Keywords: Jenkins pipeline | directory control | shell command execution
Abstract: This paper thoroughly examines the directory inconsistency issue when executing shell commands in Jenkins 2.0 pipelines and presents effective solutions. By analyzing the Jenkins workspace structure, it explains the differences between checkout operations and sh command execution environments, focusing on two core methods: using dir blocks and relative paths to ensure scripts run in the correct directory. With concrete code examples, the article compares different approaches, discusses technical details like path resolution and environment variables, and provides practical guidance for Jenkins pipeline development.
Problem Background and Phenomenon Analysis
In Jenkins 2.0 pipeline development, a common issue arises: after successfully checking out code to the workspace via checkout scm, executing a build script with the sh command results in a "command not found" error. As shown in the example:
node ('master'){
stage 'Checkout'
checkout scm
stage "Build Pex"
sh('build.sh')
}
The error indicates Jenkins searches for the build.sh script in the workspace@tmp/durable-* directory instead of the actual code location in workspace/. This directory inconsistency stems from Jenkins pipeline execution mechanisms.
Jenkins Workspace Structure Analysis
Jenkins creates a temporary working environment for each pipeline execution, where workspace/ is the main directory for code checkout, and workspace@tmp/ stores pipeline metadata and temporary files. When executing the sh command, Jenkins defaults to running in the current working directory (often a @tmp subdirectory), leading to incorrect script path resolution.
Core Solutions: Directory Control Strategies
Method 1: Using dir Blocks to Specify Execution Directory
Jenkins pipelines provide the dir block syntax, allowing developers to explicitly set the working directory for command execution. This is the most direct and recommended approach:
checkout scm
stage "Build Pex"
dir('workspace') {
sh('./build.sh')
}
The dir block accepts relative or absolute path parameters. Relative paths resolve based on the current working directory, while absolute paths require the target directory to exist on the agent node. This method not only solves path issues but also enhances code readability and maintainability.
Method 2: Using Relative or Absolute Paths
An alternative is to specify the script's full path directly in the sh command:
checkout scm
stage "Build Pex"
sh("workspace/build.sh")
Or using a relative path:
sh("./build.sh")
Note that the relative path ./build.sh depends on the current working directory, which in pipeline environments may still point to the @tmp directory, so it should be combined with a dir block or proper working directory setup.
Technical Details and Best Practices
Understanding Jenkins environment variables is crucial for directory control. The ${WORKSPACE} variable always points to the main workspace directory and can be used to construct absolute paths:
sh("${WORKSPACE}/build.sh")
For script portability, it is recommended to use relative paths with dir blocks, avoiding hard-coded absolute paths. In complex pipelines, set the working directory early:
node('master') {
stage('Setup') {
checkout scm
dir('workspace') {
// All subsequent stages execute in this directory
stage('Build') {
sh('./build.sh')
}
}
}
}
Supplementary Analysis and Considerations
Beyond directory issues, script execution failures may also result from PATH environment variable configuration. Ensuring build.sh has executable permissions (chmod +x build.sh) is necessary. For debugging, use the sh('pwd') command to output the current working directory and diagnose path problems.
In summary, the dir block approach offers the clearest directory control, while path specification is simpler but may lack flexibility. Developers should choose the appropriate method based on specific scenarios to ensure stable Jenkins pipeline execution across environments.