xargs: 引数行が長すぎます。

xargs: 引数行が長すぎます。

シェルスクリプトで次の行を実行すると:

/sbin/iptables-save -t filter | 
grep -- "-A INPUT" | 
grep -v "fail2ban-\|f2b-" | 
sed -e "s#^-A#apply_rule /sbin/iptables -D#g" | 
xargs -0 echo -e "`declare -f apply_rule`\n" | 
/bin/bash

確認するのはすべてです。

-A INPUT -s IP -j DROP 

ルールiptables-save

説明する、

-A INPUT -s 198.55.114.215 -j DROP

その後、Deleteバージョンに変換され、次に渡されます。xargs

apply_rule /sbin/iptables -D INPUT -s 198.55.114.215 -j DROP

2000 -Aしかし、ルールがあり、iptables-saveそれを実行しようとすると、上記の行でエラーが発生します。

xargs: argument line too long

制限を確認してください。

echo $(( $getconf ARG_MAX

結果:

2621440

ルールがあるとこのエラーは発生しませんが、1000 -Aルール2000 -Aがあるとiptables-saveこの問題が発生します。

実際のエラーは次のとおりです。

xargs -0 echo -e "`declare -f apply_rule`\n"

この問題をどのように解決できますか?

ベストアンサー1

パイプラインを見てみましょう。

/sbin/iptables-save -t filter | 
grep -- "-A INPUT" | 
grep -v "fail2ban-\|f2b-" | 
sed -e "s#^-A#apply_rule /sbin/iptables -D#g" | 
xargs -0 echo -e "`declare -f apply_rule`\n" | 
/bin/bash

iptables1行に1つのルールでルールのリストを生成します。つまり、各ルールは改行文字で区切られます\n。一度に1行ずつ入力を処理するには、表示されているオプションとgrepコマンドを使用します。sedつまり、改行で区切られた入力を期待し、改行で区切られた出力も生成します。 xargs -0ただし、nullで区切られた入力が期待されます。前のコマンドの出力にはヌル文字は含まれていないため、xargsすべての標準入力を単一の項目として一度に読み取ろうとします。これが「パラメータ行が長すぎます」というエラーメッセージが生成される理由です。

解決策は、xargs改行で区切られた入力を期待するように指示することです。そのためにオプションを追加します-d '\n'。しかし、我々は一度に1行だけを処理したいと思います。これを行うには、-n1次のすべてを指定する必要があります。

/sbin/iptables-save -t filter | 
grep -- "-A INPUT" | 
grep -v "fail2ban-\|f2b-" | 
sed -e "s#^-A#apply_rule /sbin/iptables -D#g" | 
xargs -n1 -d '\n' echo -e "`declare -f apply_rule`\n" | 
/bin/bash

文書

からman xargs

-D区切り
入力は指定された文字で終了します。引用符とバックスラッシュは特別ではありません。入力のすべての文字は文字通り処理されます。他のパラメーターと同様に処理されるファイル終了文字列を無効にします。このオプションは、入力が改行で区切られた項目のみで構成されている場合に使用できますが、可能であれば --null を使用するようにプログラムを設計することは、ほぼ常に優れています。指定された区切り文字は、単一文字、Cスタイル文字エスケープ(\ nなど)、または8進数または16進数のエスケープコードです。 8進数と16進数のエスケープコードはprintfコマンドとして理解されます。マルチバイト文字はサポートされていません。

-Nmax-args
コマンドラインごとに最大 max-args 個の引数を使用します。サイズを超えると(-sオプションを参照)、-xオプションが指定されていない限り、max-argsよりも少ない引数が使用されます。この場合、xargsは終了します。

おすすめ記事