TL;DR
Jenkinsfileでは sh '''
〜 '''
で囲った複数行のシェルコマンドを実行することができる。この際、通常はOSの sh
コマンドで実行されるが、開始行の '''
の右に #!/bin/bash
などのシェバンを追記すると、 bash
などの指定したインタプリタでのコマンド実行が可能となる。
pipeline {
agent any
stages {
stage('Test') {
steps {
sh '''#!/bin/bash
python3 -m venv .venv
source .venv/bin/activate
echo "hoge"
'''
}
}
}
}
詳細
Jenkinsfileには、Jenkinsパイプライン上でシェルコマンドを実行するための sh
というステップが用意されており、 sh <command>
の一行形式か、 sh '''
〜 '''
の複数行形式で記述できる。
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'echo "Hello World"'
sh '''
echo "Multiline shell steps works too"
ls -lah
'''
}
}
}
}
ただし、この sh
ステップはOSの SHELL
環境変数の値に関わらず /bin/sh
インタプリタで実行される。このことにより、時折不都合が生じることがある。
例として、Ubuntu20.04の sh
コマンドは dash
へのシンボリックリンクとなっており、 dashには source
などの一部コマンドが存在しないため、bashと同じ感覚で以下の内容をパイプラインで実行させるとエラーが発生してしまう。
- 実行するパイプライン
pipeline {
agent any
stages {
stage('Test') {
steps {
sh '''
python3 -m venv .venv
source .venv/bin/activate
echo "hoge"
'''
}
}
}
}
- 発生するエラー
script.sh: 2: source: not found
source
であれば .
に置き換えることで解消できるが、その他の理由で dash
ではなく bash
を使いたいといった場合、複数行コマンドの形式で sh '''
の右に #!/bin/bash
のシェバンを追記することで、 bash
でのコマンド実行が可能となる。
pipeline {
agent any
stages {
stage('Test') {
steps {
sh '''#!/bin/bash
python3 -m venv .venv
source .venv/bin/activate
echo "hoge"
'''
}
}
}
}
このとき、 '''
とシェバンはスペースを空けずに記述する必要がある点に注意。
参考
jenkins.io - Running multiple steps
Bourne Shell(レガシー sh)とPOSIXシェル(sh, bash, etc)の違い - Qiita