詰まったのでメモ
ユースケースと課題
例えばPipelineのパラメータとして以下のプレースホルダーに作成したいファイル名を記載するとき
ファイル名にホワイトスペースやシングルクオートといった特殊文字を入れたくなるときがある。
Jenkins内で扱うだけならまだ良いが、シェルスクリプトにコマンドライン引数などとして投げるとき、シェルがうまくパースしてくれない場合がある。非常に詰まって時間を費やしてしまったので後進のためのメモ。
解決策
Groovyファイル側で一度パラメータをエスケープしてあげ、その後シェル側でエスケープシークエンスを評価する。 今回は簡単のためホワイトスペースとシングルクオートのみを考慮に入れる。
まずJenkins側でパラメータ内の特殊文字をエスケープする。これはシェル側で正しくエスケープシークエンスを評価できるようにするための処理。
EscapedOutput="${SomeParam.replaceAll(/('| )/, /\\$0/)}"
次にコマンドライン引数のオプションとしてシェルに投げる。このとき直接Jenkinsの変数を展開してしまうと、エスケープシーケンスを正しく評価できない。
例えば、 echo 'test\'test'
のような場合、最後のシングルクオートが閉じられていないと解釈される 。
そこで$'文字列'
のように記載してあげる必要がある(因みにこれはbashでのみ利用可能でshでは利用可能でないことに注意)。
ただGroovy側では$
は特殊文字なので\$
のように書いてエスケープしてあげる必要がある。あくまでもシェルに解釈してもらいたい。
注意点として、shコマンドはGroovyではbashではなく無印shを呼び出してしまうので、
sh "#!/bin/bash \n" + "./script.sh --outputname \$'${EscapedOutput}'"
のように明示的にbashで実行してあげる必要がある。
これでスクリプト内で適切に変数が展開される。
最終的なコードは以下のような感じ。
stages { stage('build') { environment { EscapedParam="${SomeParam.replaceAll(/('| )/, /\\$0/)}" } steps { sh "#!/bin/bash \n" + "./script.sh --outputname \$'${EscapedOutput}'" } } }
続く。。。