jenkinsci / jenkinsci/docker-workflow-plugin

[JENKINS-52640] executable not found in subshells

Open
#578 0 comments 0 reactions 0 assignees View on GitHub
component:docker-workflow-plugin imported-jira-issue priority:minor resolution:unresolved
Dominant language
Java
Stars
527
Forks
422
Avg merge
10m
Merged PRs (30d)
1

Description

Consider the following pipeline used in a Go project:

node {

def goPackage = 'myrepo.com/myproject'
def goPath = "${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}"

// Jenkins binds WORKSPACE:WORKSPACE (host:container) when executing steps inside a Docker container, therefore the workspace path must be GOPATH-compatible.
ws("${goPath}/src/${goPackage}") {
withEnv(["GOPATH=${goPath}", 'GOCACHE=/tmp/.gocache']) {

stage('Checkout'){
checkout(scm)
}

// Default GOPATH is owned by root, so we mount our custom GOPATH from the host.
docker.image('golang:1.10').inside('-v $GOPATH:$GOPATH -e PATH=$GOPATH/bin:/usr/local/go/bin:/usr/sbin:/usr/bin:/sbin:/bin') {
stage('Static checks'){
// places 'golint' inside $GOPATH/bin
sh 'go get -u golang.org/x/lint/golint'

sh 'golint ./...'
sh 'golint ./... | grep -v "some text"'
}
}
}
}
}

While the first call to golint works, the second one fails with:

/bin/sh: 1: golint: not found

I can reproduce the behaviour in any subshell (regular parenthesis, command substitution, pipe). The only way around it is to use the full path to the executable.

---
Originally reported by antoineco, imported from: executable not found in subshells


  • status: Open
  • priority: Minor
  • component(s): docker-workflow-plugin
  • resolution: Unresolved
  • votes: 0
  • watchers: 1
  • imported: 2025-12-07

Raw content of original issue

Consider the following pipeline used in a Go project:


node {

def goPackage = 'myrepo.com/myproject'
def goPath = "${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}"

// Jenkins binds WORKSPACE:WORKSPACE (host:container) when executing steps inside a Docker container, therefore the workspace path must be GOPATH-compatible.
ws("${goPath}/src/${goPackage}") {
withEnv(["GOPATH=${goPath}", 'GOCACHE=/tmp/.gocache']) {

stage('Checkout'){
checkout(scm)
}

// Default GOPATH is owned by root, so we mount our custom GOPATH from the host.
docker.image('golang:1.10').inside('-v $GOPATH:$GOPATH -e PATH=$GOPATH/bin:/usr/local/go/bin:/usr/sbin:/usr/bin:/sbin:/bin') {
stage('Static checks'){
// places 'golint' inside $GOPATH/bin
sh 'go get -u golang.org/x/lint/golint'

sh 'golint ./...'
sh 'golint ./... | grep -v "some text"'
}
}
}
}
}


While the first call to golint works, the second one fails with:


/bin/sh: 1: golint: not found


I can reproduce the behaviour in any subshell (regular parenthesis, command substitution, pipe). The only way around it is to use the full path to the executable.

environment

```
Jenkins 2.133

Pipeline 2.5

Pipeline: Basic Steps 2.9

Pipeline: Groovy 2.54

Pipeline: Stage Step 2.3

Docker Pipeline 1.17
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.