標準入力全体を文字通りコマンドライン引数に変換するにはどうすればよいですか?

標準入力全体を文字通りコマンドライン引数に変換するにはどうすればよいですか?

1回試してください

xargs -I '{}' -0 -n 1 myprogram --arg '{}' --other-options

ただし、これはゼロバイトを保存しません。プログラムは複数回実行することもできます。ただし、標準入力にゼロバイトが入力されて失敗するのではなく、プログラムを複数回実行します。

2回試してください

myprogram --arg "`cat`" --other-options

しかし、これは末尾のスペースを保持しません。

3回試してください

bash -c 'read -r -d "" INPUT ; myprogram --arg "$INPUT" --other-options'

ターミナルを台無しにして末尾の空白を維持できないようです。


これを正確で信頼性が高く、読みやすく互換性のある方法は何ですか?

答え1

コマンドライン引数ではNULバイトを使用できません。だから質問は、このようなことが起こったらどうなることを望むのかです。はい標準入力の NUL バイトです。

指摘したように、この場合、候補ソリューション#1はコマンドを複数回実行することです。これは理想的ではありません。ただし、実際のバイナリ入力を処理するための理想的なソリューションはありません。他の合理的なオプションは次のとおりです。

  • NULバイトを削除して続行
    • 挿入するtr -d '\0' |前にxargs
  • NULバイトを別のバイトに変換して続行
    • 挿入tr '\0' something-else |xargssomething-elseシングルバイトの場合)
  • NULバイトがあれば、中断して宝石します。

    • bashまたはksh93を使用する(入力の終わりに単一のnullバイトが含まれていない場合は自動的に削除されます):

      { read -r -d '' input;
        if [ "$(wc -c)" = 0 ]; then
          printf %s "$input" | xargs …;
        else
          echo 1>&2 "Null bytes detected, bailing out"
          exit 2
        fi
      }
      
    • zshを使用する(bash、ksh、dashなどの他のシェルを使用する代わりに):

      input=$(<&0)
        if [[ $input != *$'\0'* ]]; then
          printf %s "$input" | xargs …;
        else
          echo 1>&2 "Null bytes detected, bailing out"
          exit 2
        fi
      
    • または一時ファイルを使用してください。
  • 最初の NUL バイト以降の入力を切り捨てます。

    • 挿入するtr '\0\n' '\n\0' | head -n 1 | tr '\0\n' '\n\0'xargsheadあなたが安全であると仮定)

関連情報