変数を使用せずに直接使用すると、条件が機能しないのはなぜですか?

変数を使用せずに直接使用すると、条件が機能しないのはなぜですか?

パラメータが多すぎるというエラーが発生します。

if [ $( file -b $i ) == "directory" ]

しかし、これを試してみました。

name=$( file -b $i )
if [ name == "directory" ]

とてもうまくいくようです。

誰かがこれを説明したり、文書で説明を指摘したりできますか?

答え1

いくつかの質問があります:

  • ][は()パラメータの終わりを表しtest、これは複数のsを持つ最後のパラメータでなければなりません。]これはおそらく間違っています。

    if [ $( file -b $i ) == "directory" ]
    
  • 上記の方法を使用すると、変数拡張()とコマンド置換(command)の出力でbash: [: too many arguments単語の分割が実行され、その前に複数の単語が表示され、エラーメッセージが表示されるため、これらのエラーが発生します。変数の拡張とコマンドの置き換えを引用する必要があります。$i$()file[=

    [ "$(file -b "$1")" == "directory" ]
    

参考までに、前者は単語分割(およびパス名拡張)を処理するため、代わりにbashキーワードを使用する必要があります。[[[

答え2

if [ $( file -b $i ) == "directory" ]

ここには2つの質問があります。

  • =文字列比較にはSingleを使用してください。正しい構文を確認してくださいman test(ほとんどの場合、シェル固有の実装があるため、ドキュメントがない場合は[シェル構文を参照してください)。必要に応じて使用してください。これはbash、ksh、zshを含む多くのBourneシェルの機能です。注:bashに存在する間man pagetest==[[==バージョン2.0以降、 "=はPOSIX準拠のテストコマンドと一緒に使用する必要があります。" (バッシュのマニュアルページ)。

  • すべての変数を"$()"特に興味のある項目として参照してください$i$iシェルの単語拡張により、空白のあるファイル名は複数の単語に分割されます。

例:

bash-4.3$ mkdir with\ space
bash-4.3$ i="./with space"
bash-4.3$ set -x
bash-4.3$ [ $( file -b $i ) == "directory" ] && echo "YES"
++ file -b ./with space
+ '[' cannot open '`./with'\''' '(No' such file or 'directory)' cannot open '`space'\''' '(No' such file or 'directory)' == directory ']'
bash: [: too many arguments

name=$( file -b $i )
if [ name == "directory" ]

ここに質問:

  • name変数の拡張はありません。ここには文字列「名前」しかありません。君は"$name"またシングルにならなければならない=

testまた、終了ステータスがfalse(終了ステータス1)を返すため、機能できません。

$ name=$(file -b /etc)
$ set -x
$ [ name == "directory" ]
+ '[' name '==' directory ']'
$ echo $?
+ echo 1
1

上記はbashシェルでmkshテストされました。

答え3

質問がたくさんあります! 「働く」部分を見てみましょう。

 name=$( file -b $i )
 if [ name == "directory" ]

これはファイルコマンドの出力を名前付き変数に割り当てますnameが、それを使わずに[3つの引数を使用してコマンドを実行します。 Accept は bash 拡張です。name==directory==

代わりに使用するように変更すると、$name多くの場合name問題が再発生します。これは複数の単語の結果が返されるtoo many argumentsためです。たとえば、コマンドを実行した後は。fileASCII text

if [ ASCII text == directory ]

これで、コマンドにいくつかのグループ化がないことが明らかになりました。

if [ "$(file -b -- "$i")" = "directory" ]

おそらくあなたが望むもの:=代わりに==移植性のためにコマンド置換の結果を引用してください。あなたがほとんどいつもしたいこと

関連情報