Q1./a.sh foo barを実行したとき$2には何が入りますか?
引数と終了コード — $1 と exit で外から制御する
この記事は、基礎コマンドからシェルスクリプトまでLinuxの実践的なスキルを1からマスターする「Linux入門講座の一部」です。
./a.sh foo barの値を $1 $2 $@ $# $0で受け取り、${2:--} で既定値を補い、$? の確認とexit 0 / exit 1で成否を返す実用スクリプトを、図解とブラウザ端末で書いて実行します。
引数を受け取る — $1 / $2 / $0
スクリプトは実行時に値を渡せます。
./a.sh foo barのように後ろに並べた値を引数といい、スクリプトの中では$1が1番目、$2が2番目の引数になります。
$0はスクリプト自身の名前、$#は渡された引数の個数、$@は全引数をまとめて表します。
これらを使うと、固定の値ではなく実行のたびに違う入力でスクリプトを動かせます。
| 書き方 | 意味 | 例 |
|---|---|---|
$1 $2 | 1番目・2番目の引数 | echo "$1 then $2" |
$0 | スクリプト自身の名前 | echo "running $0" |
$# | 渡された引数の個数 | echo "argc=$#" |
$@ | すべての引数をまとめて | echo "all: $@" |
$1 $2に入り、$#で個数、$@で全体をまとめて扱えます。set -- foo bar # 位置パラメータを擬似的に設定
echo "1st: $1" # foo
echo "2nd: $2" # bar
echo "argc: $#" # 2
echo "all: $@" # foo bar
既定値を補う — ${1:-def}
引数が渡されないこともあります。
${1:-default}と書くと、$1が未指定または空のときにdefaultが使われ、指定があればその値が使われます。
これにより、引数があれば従い、無ければ安全な既定値で動くスクリプトが書けます。
$#を見れば、必要な数の引数が来ているかも判定できます。
| 書き方 | 意味 | 例 |
|---|---|---|
${1:-def} | $1が未指定ならdefを使う | name=${1:-guest} |
${2:-def} | $2が未指定ならdefを使う | sep=${2:--} |
${2:--}は、2番目を渡せばその値、省けば既定値-を使います。set -- # 引数なしで実行した状態を再現
echo "${1:-guest}" # 未指定なので guest
set -- alice # 1番目に値を渡した状態
echo "${1:-guest}" # 値があるので alice
成否を返す — $? と exit N
コマンドは終わるときに終了コードという 0〜255 の数を返します。
0は成功、0以外は失敗を表す慣習です。
直前のコマンドの終了コードは$?で読み取れます。
grepで見つかれば0、見つからなければ1のように、結果に応じて値が変わります。
スクリプト側からはexit Nで終了コードを明示できます。
exit 0は成功、exit 1は失敗として返すのが一般的です。
呼び出し側はこの値を$?や&& ||で受け取り、成功時だけ次の処理へ進む、といった制御に使えます。
exitを省くと最後に実行したコマンドの終了コードがそのまま返ります。
| 書き方 | 意味 | 例 |
|---|---|---|
$? | 直前のコマンドの終了コード | grep x f; echo $? |
exit N | 終了コードNでスクリプトを終える | exit 1 |
exit 0、失敗ならexit 1を返し、呼び出し側は$?で結果を読み取ります。printf 'apple\nbanana\n' > fruits.txt # 素材を作成
grep apple fruits.txt > /dev/null
echo "found? $?" # 見つかったので 0
grep mango fruits.txt > /dev/null
echo "found? $?" # 見つからないので 1
全引数を順に処理する — $@ と $#
引数の数が決まっていないとき、$1 $2を順に書く代わりに$@をforで回すと、渡された分だけ繰り返し処理できます。
for x in "$@"; do … doneの形で1つずつ取り出し、件数は$#で表示すると、いくつ渡されても同じスクリプトで扱えます。
複数ファイルをまとめて処理するツールでよく使う書き方です。
| 書き方 | 意味 | 例 |
|---|---|---|
"$@" | 全引数を1語ずつ安全に渡す(for用・要ダブルクォート) | for x in "$@"; do |
$# | 渡された引数の個数 | echo "count=$#" |
$#で個数を知り、$@をforで1つずつ取り出して各引数を処理します。set -- foo bar baz # 位置パラメータを擬似的に設定
echo "argc: $#" # 3
for x in "$@"; do
echo "- $x" # - foo / - bar / - baz
done
理解度チェック
まずは1問ずつ答えてみましょう。
Q2${1:-guest}の意味として正しいものはどれですか?
Q3直前のコマンドが成功したかを表す終了コードを読み取る書き方はどれですか?