Kode berikut paling menggambarkan situasi. Mengapa baris terakhir tidak menghasilkan char baris baru yang tertinggal? Output setiap baris ditampilkan dalam komentar. Saya menggunakan bash GNU, versi 4.1.5
echo -n $'a\nb\n' | xxd -p # 610a620a
x=$'a\nb\n' ; echo -n "$x" | xxd -p # 610a620a
echo -ne "a\nb\n" | xxd -p # 610a620a
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p # 610a62
tmp=$(somecommand; echo a); tmp=${tmp%a}
tmp=$(somecommand; echo a)
... Ini sudah pasti mengarahkan poinnya ke rumah ... Sampai saya melihat contohnya, kecenderungan saya masih akan digunakanecho -n a
... tapi, tentu saja !, tidak perlu itu-n
, karena Substitusi Perintah akan menghapus baris tambahan yang diperkenalkan di awal! ... terima kasih ...Jawaban:
Fungsi substitusi perintah
$()
(dan sepupunya pada backtick) secara khusus menghapus baris baru. Ini adalah perilaku yang didokumentasikan , dan Anda harus selalu menyadarinya saat menggunakan konstruk.Baris baru di dalam badan teks tidak dihapus oleh operator substitusi, tetapi baris tersebut juga dapat dihapus ketika melakukan pemisahan kata pada shell, jadi bagaimana hasilnya tergantung pada apakah Anda menggunakan tanda kutip atau tidak. Perhatikan perbedaan antara kedua penggunaan ini:
Dalam contoh kedua, output tidak dikutip dan baris baru ditafsirkan sebagai pemisahan kata, sehingga ditampilkan dalam output sebagai spasi!
sumber
Saat menggunakan substitusi perintah, shell mengeksekusi perintah dalam subshell, mengembalikan stdout mereka. dalam proses ini, karakter IFS kehilangan signifikansinya (jika tidak dikutip), karena commend mengembalikan kata-kata split, jadi yang trailing dihapus. Sebagai contoh:
dan lebih praktisnya,
pwd
akan berfungsi bahkan jika nama direktori Anda memiliki baris baru di antaranya, tetapi$(pwd)
tidak akan.Solusi yang biasa adalah menambahkan sesuatu di akhir perintah Anda dan menghapusnya setelahnya.
sumber
echo "$(echo -e '\n')" | wc
, yang menghasilkan1 0 1
, dibandingkan dengan2 0 2
$(pwd)
dan"$(pwd)"
, lihat jawaban Caleb.