Bashには、$から始まる変数が色々とあります。ここでは$から始まる特殊な変数について紹介します。$から始まる変数はよく使うものもあり、専門的っぽく見えるので知っておくと便利だと思います。
目次
引数の展開について($@と$*と$#)
$@と$*の変数はシェルスクリプトの実行時に渡された引数をすべて展開または関数に渡された引数をすべて展開する変数として利用できます。
また、渡されている引数の数を確認するには$#の変数が利用できます。
$@と$*の変数は二重引用符で囲まれたときに動作が異なります。$@は個々の展開される引数がスペースで区切られて、二重引用符に囲まれている解釈を行います。
しかし、$*では、すべての引数が展開された状態を一つの文字列として扱います。
補足として、区切り文字を取り扱う組み込み変数IFSを変更すると、$*が展開されたときに引数を区切っていた文字が変更されます。
script1.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#!/bin/bash echo -n '$@:'; echo $@ echo -n '$*:'; echo $* echo -n '$#:'; echo $# echo; echo '**"$@"をループさせた場合**' for var1 in "$@" ; do echo $var1 done echo '**"$*"をループさせた場合**' for var2 in "$*" ; do echo $var2 done echo; echo '**IFSを'"','"'に変更**' IFS=',' echo -n '$@:'; echo "$@" echo -n '$*:'; echo "$*" |
実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ ./script1.sh aaa bbb ccc $@:aaa bbb ccc $*:aaa bbb ccc $#:3 **"$@"をループさせた場合** aaa bbb ccc **"$*"をループさせた場合** aaa bbb ccc **IFSを','に変更** $@:aaa bbb ccc $*:aaa,bbb,ccc |
コマンドの引数を処理するコマンドにはshiftコマンドがあります。shiftコマンドを実行すると'$@','$*','$#'の変数も変化します。
script2.sh
1 2 3 4 5 6 7 8 9 10 11 |
#!/bin/bash echo -n '$@:'; echo $@ echo -n '$*:'; echo $* echo -n '$#:'; echo $# echo ; echo 'shiftコマンドの実行' shift echo -n '$@:'; echo $@ echo -n '$*:'; echo $* echo -n '$#:'; echo $# |
実行結果
1 2 3 4 5 6 7 8 9 |
$ ./script2.sh aaa bbb ccc $@:aaa bbb ccc $*:aaa bbb ccc $#:3 shiftコマンドの実行 $@:bbb ccc $*:bbb ccc $#:2 |
コマンドの成功($?)
$?は直前のコマンドの終了ステータスを確認できます。終了ステータスは基本的に0が成功(正常)、それ以外が失敗(異常)になります。
script3.sh
1 2 3 4 5 6 7 8 9 |
#!/bin/bash echo '1=1の終了ステータス' [ 1 = 1 ] echo $? echo '1=2の終了ステータス' [ 1 = 2 ] echo $? |
実行結果
1 2 3 4 5 |
$ ./script3.sh 1=1の終了ステータス 0 1=2の終了ステータス 1 |
Bashのフラグの確認($-)
$-は実行しているBashについているフラグを確認できます。フラグはBashの起動時に付与できます。また、setコマンドでも変更を行うことができます。
script4.sh
1 2 3 4 5 6 7 8 9 |
#/bin/bash echo -n '$-:'; echo "$-" set -x echo -n '$-:'; echo "$-" set -v +x echo -n '$-:'; echo "$-" |
実行結果
1 2 3 4 5 6 7 8 |
$ ./script4.sh $-:hB ++ echo -n '$-:' $-:++ echo hxB hxB ++ set -v +x echo -n '$-:'; echo "$-" $-:hvB |
hBはデフォルトで付けられるフラグになります。hがコマンドの実行時に検索したそのコマンドのフルパスを記録する機能(hashコマンドの機能)です。Bがブレース展開(例:a{a,b,c}bでaaa,abb,acbに展開される機能)のフラグです。
付与したxとvのフラグは、xがコマンドのトレースを行うフラグで、vが入力したコマンドをそのまま出力するフラグになります。
プロセス関連($$と$!)
$$は現在のシェルのプロセスIDを取得できます。
1 2 |
$ echo "$$" 2803 |
$!は直前のバックグラウンドに移行したジョブのプロセスIDを取得できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ sleep 100 & [1] 2897 $ echo "$!" 2897 $ sleep 100 & [2] 2898 $ echo "$!" 2898 $ $ ps PID TTY TIME CMD 2803 pts/18 00:00:00 bash 2897 pts/18 00:00:00 sleep 2898 pts/18 00:00:00 sleep 2901 pts/18 00:00:00 ps |
実行中のシェルやシェルスクリプト名($0)
$0は実行中のシェルやシェルスクリプトの名前(実行コマンドの名前)を取得できます。
シェルで実行した場合
1 2 |
$ echo $0 bash |
シェルスクリプト中で実行した場合
1 2 |
$ ./script5.sh ./script5.sh |
また、ファイル名だけを取得したい場合はbasenameコマンドを活用するといいと思います。
直前コマンドの最後の引数を呼び出し($_)
$_は直前のコマンドの末尾にある最後の引数の部分として展開されます。
1 2 3 4 |
$ echo aaa bbb ccc aaa bbb ccc $ echo $_ ccc |
$_が展開する直前のコマンドはシンプルコマンド(simple command)でこれはよく使われるコマンドの種類です。シンプルコマンドの区切りは改行のほかには‘||’, ‘&&’, ‘&’, ‘;’, ‘;;’, ‘;&’, ‘;;&’, ‘|’, ‘|&’, ‘(’, or ‘)’のようなものがあります。
$_を利用するよくある例として
1 |
mkdir directory_name && cd $_ |
のようなものがあります。これはディレクトリの作成に成功したらすぐにそのディレクトリに移動するものになります。
また、Gitで何かをクローンする際に
1 |
git clone url directory_name && cd $_ |
みたいに利用しても良いかもしれません。