バイナリ演算子が必要 - シェルスクリプトパラメータの引用の問題

バイナリ演算子が必要 - シェルスクリプトパラメータの引用の問題

シェルスクリプトの実行時にパラメータを追加する方法について質問があります。

IP範囲をブロックするのに役立つ簡単なスクリプトがあります。

~/block_ip.sh:

if [ ! $3 ]
then
 echo "usage ~/block_ip.sh (DROP/ACCEPT) '0.0.0.0' 'amsterdam'"
 exit 1
fi

echo "adding $3"
sudo iptables -I INPUT -s $2 -j $1 -m comment --comment "$3"

パラメータなしでこれを実行すると、期待どおりに出力されます。

~$ ./block_ip.sh
usage ~/block_ip.sh (DROP/ACCEPT) '0.0.0.0' 'amsterdam'

しかし、空白が予期しない出力の原因であるようです。「予想されるバイナリ演算子」:

~$ ./block_ip.sh DROP '1.0.0.0/8' 'south brisbane qld'
./block_ip.sh: line 1: [: brisbane: binary operator expected
adding south brisbane au

しかし、予期しない結果が出たにもかかわらずこれを追加します。

Chain INPUT (policy ACCEPT)
num  target     prot opt source           destination
1    DROP       all  --  1.0.0.0/8        anywhere         /* south brisbane au */

これが引用の問題である場合は、スペースをエスケープするためにバックスラッシュを使用せずにパラメータをどのように設定しますか?もちろん、スクリプトを変更する必要があるかもしれませんが、これは許容可能なソリューションです。

答え1

はい、引用の問題です。[ ! $3 ](および[ ! south brisbane qld ]その間の4つの引数)に拡張されます。 4つのパラメータ(そのうちの最初のパラメータはa)が表示されると、where isバイナリ演算子などの内容が表示されると予想されます。 (これは再びとの違いの1つです。[]![[ ! arg1 op arg2 ]op[ .. ][[ .. ]]この質問を見ました。そしてそしてこのQ)

brisbane有効な演算子ではないため、文句を言って誤った2を返すので、文はif実行されません。一般的な失敗テストとエラーを区別するには、2に従って戻り値を明示的にテストする必要があります。

一方、空の場合、$3テストは[ ! ]単一の引数テストになり、唯一の引数が空でないことを確認します(つまり、単一の文字列です!)。この場合、期待どおりに動作しますが、期待した理由ではない可能性があります。


文字列を引数の1つに保持または[ ! "$3" ]維持しようとしています。[ -z "$3" ][

もちろん、テストの意味を逆にして実際のタスクを実行して、ifテストエラーがデフォルトのコマンド実行を防ぐこともできます。しかし、これはコード構造をより不明瞭にする。

関連情報