フルスクラッチから1日でCMSを作る シェルスクリプト高速開発手法入門 改訂2版
目次
- 目次
- はじめに
- シェルスクリプトを安全に実行する
- デバッグモードを作成する
- helpを出すようにする
- error関数とabort関数を使う
- コマンドが使えるか確認する
- 複数のファイルを連結する
- スクリプトの場所に移動してから、シェルスクリプトを実行する
- 二つのコマンドを一行で実行する
- シェル変数のデフォルト値
- コマンドを実行して、その結果を変数に代入
- カレントディレクトリ以下の全ファイルからxxxという文字列を検索
- シェルスクリプトのif文などで比較するときは、[[]]を使う。
- 文字列
- 配列
- ループ関連
- Bashの予約語
- cutコマンドを使うと各列の一部のデータを取得できる。
- 数字列を取得する場合はegrepを使うと良い
- awkの使い方
- sedの使い方
- 参考資料
- MyEnigma Supporters
はじめに
長めのシェルスクリプトを作るときに、
便利な逆引きメモです。
シェルスクリプトを安全に実行する
シェルスクリプトの冒頭に、
#!/bin/bash -euo pipefail
と書くと、各コマンドを表示してくれたり、
エラーが発生した場合や、
未定義の変数がある場合は、そこで止まってくれます。
スクリプトの中で、
set -euo pipefail
としてもOKです。
それぞれのオプションの意味は下記の通りです。
オプション | 意味 |
---|---|
-e (errexit) | コマンド実行がエラー(exit statusが0以外)のときは、停止 |
-u | 未定義の変数がある場合は終了 |
-o pipefail | パイプの途中でエラーがあった時でも止める |
デバッグモードを作成する
下記の記事の通りにシェルスクリプトを書くと、
$ TRACE=1 ./script.sh
とすることで、実行したコマンドを全部表示することができ、
シェルスクリプトをデバックしやすくなります。
helpを出すようにする
下記の記事の通りにシェルスクリプトを書くと、
--helpや-hで、任意の説明文を表示することができます。
error関数とabort関数を使う
下記の記事の通りです。
error関数とabort関数を使うと
$ command || error "Error"
でcommandが失敗したときに、エラーハンドリングできます。
コマンドが使えるか確認する
あるコマンドがシェルから実行できるかを確認するには、
下記のtypeコマンドを使うことができます。
下記はyumコマンドが使える場合は、
yumでvimをインストールし、
それ以外はaptでインストールする例です。
# yumコマンドがある場合は if type yum > /dev/null 2>&1; then sudo yum install vim else # Ubuntu apt install vim fi
複数のファイルを連結する
cat *.txt > all.txt
txt形式のログファイルを連結したりするのに便利です。
スクリプトの場所に移動してから、シェルスクリプトを実行する
スクリプトが実行される場所に関係ないシェルスクリプトを作るには、
下記のコマンドを最初に実行すれば、
スクリプトの場所に移動してから、シェルスクリプトを実行することができます
$ cd $(dirname $0) || exit 1
二つのコマンドを一行で実行する
; (セミコロン)でつなぐと一行で書けます。
シェル・スクリプト・リファレンス - 【 複数のコマンドの実行「;」 】:ITpro
シェル変数のデフォルト値
下記のようにすると、
$1が設定されていない場合は、fooにhogeが入り、
$1が設定されている場合は、fooに$1の値が設定されます。
foo=${1:-hoge}
コマンドを実行して、その結果を変数に代入
ドルマークと丸括弧でコマンドを囲います。
$ hoge=$(command)
カレントディレクトリ以下の全ファイルからxxxという文字列を検索
find ./ -name '*'| xargs grep 'xxx'
.cppファイルのみから見つけたい時
find ./ -name '*.cpp' | xargs grep 'xxx'
シェルスクリプトのif文などで比較するときは、[[]]を使う。
文字列
シェルスクリプトで文字列を扱う方法です。
同じ文字列の比較
#!/bin/bash VAR1="Linuxize" VAR2="Linuxize" if [ "$VAR1" = "$VAR2" ]; then echo "Strings are equal." else echo "Strings are not equal." fi
配列
シェルスクリプトで配列を扱う方法を説明します。
配列の初期化
一般的には、
$ declare -a my_array
でmy_arrayという配列を作ることができます。
他には、下記のように空の配列を作ったり、
$ my_array=()
初期値を入力して、初期化することもできます。
$ my_array=(foo hoge huga)
コマンドの出力を配列に入力する
bash v4.0から導入されたmapfileを使うと簡単に実現できます。
mapfile -t my_array < <( my_command )
関数から配列を返す
そもそもシェルスクリプトでは、返り値を返すことそのものが難しいため、
あまり美しい方法はなさそうですが、一番良さそうな方法は、
返り値用の配列変数を、引数として渡してnamerefの機能を使って
その配列変数に代入することです。
create_array() { local -n arr=$1 # namerefを使って、参照とする arr=(one "two three" four) } main() { local my_array create_array my_array # my_arrayを引数として渡す echo $my_array[@] } main
配列のスライス
一応、スライスも可能です。
その他参考資料
ループ関連
ダブルループから抜ける
breakの後に、ネスト数を入れる必要があります。
for i in something do while true do [ condition ] && break 2 done done
Bashの予約語
Bashにはいくつか予約語があります。
予約語 | 用途 |
---|---|
$0 | スクリプトの名前 |
$1 to $9 | スクリプトの引数。$1は最初の引数で、残りも同様にアクセスできます。 |
$@ | すべての引数 |
$# | 引数の数 |
$? | 一つ前のコマンドの終了コード |
$$ | このスクリプトの Process identification (PID) 番号。一時ファイルの名前にすると良い |
!! | 引数を含む最後のコマンド全体。よくある使い方は、コマンドを実行してもパーミッションが足りないために失敗したときに、sudo !! とすることです。 |
$_ | 最後のコマンドの最後の引数。対話型シェルを使用している場合は、Escの後に.を入力することで、この値を取得することも可能 |
cutコマンドを使うと各列の一部のデータを取得できる。
ドット区切りで第二フィールドを取得する。
$ cut -d. -f2
数字列を取得する場合はegrepを使うと良い
0-9の数字が8個並ぶ所を取得する
$ egrep "[0-9]{8}"
awkの使い方
awkは位置指定付きのgrepとして使える
第5フィールドにsuを含む行を抽出
awk '$5=="su*"
awkでは文字列を”“で囲むと文字列扱い、囲まないと数値扱いになる
数値にすれば大小の比較条件などを使える。
sedの使い方
nanが混入してしまったデータを0に置き換える
別のファイルとして置き換えたい場合
$ cat hoge.txt | sed "s/nan/0/g" > hoge2.txt
同じファイルとして上書きしたい場合
$ sed -i "s/nan/0/g" hoge.txt
単語置換
$ #11行目~25行目までAAAをBBBに置換する
$ sed -e '11,25 s/AAA/BBB/g' source.txt
GitHubのリポジトリの最新tagのバージョンを取得する
下記のように、curlとsedを組み合わせることで、最新のバージョンを取得できます。
$ curl -s https://api.github.com/repos/AtsushiSakai/DiffSentinel/tags|grep -m1 '"name":'|sed 's/^.[^0-9]([0-9].[0-9].[0-9]).*$/\1/'
参考資料
フルスクラッチから1日でCMSを作る シェルスクリプト高速開発手法入門 改訂2版
MyEnigma Supporters
もしこの記事が参考になり、
ブログをサポートしたいと思われた方は、
こちらからよろしくお願いします。