İki önemli tuzak
Şimdiye kadar başka cevaplar tarafından göz ardı edildi:
- Komut genişletmesinden son satırsonu kaldırma işlemi
- NUL karakteri kaldırma
Komut genişletmesinden son satırsonu kaldırma işlemi
Bu, aşağıdakiler için bir sorundur:
value="$(cat config.txt)"
tipi çözümler, ancak read
tabanlı çözümler için değil .
Komut genişletme, takip eden yeni satırları kaldırır:
S="$(printf "a\n")"
printf "$S" | od -tx1
Çıktılar:
0000000 61
0000001
Bu, dosyalardan naif okuma yöntemini kırar:
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
POSIX geçici çözümü: komut genişletmesine fazladan bir karakter ekleyin ve daha sonra kaldırın:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Çıktılar:
0000000 61 0a 0a
0000003
Neredeyse POSIX geçici çözümü: ASCII kodlaması. Aşağıya bakınız.
NUL karakteri kaldırma
NUL karakterlerini değişkenlerde saklamanın aklı başında bir Bash yolu yoktur .
Bu hem genişlemeyi hem de read
çözümleri etkiler ve bunun için iyi bir çözüm bilmiyorum.
Misal:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
Çıktılar:
0000000 61 00 62
0000003
0000000 61 62
0000002
Ha, NUL'umuz gitti!
Geçici Çözümler:
ASCII kodlaması. Aşağıya bakınız.
bash uzantısı $""
değişmezlerini kullanın :
S=$"a\0b"
printf "$S" | od -tx1
Yalnızca değişmez değerler için çalışır, bu nedenle dosyalardan okumak için yararlı değildir.
Tuzaklar için geçici çözüm
Bir uuencode base64 kodlu sürümünü değişkente saklayın ve her kullanımdan önce kodunu çözün:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
Çıktı:
0000000 61 00 0a
0000003
uuencode ve udecode POSIX 7'dir ancak varsayılan olarak Ubuntu 12.04'te değildir ( sharutils
paket) ... <()
Başka bir dosyaya yazmak dışında bash işlemi ikame uzantısı için POSIX 7 alternatifini görmüyorum ...
Tabii ki, bu yavaş ve elverişsiz, bu yüzden gerçek cevap: giriş dosyası NUL karakterler içeriyorsa Bash kullanmayın.
cat
ya$(<someFile)
(boyut gerçek dosyadan daha azdır) tamamlanmamış bir çıkış ile sonuçlanacaktır.