Dua perangkap penting
yang diabaikan oleh jawaban lain sejauh ini:
- Mengikuti penghapusan baris baru dari ekspansi perintah
- Penghapusan karakter NUL
Mengikuti penghapusan baris baru dari ekspansi perintah
Ini adalah masalah untuk:
value="$(cat config.txt)"
ketik solusi, tetapi tidak untuk read
solusi berbasis.
Ekspansi perintah menghapus trailing newlines:
S="$(printf "a\n")"
printf "$S" | od -tx1
Output:
0000000 61
0000001
Ini memecah metode naif membaca dari file:
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
Solusi POSIX: tambahkan char tambahan ke perintah ekspansi dan hapus nanti:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Output:
0000000 61 0a 0a
0000003
Solusi Hampir POSIX: ASCII encode. Lihat di bawah.
Penghapusan karakter NUL
Tidak ada cara Bash yang waras untuk menyimpan karakter NUL dalam variabel .
Ini memengaruhi ekspansi dan read
solusi, dan saya tidak tahu solusi yang bagus untuk itu.
Contoh:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
Output:
0000000 61 00 62
0000003
0000000 61 62
0000002
Ha, NUL kita hilang!
Penanganan masalah:
Encode ASCII. Lihat di bawah.
gunakan bash extension $""
literals:
S=$"a\0b"
printf "$S" | od -tx1
Hanya berfungsi untuk literal, jadi tidak berguna untuk membaca dari file.
Solusi untuk perangkap
Menyimpan versi yang disandikan uuencode base64 dari file dalam variabel, dan mendekode sebelum setiap penggunaan:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
Keluaran:
0000000 61 00 0a
0000003
uuencode dan udecode adalah POSIX 7 tetapi tidak di Ubuntu 12.04 secara default ( sharutils
paket) ... Saya tidak melihat alternatif POSIX 7 untuk proses bash<()
ekstensi pengganti kecuali menulis ke file lain ...
Tentu saja, ini lambat dan tidak nyaman, jadi saya kira jawaban sebenarnya adalah: jangan gunakan Bash jika file input mungkin berisi karakter NUL.
cat
atau$(<someFile)
akan menghasilkan output yang tidak lengkap (ukurannya lebih kecil dari file sebenarnya).