シェルスクリプトの実行時にパラメータを追加する方法について質問があります。
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
テストエラーがデフォルトのコマンド実行を防ぐこともできます。しかし、これはコード構造をより不明瞭にする。