Apakah piped sama dengan ls -1?

19

lsmengembalikan output dalam beberapa kolom, sedangkan ls|catmengembalikan byte-identik dengan ls -1untuk direktori saya sudah mencoba. Masih saya lihat ls -1disalurkan dalam jawaban, seperti ls -1|wc -l. Apakah ada alasan untuk memilih ls -1? Mengapa ...|catmengubah output ls?

rubystallion
sumber
1
nama file dapat berisi baris baru, jadi Anda akan menghitungnya beberapa kali ... Anda malah bisa melakukannya: n=0; for i in .* *; do ((n++)) ; done ; echo $n(jatuhkan. * jika Anda tidak ingin menghitungnya). atau: ls -1d ./.* ./* | grep '^\./' | wc -l (karena nama file tidak boleh mengandung '/')
Olivier Dulac
3
lsoutput ke terminal biasanya menyertakan kode warna secara default. Untuk output ke non-terminal, warna biasanya dinonaktifkan secara default. Di GNU, itu adalah --color={always,auto,never}IIRC. Jika warna termasuk dalam satu tetapi bukan yang lain, maka output mungkin tampak identik pada layar, tetapi mereka tidak identik-byte (kode warna membentuk bagian dari output ls).
CVn
@ MichaelKjörling Saya pikir Anda harus menulis itu sebagai jawaban.
200_success
@ MichaelKjörling Itu sesuatu yang menarik yang belum saya pertimbangkan. Apakah ada cara umum untuk selalu pipa seolah-olah keluaran ke terminal tanpa harus mengingat opsi terminal untuk warna dan keluaran kolom, dll?
rubystallion
@rubystallion Kedengarannya seperti pertanyaan terpisah yang bagus.
CVn

Jawaban:

26

lsmenguji apakah output akan ke terminal. Jika output tidak menuju terminal, maka -1defaultnya. (Ini dapat diganti dengan salah satu -C, -matau -xpilihan.)

Jadi, ketika lsdigunakan dalam pipa dan Anda belum menimpanya dengan opsi lain, lsakan digunakan -1. Anda dapat mengandalkan ini karena perilaku ini diperlukan oleh POSIX

Spesifikasi POSIX

POSIX memerlukan -1sebagai default setiap kali output tidak pergi ke terminal:

Spesifikasi POSIX :

Format default adalah daftar satu entri per baris ke output standar; pengecualian untuk terminal atau ketika salah satu opsi -C, -m, atau -x ditentukan. Jika output ke terminal, formatnya ditentukan implementasi.

Tiga opsi yang menggantikan format kolom tunggal default adalah:

-C
Tulis output multi-teks-kolom dengan entri diurutkan ke bawah kolom, sesuai dengan urutan susun. Jumlah kolom teks dan karakter pemisah kolom tidak ditentukan, tetapi harus disesuaikan dengan sifat perangkat output. Opsi ini menonaktifkan output format panjang.

-m
Streaming format output; daftar nama jalur di seluruh halaman, dipisahkan oleh karakter <comma> diikuti oleh karakter <spasi>. Gunakan karakter <newline> sebagai terminator daftar dan setelah urutan pemisah ketika tidak ada ruang pada baris untuk entri daftar berikutnya. Opsi ini menonaktifkan output format panjang.

-x
Sama dengan -C, kecuali bahwa output multi-teks-kolom diproduksi dengan entri diurutkan, bukan ke bawah, kolom. Opsi ini menonaktifkan output format panjang.

Dokumentasi GNU

Dari manual GNU :

'-1'
'--format = kolom tunggal'
Sebutkan satu file per baris. Ini adalah default untuk ls ketika output standar bukan terminal . Lihat juga opsi -b dan -q untuk menekan output langsung dari karakter baris baru dalam nama file. [Penekanan ditambahkan]

Contohnya

Mari kita membuat tiga file:

$ touch file{1..3}

Ketika output masuk ke terminal, GNU lsmemilih untuk menggunakan format multi-kolom:

$ ls
file1  file2  file3

Ketika output beralih ke pipeline, spec POSIX mensyaratkan bahwa satu kolom adalah default:

$ ls | cat
file1
file2
file3

Tiga pengecualian yang mengesampingkan perilaku kolom tunggal default adalah -muntuk dipisahkan dengan koma, -Cuntuk kolom diurutkan ke bawah, dan -xuntuk kolom diurutkan di:

$ ls -m | cat
file1, file2, file3
$ ls -C | cat
file1  file2  file3
$ ls -x | cat
file1  file2  file3
John1024
sumber
"POSIX membutuhkan -1 sebagai default ketika output pergi ke terminal:" ... tetapi kutipan menunjukkan bahwa itu memerlukan -1sebagai default kecuali ketika output pergi ke terminal (atau kondisi lainnya)
muru
@uru Terima kasih telah menangkap itu! Jawaban diperbarui.
John1024
Ya, setiap awan memiliki garis perak. Karena jawaban Anda diterima sebelum saya diposting, saya mendapat topi pizza yang funky!
G-Man Mengatakan 'Reinstate Monica'
@ G-Man Sangat bagus. Dan, topi yang tampan itu!
John1024
9
  • Mengapa pemipaan output standar mengubah perilaku ls? Karena memang dirancang seperti itu. The POSIX Keterangan mengatakan:

    Format default adalah daftar satu entri per baris ke output standar; pengecualian adalah untuk terminal atau ketika salah satu -C, -matau -xopsi ditentukan. Jika output ke terminal, formatnya ditentukan implementasi.

    yang sebenarnya ambigu tentang perilaku default (ketika tidak ditentukan oleh opsi seperti -latau -1) dengan output ke terminal, dan dokumentasi GNU Coreutils mengatakan

    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.

    Jadi Anda dapat melihat bahwa output ke file akan bertindak sama seperti output ke pipa; yaitu, satu entri per baris, seolah-olah -1telah ditentukan.

  • Mengapa itu dirancang seperti itu? Mungkin tidak mungkin untuk mengetahui dengan pasti (kecuali seseorang dapat menemukan beberapa catatan desain), tapi saya kira:
    • Ketika lssedang menulis ke terminal, ia berharap bahwa manusia sedang melihat hasilnya. Orang akan lebih suka mendapatkan informasi dalam jumlah baris minimum yang diperlukan, sehingga barang tidak menggulung layar.
    • Ketika lsmenulis ke sebuah pipa, ia berharap bahwa program lain membaca output. Jauh lebih mudah bagi sebuah program untuk membaca data yang satu nilai per baris daripada harus mencoba mem-parsing kolom (karena nama file dapat berisi spasi).
  • Apakah ada alasan untuk memilih ls -1 ketika Anda menulis ke file atau pipa? Tidak.
G-Man Mengatakan 'Reinstate Monica'
sumber
-4

Saat mem-pip ls, ls tidak dapat menentukan berapa banyak kolom yang sebenarnya dimiliki konsol (tidak tergantung pada perintah sisi kanan). Jadi, apakah itu dilakukan atas pilihannya sendiri, atau, dengan kata lain, perilaku ini tidak stabil dan dapat berubah di versi mendatang.

Sebaliknya, ls -1diciptakan untuk tujuan penghitungan atau scripting secara umum, sehingga perilakunya stabil.

xanoetux
sumber
9
Seperti jawaban lain mengatakan perilaku ini diperlukan oleh POSIX, jadi menyebutnya tidak stabil itu salah.
Henrik - berhenti menyakiti Monica