Output dari ls memiliki baris baru tetapi ditampilkan pada satu baris. Mengapa?

41

Saya pikir saya mungkin mengabaikan poin yang relatif mendasar tentang shell. Output dari perintah ls secara default memisahkan output dengan baris baru, tetapi shell menampilkan output pada satu baris.

Adakah yang bisa menjelaskan hal ini kepada saya? Saya selalu berasumsi bahwa output hanya dipisahkan oleh spasi, tetapi sekarang saya melihat output dipisahkan oleh baris baru, saya berharap output akan ditampilkan pada baris yang berbeda.

Contoh:

cpoweradm@debian:~/lpi103-4$ ls text*
text1  text2  text3

od menunjukkan bahwa output dipisahkan oleh baris baru:

cpoweradm@debian:~/lpi103-4$ ls text* | od -c
0000000   t   e   x   t   1  \n   t   e   x   t   2  \n   t   e   x   t
0000020   3  \n
0000022

Jika ada baris baru, maka mengapa output tidak ditampilkan sebagai:

text1 
text2
text3
zod90
sumber

Jawaban:

44

Ketika Anda menyalurkan output, lsbertindak berbeda.

Fakta ini disembunyikan dalam dokumentasi info :

Jika output standar adalah terminal, output dalam kolom (diurutkan secara vertikal) dan karakter kontrol adalah output sebagai tanda tanya; jika tidak, output terdaftar satu per baris dan karakter kontrol adalah output apa adanya.

Untuk membuktikannya, coba jalankan

ls

lalu

ls | less

Ini berarti bahwa jika Anda ingin output dijamin menjadi satu file per baris, terlepas dari apakah itu sedang disalurkan atau dialihkan, Anda harus menjalankan

ls -1

( -1adalah yang nomor satu)

Atau, Anda dapat memaksa ls | lessuntuk menghasilkan dalam kolom dengan menjalankan

ls -C

( -Cadalah huruf kapital C)

Mikel
sumber
6
@ theconnorpower: cukup spesifik untuk ls. Ini berguna, tetapi jelas tidak konsisten dan mengejutkan. Tetapi perhatikan bahwa beberapa perintah yang menghasilkan keluaran berwarna akan menghapus warna saat disalurkan juga.
Mikel
5
@theconnorpower: Trivia: Para penemu Unix kemudian menulis Plan9. Di Plan9, lsselalu cetak satu per baris, dan lcselalu cetak dalam kolom.
Mikel
2
@theconnorpower: Ada juga program yang membaca ukuran terminal, dan menyesuaikan outputnya, misalnya pada Debian dpkg -lakan menggunakan seluruh lebar layar, tetapi jika itu mencetak ke pipa, ia menganggap terminal memiliki lebar 80 kolom , dan menyingkat output agar pas jika perlu.
Mikel
1
@Mikel Menarik untuk mendengar perbedaan ls / lc di Plan9. Terima kasih atas jawaban terinci.
zod90
1
Bagaimana suatu program dapat menentukan apakah outputnya diarahkan ke suatu file atau apakah itu akan menjadi shell?
user2820379
4

Penemuan Anda menyoroti alasan utama mengapa mengurai output lsselalu merupakan ide yang buruk. Lihat wiki Greg untuk penjelasan lengkap .

Pikirkan masalah Anda secara terbalik. Anda perhatikan bahwa kadang-kadang memang dan kadang-kadang tidak mencetak baris baru di antara output itu. Untuk digunakan dalam skrip atau ketika dipaksa oleh -1bendera, itu berlaku. Satu baris baru di akhir setiap file. Apa yang tidak ada jaminan bahwa setiap baris baru mewakili nama file baru . Bahkan, jika nama file mengandung baris baru itu sendiri, output dari ls akan absolut dan tidak dapat diuraikan. Pertimbangkan nama file ini:

file1
file2\nfile3
file4

Ketika Anda ls -1direktori dengan itu di dalamnya, Anda akan mendapatkan sesuatu yang tampak seperti ini:

file1
file2
file3
file4

Tidakkah Anda secara alami mengasumsikan ada empat file? Begitu juga skrip yang mem-parsing keluaran ls. Pada kenyataannya ada tiga file, salah satunya dengan nama yang rumit, tetapi Anda tidak akan dapat menemukan itu dari output ls. *

* Kecuali jika Anda menggunakan -lbendera dan melihat hasilnya borked, tetapi skrip Anda masih akan tersedak.

Caleb
sumber
3
Jika Anda benar - benar harus menguraikan output ls, -bopsi dapat membantu. Ini mengubah baris baru menjadi \n, dll.
Mikel