NCが受信したすべてを次のように送信しようとしています。
nc -l 20000 | xargs /root/test
...xargsが引用符付き引数を受け取らない限り、うまくいきます。まるで別の引数であるかのように分離します。
パラメータ()を繰り返すと、パラメータ/root/test
が正しく渡されていないことがわかります。
for i in $*; do
echo "$i"
done
echo 'test1 test2'
ポート20000(nc)に送信すると、次の結果が得られます。
echo
'test1
test2'
リクエスト(ncが受け取ったもの)を二重引用符で囲み、"echo \'test1 test2\'"
この答えに従って引用符(例:)をエスケープしてみました。https://unix.stackexchange.com/a/38151/224371しかし、これは役に立ちません。ただ次のような結果を得るだけです。
echo
\'test1
test2\'
答え1
netcatはそれを介して送信されるデータに影響を与えてはいけませんので、スキップしてxargsのパイピングに集中します。
ここで:
echo "aa 'bb cc'" | xargs
シェルは引用符セットを削除し、文字列をaa 'bb cc'
xargs に送信します。 xargsは、デフォルトでは、引用符付きの文字列を単一要素として(引用符を削除)実行するコマンドにaa
文字列を渡します。bb cc
一方、ここでは:
echo "aa \'bb cc\'" | xargs
シェルは二重引用符セットを削除し、二重引用aa \'bb cc\'
符内の一重引用符(バックスラッシュを含めるか除く)は特別ではありません。ただし、二重引用符内の二重引用符はエスケープする必要があります。
xargsは文字列を表示し、自己引用符を削除しますが、引用符はエスケープされ、バックスラッシュのみを削除してスペースに分割します。 3つの文字列が残ります:aa
、、'bb
およびcc'
。これがあなたが見るものです。
一般的に、私たちはその逆を望んでいます。 xargs はファイル名の一部である可能性があるため、引用符の処理を許可しないでください。したがって、これには56の質問の推奨事項xargs -0
またはxargs -d'\n'
選択肢が表示されます。ただし、xargsに引用符付き文字列を処理させるには、引用符をエスケープせずに送信する必要があります。
もう1つの問題は、テストスクリプトが$*
引用符なしでを使用することです。これにより、すべてのパラメータが空白に分割され、結果の単語に対してグローブが実行されます。 (引用符を使用すると、パラメータは単一の文字列に連結されます。)ほとんど常にthisを使用しようとしています"$@"
。またはここだけ:
for i do
echo "$i"
done
でも:
printf '%s\n' "$@"
したがって、引用符のエスケープを確認して"$@"
代わりに使用してください$*
。
$ cat args.sh
for x in "$@" ; do echo ":$x" ; done
$ echo "aa 'bb cc' \"dd ee\""
aa 'bb cc' "dd ee"
$ echo "aa 'bb cc' \"dd ee\"" | xargs ./args.sh
:aa
:bb cc
:dd ee