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


40

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

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

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


1.スクリプトを呼び出すコマンドと2.完全な出力を提供する必要があります。
ルシオ14

2
を使用する必要があります[[ ]]。それ以外の場合は、変数を引用する必要があります。
クリストフ・デ・トロイエ

$ 1が存在しなかった場合、$ 2は$ 1になり、$ 1と$ 2の両方がnullであるかどうかのテストは無関係に見えます。
WinEunuuchs2Unix 16

@ WinEunuuchs2Unix必ずしも無関係ではありません-場合によっては、引数に空白またはヌル文字列の代わりに実際に何かがあることを確認したいことがあります。$1スクリプトのユーザーが設定解除するか、ヌル文字列に設定できます。この一連のコマンドを考えてみましょう。$ set '' barその後、echo "x${1}x";両方の変数が設定されますが、そのうちの1つはヌルです。
セルギーKolodyazhnyy

回答:


55

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

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

男からbash

-z string
   True if the length of string is zero.

わたしにはできる!
pengisgood

最も投票されて受け入れられた答えが、質問に対して実際に答えていないことは興味深いことです。
メフメト

ポータブルシェルスクリプトを作成する場合、このフラグは注意して使用する必要があります。特定の商用Unixでは、このフラグに欠陥があるためです。リンクされたソースに関する私の答えをご覧ください。
セルギーKolodyazhnyy

14

これはタグ付きなのでbash拡張テスト構成([[...]])を使用し、引用符を忘れることをお勧めします。

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

sh/ POSIXとの互換性を考えていない限り、を使用しない理由はありません[[ ]]


3

以下も機能します、

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

&&そして他の論理コマンドセパレータは、古典的に許可されていませんtest。あなたは(のような代わりに、他のテスト構造を使用する必要があり-a、私は思う)
muru

3

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

問題の原因

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

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

では/bin/shこれが実際にシンボリックリンクされている/bin/dashUbuntuの上で、以下のように、エラーが報告されました:

$ 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

ジルを引用するには:

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

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

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

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

こちらもご覧ください


+1は非常に興味深いアプローチです。
WinEunuuchs2Unix

@ WinEunuuchs2Unix編集してさらにおもしろい:)
セルギー・コロディアズニー

1

メッセージの意図は$ 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...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.