0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

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 $arg1
else
  bundle exec ruby hoge.rb
fi
hoge.rb
# require 'optimist'

class Hoge
  def initialize
    @options = Optimist::options do
      opt :opt, 'Option', type: :string, required: false
    end
  end
  def run
    echo @options[:opt] if @options[:opt]
  end
end

というシェルプログラムを書きました。
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コマンドを利用する際は変数の展開を意識しないとハマるよ、というお話でした。

おわり

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?