xargsとパイプを使用して標準出力を複数の単語を許可しない生データに変換する

xargsとパイプを使用して標準出力を複数の単語を許可しない生データに変換する

現在コマンドを実行しています。echo "hello world" | xargs curl http://localhost:8080/function/func_wordcount -d"標準出力を取得し、オプションを使用するようにecho "hello world"パイプfunc_wordcountします-d。この-dオプションは生データを送信するために使用され、myは生func_wordcountデータの入力を許可し、単語数と文字数を印刷します。

たとえば、私が書くとき、echo "hello" | xargs curl http://localhost:8080/function/func_wordcount -d"出力は1、5です。これは、5つの文字を含む単語があることを意味します。

ただし、多くの単語を含めようとするとエラーが発生します。書き込み時にecho "hello world" | xargs curl http://localhost:8080/function/func_wordcount -d"出力1、5が表示され、エラーのある改行文字が表示されますcurl: (6) could not resolve host: world。したがって、これらのオプションを使用してstdoutを生データに変換すると、hello worldが2つの単語に分割されると確信しています-d

また、関数がパイプや変換なしで機能することを示すために関数を実行すると、2、11が表示され、2つの単語とcurl http://localhost:8080/function/func_wordcount -d "hello world"11の文字があることを示しています。

私の質問は、この分割問題を解決する方法です。私が混乱しているのは、入力の前半だけを解析して完了し、データの塊を送信するのではなく、2番目の部分でエラーを発生させる理由です。スペースで区切られていない入力のみを送信できるため、機能の使用は非常に制限されます。

答え1

それだけですxargs。標準入力から単語リスト(スペースまたは改行で区切られ、いくつかの形式の引用も理解しています)を受け入れて渡します。それら実行されるコマンドの引数として。

hello wordここからパラメータとして渡すには、curl次のものが必要です。

echo '"hello world"' | xargs curl...

これは、スペース間のスペースがパラメータ区切り文字で処理されるのをxargs防ぐための引用メカニズムとして理解されています。"..."また、(POSIXシェルとは異なる方法で)理解しています。helloworldxargs\'...'

GNU ではxargs区切り文字を指定することもできます。たとえば、

echo hello world | xargs -d '\n' curl...

改行のみが区切り文字(空白ではない)として認識され、引用メカニズムは無効になります。

これにより、各単語ではなく各行の内容をコマンドの引数として渡すことができます。

-dGNUの外ではほとんどサポートされていませんが、xargsNULを-0区別し、引用符を無効にする別の拡張がより広くサポートされています。したがって、次のようにすることもできます。

echo hello world | tr '\n' '\0' | xargs -0 curl...

複数行の入力がある場合、xargsすべての行は別々の引数として渡されます。各行に1つずつ呼び出すcurlには、オプションを追加できます。curl-n 1

以下も使用できます。

echo hello world | xargs -I@@ curl... @@

これはcurl各行ごとに1つずつ呼び出されますが、前のスペースは削除され、xargsいくつかの引用がまだ実行されるため、任意のデータを避ける必要があります。

答え2

~からGNU xargs のマニュアルページ:

xargs標準入力、区切り文字から項目を読むスペース(二重引用符、一重引用符、またはバックスラッシュで保護できます)または 改行文字、初期引数を使用してコマンドを1回以上実行し、標準入力から読み取った項目を実行します。

つまり、デフォルトの動作は、入力内のすべてのスペースが区切り文字として機能するため、hello world実際には2つの引数が生成されることです。

xargsが行全体をそのまま維持するには、 `xargs -d '\ n'を使用してください(GNU xargsでは他のことを覚えていません)。

ただし、複数の引数が与えられると、まだ複数行の入力が発生しますcurl。これを防ぎ、curl各入力ラインに対してコマンドを一度実行するには、を使用しますxargs -d '\n' -n 1

入力に1行しか含まれていない場合は、パイピングの代わりにコマンド置換を使用できます。

curl http://... -d "$(echo "hello world")"

関連情報