Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2810

bash testコマンドと変数の展開

$
0
0

testコマンド、知ってますか

シェルスクリプトで重要な役割を果たすのがtestコマンドです。

sample1.sh
if[$# -eq 1 ];then
  echo'an argument is set'fi

といった感じで使います。
え?どこにtestが使われているんだって?
[]testコマンドのシンタックスシュガーです。
[の直後、]の直前には必ず半角スペースを入れましょう(初心者がハマりがちな罠)

オプション色々

testコマンドには様々なオプションがあります。

  • 引数をオプションの前後に取るもの
    • -eq, -ne, -gt, -ge, -lt, -le: 数値比較(等しい、等しくない、大きい、以上、小さい、以下)
    • =, !=: 文字列比較(等しい、等しくない)
  • 引数をオプションの後ろにのみ取るもの
    • -n, -z: 文字列長(0ではない、0である)
    • -e, -f, -dなど: ファイル確認(存在する, 通常ファイルである, ディレクトリである)
    • -v: 変数が定義されている
sample2.sh
hoge='sample2.sh'if[$hoge='sample2.sh'];then
  echo"I am $hoge"# I am sample2.shと出力
end
if[-e$hoge];then
  echo"$hoge exists!"# sample2.sh exists! と出力
end

変数の展開

さて、シェルには変数の展開という機能があります。
さきほどのsample2.shの中で、echo "I am $hoge"という命令で I am sample2.shと出力していた機能です。

この機能、意識しないとハマります

sample3.sh
if[$# -eq 1 ];then$arg1='yobaretayo'fi
if[-v$arg1];then
  bundle exec ruby hoge.rb --opt$arg1else
  bundle exec ruby hoge.rb
fi
hoge.rb
#require 'optimist'classHogedefinitialize@options=Optimist::optionsdoopt:opt,'Option',type: :string,required: falseendenddefrunecho@options[:opt]if@options[:opt]endend

というシェルプログラムを書きました。
hoge.rbは --optというオプションを受け取るか、引数なしで呼び出されます。
ところが、
$ ./sample3.sh
というコマンドを実行すると、
Error: option '--opt' needs a parameter.
というエラーになってしまうのです。

$arg1はsample3.shの引数がない場合には未定義なので、
if [ -v $arg1 ];はfalse(!=0)となり、bundle exec ruby hoge.rbが呼ばれるはずです。
はて・・・?

正解は
if [ -v arg1 ];でした。

違いがわかりますか?

if [ -v $arg1 ];は変数の展開が行われて if [ -v ];と解釈されてしまい、true(=0)で扱われるのです。

シェルスクリプトでtestコマンドを利用する際は変数の展開を意識しないとハマるよ、というお話でした。

おわり


Viewing all articles
Browse latest Browse all 2810

Trending Articles