2つの重要な落とし穴
これまでのところ他の回答では無視されていました:
- コマンド展開からの末尾の改行の削除
- NUL文字の削除
コマンド展開からの末尾の改行の削除
これは次の問題です。
value="$(cat config.txt)"
タイプソリューション。ただし、read
ベースソリューションでは使用できません。
コマンド展開により、末尾の改行が削除されます。
S="$(printf "a\n")"
printf "$S" | od -tx1
出力:
0000000 61
0000001
これは、ファイルから読み取る単純な方法を壊します。
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
POSIXの回避策:コマンド展開に余分な文字を追加し、後で削除します。
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
出力:
0000000 61 0a 0a
0000003
ほとんどPOSIXの回避策:ASCIIエンコード。下記参照。
NUL文字の削除
変数にNUL文字を格納するための健全なBashの方法はありません。
これは、拡張と read
ソリューションのますが、適切な回避策はわかりません。
例:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
出力:
0000000 61 00 62
0000003
0000000 61 62
0000002
ハ、私たちのNULはなくなった!
回避策:
落とし穴の回避策
uuencode base64エンコードバージョンのファイルを変数に格納し、使用する前にデコードします。
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
出力:
0000000 61 00 0a
0000003
uuencodeとudecodeはPOSIX 7ですが、Ubuntu 12.04にはデフォルトでsharutils
はありません(パッケージ)... bashプロセスのPOSIX 7の代替案が表示されません<()
別のファイルに書き込むことを除いて置換拡張機能の ...
もちろん、これは遅くて不便なので、本当の答えは、入力ファイルにNUL文字が含まれている可能性がある場合はBashを使用しないことです。
cat
または$(<someFile)
(サイズが実際のファイルよりも小さい)、不完全な出力になります。