シェルスクリプト
シェルスクリプトは主にUnix系OSのシェルに関わる操作を行うためのスクリプト言語で,ファイル操作やプログラム実行のために書かれます.
このページは,シェルスクリプトの文法を中心に整理しています.
目次
スクリプトの実行
shコマンド
直接sh
の引数として,シェルスクリプトを実行することができます.
sh スクリプト |
シェルとしてbash
を利用したいなら,
bash スクリプト |
とします.
sourceコマンド
現在のシェルで引き渡したスクリプトを実行する組み込みコマンドの.
コマンドを利用するなら,
. スクリプト |
とします.
シェルがbash
であるなら,source
コマンドを用いて
source スクリプト |
としても同じです.
引数が存在するときは
source スクリプト 引数1 引数2 … |
とします.
シェルスクリプトをコマンドにする
スクリプトを作成する際,1行目を
のように,#!
に続けて使用するシェルを宣言します.
この1行目をシバンといいます.
もし/usr/local/bin/bash
を使用するなら,シバンは#!/usr/local/bin/bash
です.
2行目以下にスクリプトを書き,拡張子sh
などで保存します.
作成したスクリプトは
chmod +x スクリプト |
で実行権限を付与し,echo $PATH
で表示されるパスの通ったところにスクリプトを置きます.
以上で,スクリプト
がコマンドとして実行できるようになります.
文法
for文
for i in 配列 |
for文を抜けるにはbreak
を使います.
次のループに移るには,処理中でcontinue
を使います.
数値の場合,配列の例は以下の通りです.
0 1 2
{0..2}
`seq 0 2`
もしくは1行目自体を次のように書くこともできるかもしれません.
for ((i=0; i < 3; i++))
その他,
- カレントディレクトリの
*.txt
など `cat ファイル名`
によりファイルから読み込ませた配列- 引数全部のセット
$@
という指定をすることもできます.
if文
if文は次のように記述します.
if 条件式1 |
ここで,条件式の記述にはtest
コマンドを使います.
test 値1 比較方法 値2 |
この条件式は次のようにも書くこともできます.
[値1 比較方法 値2] |
test
の結果,真であれば0
が返ります.
比較方法は以下の通りです.
-eq
等しい-ne
等しくないlt
より小さい,gt
より大きいle
以下,ge
以上
否定文は
test ! 値1 比較方法 値2 |
のように!
を使って書きます.
ファイルの存在を条件にすることもでき,その真偽は
test -f ファイル名 |
で判定します.ディレクトリであれば,-d ディレクトリ名
です.
また,文字列が等しいかどうかを判定する場合は
test 文字列1 = 文字列2 |
とし,その否定では!=
を使います.
その他,ファイルの更新時刻やユーザーのID,権限等もtest
コマンドで確かめることができます.
もし条件が複数存在するなら,ANDであれば
test 条件式1 -a 条件式2 |
ORであれば
test 条件式1 -o 条件式2 |
とします.
処理に際して「何もしない」という処理(Pythonでのpass
)を行いたいなら,:
と書きます.
if文をシンプルに書きたい場合は,三項演算子もどきとして左のパイプラインが真/偽のときに右に進むという性質のある&&
や||
を使うこともできます.
常に使えるわけではありませんが,
[ 条件 ] && trueの処理 || falseの処理 |
という形です.
select文
select var in item1 item2 item3 |
延々ループするので,何かの処理ではbreak
する必要があります.
case
文でパターンごとの処理は以下のように書きます.
case 値 in |
リストを継続実行する場合は以下の通りです.
- カスケードは文末
;;
に代えて;&
- 継続検索は文末
;;
に代えて;;&
while文
while 条件式 |
while
をuntil
に代えると,until文となります.
break
やcontinue
でループを抜けたり継続することができます.
while true
で始める無限ループと併せても使う方法もあります.
スクリプトが引数をとる場合,引数をシフトさせるにはshift
を使います.
シェル関数
関数名() |
シェルスクリプトは関数名
のみで使用できます.
括弧は不要です.
リストでlocal
コマンドにより宣言した変数はローカル変数となります.
関数と同名の組み込みコマンドがある場合,シェル関数が優先されます.
もし組み込みコマンドを優先したい場合は,該当箇所でbuiltin
コマンドを宣言して使います.
配列
次は配列の一例です.
array=(a b) |
配列の先頭要素や全要素は次のように取得することができます.
echo ${array[0]} #始めの要素 |
配列の追加は
array+=(値) |
で行うことができます.
複数追加も可能です.
要素数は
echo ${#array[@]} |
として取得できます.
パラメータ
デフォルト値
あるパラメータが設定されていなかった場合にデフォルト値を代入するのであれば,
${パラメータ=値} |
とします.
もしパラメータが空文字列であった場合にも,記号(ここでは=
)と同じ処理をさせることを:
で表現します.
パラメータが空文字列であった場合に,デフォルト値を代入したいなら,
${パラメータ:=値} |
とします(:
付きで以下同).
あるパラメータにワンショットである値をはめて使いたいなら,${パラメータ-値}
とします.
パラメータが設定されているときのみワンショットである値を使うなら,${パラメータ+値}
とします.
それぞれ,パラメータが空文字列であるときにも同じ処理をさせるものとして,:-
や:+
があります.
パラメータ未設定時にエラー終了させたいなら,${パラメータ?値}
を使います.
このケースでの値はエラーメッセージです.
特殊なパラメータ
スクリプト実行時の第1引数は$1
,第2引数は$2
のようにして使用します.
また,引数全ては$@
,引数の個数を取得するには$#
とします.
$!
で直近のバックグラウンド起動のプロセスIDを取得できます.
一部除去
パラメータから一部を切り出すことができます.
次は最長左方除去の例です.
左方除去は#
,最長片除去は記号重ね打ちで指定するので,/usr/local/bin
をbin
にするには,
example="/use/local/bin" |
とします.
対して,右方除去は%
で行います.
最短片除去は記号1つのみで指定するので,text.txt
をtest
にする最短右方除去の例は
example="test.txt" |
です.
m文字目からn文字目までパラメータを切り出すには,
${パラメータ:m:n} |
とします.
m
が指定されていなければ,最初からとなります.
n
が指定されていなければ,最後までとなります.
リダイレクト
読み書き
上書き保存形式での書き込みは>
によってリダイレクトして,
コマンド > ファイル |
とします.
if文やfor文も複合コマンドとしてリダイレクトできます.
追記形式での書き込みには>
に代えて>>
を使います.
コマンド >> ファイル |
読み込むときは<
とします.
コマンド < ファイル |
読み書き両用オープンは<>
です.
コマンド <> ファイル |
標準エラー出力
標準エラー出力は2>
等でリダイレクトできます.
エラーを捨てるには
コマンド 2> dev/null #「2>」で標準エラー出力(2番)をリダイレクトする |
とします.
ログファイルにアペンドするには2>>
とします.
コマンド 2>> ログファイル |
標準出力とともにログファイルに書き込むには,
コマンド > ログファイル 2>&1 |
または
コマンド &> ログファイル |
とします.
出力の退避
リダイレクトを応用して出力を退避させる例です.
手順は
- 1番から3番にコピー
- 1番をファイルに出力
- 3番から1番にコピーして,3番を閉じる
という流れになります.
exec 3>&1 #「>&」で左から右へ流し込む |
ヒアドキュメント
長文を読み込む場合は,ヒアドキュメントが便利です.
ヒアドキュメントでは,予め指定した文字列が出現するまで読み込みを続けます.
次の例は,EOF
という文字列が行頭に現れるまでに読み込んだ文字列を標準入力へリダイレクトします.
cat << 'EOF' |
ヒアストリング
ヒアドキュメント同様に長文を読み込むのに適したヒアストリングで3行読ませる例です.
cat <<< '1行目 |
ヒアストリングでシングルクォートを書きたいなら,
シングルを終える'\''シングル再開 |
ダブルクォートによるクォート展開する必要があるなら,
シングルを終える'"ダブルで囲まれた部分"'シングル再開 |
という形を用います.
クォートの違い
シングルクォーテーション'
では,囲み内は単純に文字列として扱われる.
ただし,囲みに使っているシングルクォーテーションを打ちたいなら,一度シングルクォーテーションの囲みを閉じて\'
を打ち,シングルクォーテーションの囲みを再開する.
ダブルクォーテーション"
では,その囲み内で変数とバッククォーテーションによる囲みが使える.
すなわち,エスケープに用いる\
に加えて変数に用いる$
とバッククォート`
は解釈が行われ,他を文字列として扱う.
バッククォーテーション`
では,コマンドが有効である.
\$
と\\
と\`
は特殊解釈する.($()
はそうしない.)
グループコマンドとサブシェル
グループコマンドは当シェルで実行されるが,サブシェルは別シェルで実行される.
{ |
( |
その他
- 行末に
\
で改行しなかった扱いとなります. - コマンドはフルパスで指定しておく方がエイリアスが存在していたときに安全です.フルパスは
which コマンド名
で調べることができます. - ブレース展開できるなら,
echo {a,b}{1,2}
でa1 a2 b1 b2
,echo {,1}2
なら2 12
を返します.
コマンドの利用
オプションを付ける
getopts
コマンドを利用して,シェルスクリプトにオプションを設定する例です.
while getopts オプション opt |
オプション
で例えばabc:d:
と書けば,4つの一文字オプションを作成します.
オプションのうち,コロンが後置されているc
とd
については,引数有りオプションとなります.
オプションが残らないように,サブシェルで実行するなどしてください.
tmpファイルの作成
tmpファイルの作成にはmktemp
コマンドを使います.
tmp_file=$(mktemp) #一時的に利用するファイル |
必要な処理を行なった後,最後に
trap " |
とすれば,不要な一時ファイルを削除することができます.
スペース区切りされる結果の利用
コマンドの実行結果がある種の順序を持ったスペース区切りで列挙される場合,次のようにset
コマンドを利用して引数を変数に格納することができます.
set -- `date '+%Y %m %d'` |
小数点を含んだ計算
計算はbc
で行います.
echo 計算式 | bc |
書式をprintf
で指定することで,小数点第1位までで四捨五入して出力を行います.
printf '%.1f \n' `echo '計算式' | bc -l` |
関連して,単位換算について調べたいときはunits
コマンドを使うとよいでしょう.
pointからmmに換算する比率を調べる例は,
units |
です.
最後の2行が出力結果で,pointの値に0.35277778を掛けるか,mmを2.8346457で割ればよいことを意味しています.
キーボード入力の読み込み
キーボード入力を変数に格納するには,
read 変数名(複数可) |
とします.
同じ要領で,read
だけ書いておけば,キー入力するまで一時停止できます.
スクリプトのあるディレクトリを取得する
実行しているスクリプトが存在するディレクトリまでのパス取得は
path=$(dirname $(readlink -f $0)) |
で行えます.
参考文献
シェルスクリプトを作成するのに必要となる基本的コマンドから文法まで扱った,読めるリファレンスです.
- 山森丈範 (2017)「シェルスクリプト基本リファレンス」3版,技術評論社.