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