はじめに
デプロイ用スクリプトとか書いてます。
プログラムはPHPとかNode.jsで書くので、Bashで書くのはコマンドを取りまとめたものになります。
引数を渡したり、環境変数を定義させたりしつつ、シェルに対しての操作が多いです。
「Bash 書き方」とかでググるとBashスクリプト全般のことが出てくるのでちょっと趣旨がちがって、CIとかインフラ用に書くときにぐぐっていることのまとめです。
よく書くパターン
#!/usr/bin/env bash
set -xe # -xで実行コマンドを表示、-eでエラーがあったときに終了
cd -- "$(dirname "$BASH_SOURCE")" # ファイルがある場所に移動
Shebang
最初の行に書いておくやつ。シェバン。
#!/usr/bin/env bash
エラーなどの出力を出す
エラーのみ。
set -e
コマンドも出力する。
set -xe
set -x
したものを無効化する
set -x
していると色々とデバッグメッセージが流れるので、無効化したいときは+
オプションを使う。
-x
に対しては+x
。
set -x # ここからデバッグ用の実行中コマンドが出力されます
echo 'hoge'
set +x # ここからデバッグ用の実行中コマンドの出力が無くなります。
With set +e. Yeah, it's backward that you enable shell options with set - and disable them with set +. Historical raisins, donchanow.
参考
色付けする
\e[34m
などのエスケープシーケンスで色がつきます。
printf '🎉\e[34m Success! \e[m🎉\n'
出力例
カレントディレクトリをスクリプトファイルがある場所に移動
pwd -P # 確認用 /home/username
cd -- "$(dirname "$BASH_SOURCE")" # ここ
pwd -P # 確認用 /home/username/bin/test
testを使った判定
本来test
は数値判定に使われていたけど、シェルスクリプトとしてのtest
は文字列操作、ファイル操作を主に使っているのでそこにフォーカス。
オプション | 説明 | オプションの語源 |
---|---|---|
-z | 変数が空 | is Zero |
-n | 変数になにかある | is Number |
-d | ディレクトリかどうか | is Directory |
-f | ファイルかどうか | is File |
-e | 存在するか | is Existing |
-r | 読めるか | is Readable |
-w | 書けるか | is Writable |
-x | 実行できるか | is e Xecutable |
ググるときは「bash test file exsist」のように「bash test」と書くと良い。
変数が存在するか
基本的にはtest
の-z
で調べるらしいんだけど、-zの本来の意味はゼロかどうか。なので変数をダブルクォートで囲むと良い。
HOGE='hoge desu yo'
FUGA=''
if [ -z "$HOGE" ]; then
echo "HOGE is empty" # 🙅♂️ここに来ません
else
echo "HOGE is ${HOGE}" # 🙆♂️こちらになります
fi
if [ -z "$FUGA" ]; then
echo "FUGA is empty" # 🙆♂️こちらになります
else
echo "FUGA is ${FUGA}" # 🙅♂️ここに来ません
fi
$ bash test.bash
HOGE is hoge desu yo
FUGA is empty
https://stackoverflow.com/questions/18096670/what-does-z-mean-in-bash
ディレクトリが存在するか
if [[ -d "path/to/target" ]]; then
echo 'Directory exists'
exit 1
fi
変数の展開
基本的には$
と変数名。
例:)$HOGE
文字列が連続する場合に確実に展開させるには$
の後に中括弧で変数名を書く。
例1:) $HOGEFUGA
(これだと$HOGE + 'FUGA'なのか$HOGEFUGAなのか区別が付かない
例2:) ${HOGE}FUGA
引数の処理 (Arguments)
1番目の引数を$PROFILE
に代入。指定されていなければ default
を代入。
PROFILE=${1:-default}
echo $PROFILE
$ ./test.sh profile_desu
profile_desu
変数が定義されていれば○○
三項演算子的なあれです。
HOGE=hoge
FUGA=${HOGE-fuga} # $HOGEは定義されているのでhogeが参照される
echo $FUGA # hoge
PIYO=${HOGE2-piyo} # $HOGE2は定義されていないのでpiyoが参照される
echo $PIYO; # piyo
タブ文字などを出したい
$
を使ってシェルに展開してもらう。
$ $'\t' # タブ文字が出る
$ echo 'mae'$'\t''usiro' # mae usiro
先頭にタブ文字を追加する。
$ echo 'hoge' | sed -e 's/^/'$'\t''/g'
curlのダウンロード
Bashスクリプトではないのですが、スクリプト内で使うコマンド。
curl -LOJ https://example.com
オプション | 説明 |
---|---|
-L | リダイレクトをフォローする。(リダイレクトが合った場合に追跡して次のURLに自動でアクセスする) |
-O | ファイルをそのまま保存させる。 |
-J | サーバから指定されたファイル名を保存時のファイル名として使う。このオプションが無いとURLの末尾をファイル名として使おうとするため、トークンやクエリパラーメータ付きのURL等のダウンロードの際に苦労します。 |
ShellCheck
シェルの構文にエラーがないかチェックをすることができます。
手元でも行うことができますし、オンラインでも可能です。