$ FILE="$(mktemp)"
$ printf "a\0\n" > "$FILE"
$ od -tx1z "$FILE"
0000000 61 00 0a >a..<
0000003
今まではそんなに良くなった。
上記の内容をbashスクリプトでカプセル化しました。
#! /bin/bash
cmd=("$@")
FILE="$(mktemp)"
eval "${cmd[@]}" > "$FILE"
od -tx1z "$FILE"
しかし、
$ script printf 'a\0\n'
0000000 61 30 6e >a0n<
0000003
出力が\0
リテラル文字列になるのはなぜですか?これが起こらないようにするにはどうすればよいですか?
この投稿ではあまり重要ではありません。私の問題は、いくつかのコマンドをbashスクリプトでラップしようとした結果です。NUL 除去によるコマンド拡張の防止:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
ベストアンサー1
出力が
\0
リテラル文字列になるのはなぜですか?これが起こらないようにするにはどうすればよいですか?
.eval
バックスラッシュでエスケープされた 0 と 0 を使用してeval
コマンドを実行し、バックスラッシュを削除してそのままにします。printf a\0\n
n
代わりに、これを効果的に防ぐことができますeval
。を使用すると、"$@" > "$FILE"
スクリプト引数で指定されたコマンドを実行できる必要があります。ただし、この場合は使用できませんeval
。あるいは、コマンドを引数として渡す必要がないように全体を再設計することもできます。
コマンド拡張がNULを削除するのを防ぐために、いくつかのコマンドをbashスクリプトでラップしようとしています。
S="$(uuencode -m "$FILE" /dev/stdout)"
これはここで問題ですか?uuencode -m
NULバイトを生成してはいけません。バイナリデータをテキストにエンコードするので正反対です。
最後のスクリプトはa
、NUL および改行文字を作成して に渡します。これにより、16進表現または同様の内容が$FILE
印刷されます。od
0000000 61 00 0a