評価する

評価する
$ 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\nn

代わりに、これを効果的に防ぐことができますeval。を使用すると、"$@" > "$FILE" スクリプト引数で指定されたコマンドを実行できる必要があります。ただし、この場合は使用できませんeval。あるいは、コマンドを引数として渡す必要がないように全体を再設計することもできます。

コマンド拡張がNULを削除するのを防ぐために、いくつかのコマンドをbashスクリプトでラップしようとしています。

S="$(uuencode -m "$FILE" /dev/stdout)"

これはここで問題ですか?uuencode -mNULバイトを生成してはいけません。バイナリデータをテキストにエンコードするので正反対です。

最後のスクリプトはa、NUL および改行文字を作成して に渡します。これにより、16進表現または同様の内容が$FILE印刷されます。od0000000 61 00 0a

おすすめ記事