Ketika Anda menjalankan perintah ini:
ls
terminal menampilkan output dari ls.
Ketika Anda menjalankan perintah ini:
echo $(ls)
shell menangkap output $(ls)dan melakukan pemisahan kata di atasnya. Dengan default IFS, ini berarti bahwa semua urutan ruang putih, termasuk karakter baris baru, diganti dengan satu kosong. Itu sebabnya output echo $(ls)muncul pada satu baris.
Untuk diskusi lanjutan tentang pemisahan kata, lihat FAQ Greg .
Menekan pemisahan kata
Shell tidak melakukan pemisahan kata pada string dalam tanda kutip. Dengan demikian, Anda dapat menekan pemisahan kata dan mempertahankan output multiline dengan:
echo "$(ls)"
ls dan output multiline
Anda mungkin memperhatikan bahwa lskadang - kadang mencetak lebih dari satu file per baris:
$ ls
file1 file2 file3 file4 file5 file6
Ini adalah default ketika output dari lspergi ke terminal. Ketika output tidak langsung ke terminal, lsubah default-nya ke satu file per baris:
$ echo "$(ls)"
file1
file2
file3
file4
file5
file6
Perilaku ini didokumentasikan dalam man ls.
Kehalusan lainnya: substitusi perintah dan mengikuti baris baru
$(...)adalah substitusi perintah dan shell menghapus karakter baris baru dari output substitusi perintah . Ini biasanya tidak terlihat karena, secara default, echomenambahkan satu baris baru ke akhir outputnya. Jadi, jika Anda kehilangan satu baris baru dari akhir $(...)dan Anda memperolehnya dari echosana, tidak ada perubahan. Namun, jika output dari perintah Anda berakhir dengan 2 atau lebih karakter baris baru sambil echomenambahkan kembali hanya satu, output Anda akan hilang satu atau lebih baris baru. Sebagai contoh, kita dapat menggunakan printfuntuk menghasilkan trailing karakter baris baru. Perhatikan bahwa kedua perintah berikut, meskipun jumlah baris baru berbeda, menghasilkan output yang sama dari satu baris kosong:
$ echo "$(printf "\n")"
$ echo "$(printf "\n\n\n\n\n")"
$
Perilaku ini didokumentasikan dalam man bash.
Kejutan lain: ekspansi pathname, dua kali
Mari kita membuat tiga file:
$ touch 'file?' file1 file2
Amati perbedaan antara ls file?dan echo $(ls file?):
$ ls file?
file? file1 file2
$ echo $(ls file?)
file? file1 file2 file1 file2
Dalam kasus echo $(ls file?), file glob file?diperluas dua kali , menyebabkan nama file file1dan file2muncul dua kali dalam output. Ini karena, seperti yang ditunjukkan Jeffiekins, ekspansi pathname dilakukan terlebih dahulu oleh shell sebelum lsdijalankan dan kemudian lagi sebelum echodijalankan.
Perluasan pathname kedua dapat ditekan jika kami menggunakan tanda kutip ganda:
$ echo "$(ls file?)"
file?
file1
file2