web-dev-qa-db-ja.com

$ 1と$ 2がnullかどうかを確認する方法は?

文字列引数を渡すスクリプトを実行していますが、elseステートメントが次のようになっている場合は実行したいと思います。

if [ $1 != '' ] && [ $2 != '' ]
then 
    do something.....

しかし、それはError too many argumentを示しました。どうして?

40
taymindis Woon

-zテストを使用してみてください。

if [ -z "$1" ] && [ -z "$2" ]

Man bashから:

-z string
   True if the length of string is zero.
53
Sylvain Pineau

これにはbashというタグが付けられているため、 拡張テストコンストラクト([[...]] を使用し、引用符を忘れることをお勧めします。

if [[ -z $1 && -z $2 ]]; then
...

sh/POSIXとの互換性を求めているのでない限り、[[ ]]を使用しない理由はありません。

13
muru

回答の古いバージョンについては、この回答の2番目の部分を参照してください。詳細について知りたい場合は、

問題の原因

質問自体では、OPはtoo many arguments errorを見ると報告されていますが、bashでテストした場合はそうではないようです:

$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected

Ubuntuで/bin/shに実際にシンボリックリンクされている/bin/dashでは、エラーは次のように報告されます。

$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator

スタンドアロン/bin/testも:

$ /usr/bin/test $1 != ''  
/usr/bin/test: missing argument after ‘’

サイドノート:/usr/bin/testとは何か、なぜbashshを使用しているのか疑問に思っている場合は、[testのエイリアスであることを知っておく必要があります。コマンドは、スタンドアロンの実行可能ファイルまたはより一般的にも存在します-各シェルが最初に使用するシェルビルトインとして。 ifステートメントについては、コマンドの終了状態で動作するため、[およびtestがコマンドであり、他のすべてがそのコマンドに対する引数である理由-これらのコマンドライン引数の順序は不適切ですエラーにつながります。

トピックに戻ります:OPが無関係のエラーを取得した方法は不明です。ただし、3つのケースすべてで問題は同じです。未設定の変数は空として扱われるため、シェルはこれらの引用されていない変数で表示されます

[ != '' ]

testが理解する構文を破ります。コマンドライン引数の不適切な順序について私が言ったことを覚えていますか?したがって、引用が重要である理由。診断出力を有効にして、シェルが実行するものを見てみましょう。

$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ] 
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars

設定されていない変数をテストするより良い方法

よく見かけるアプローチは次のとおりです。

 if [ "x$var1" == "x"  ] && [ "x$var2" == "x"  ];                                                                
 then
     echo "both variables are null"
 fi

引用するには Gilles

["x $ 1" = "x"]で、xプレフィックスはx "$ 1"が演算子のように見えないことを保証するため、シェルがこのテストを解析できる唯一の方法は=を二項演算子として扱うことです。

おそらく、これは/bin/shスクリプトで見たので、かなり移植性があるはずです。以下のように組み合わせることもできます

if [ "x${var1}${var2}" == "x" ]; then
    ...
fi

もちろん-zフラグを使用できますが、一部のシェル、特にksh88( Stephane Chazelas による)の調査によると、このフラグは故障しています。

こちらもご覧ください

3

以下も機能します、

if [ "$1" == "" && "$2" == ""]; then
    echo NULL
fi
3
Avinash Raj

メッセージの意図は$ 1と$ 2がnullではないかどうかをチェックすることだったので、投稿のタイトルは正確ではないと思います。この例では、$ 1と$ 2の二重引用符が機能していません。文字列を比較するときに変数を展開するには、変数を二重引用符で囲む必要があります。ただし、$ 1と$ 2が存在するかどうかを確認することは、$ 1が存在しない場合は存在できないため、$ 2が存在するかどうかを確認することと同じです。この場合、 'test'はtrue/falseを返し、returnが0/trueの場合は '&&'を 'then'として使用するため、 'if'コマンドも不要です。

[ "$2" != '' ] && commands...

-n(ゼロ以外)を使用した単純化:

[ -n "$2" ] && commands...

「$ 1と$ 2がnullかどうかを確認する」ことは、パラメータがないかどうかを確認することと同じです。

[ $# -eq 0 ] && commands...
1
Guariba Som