Mengapa tanda kurang dari itu tidak berfungsi sebagai pengganti cat in bash?

17

Saya mendengar tentang "penggunaan kucing yang tidak berguna" dan menemukan beberapa saran, tetapi berikut ini tidak menghasilkan apa-apa di bash shell saya.

< filename

Namun, menggunakan kucing berfungsi seperti yang diharapkan.

cat filename

Saya menggunakan Fedora Core 18 dan GNU bash, versi 4.2.45 (1).

EDIT: Menggunakannya di depan pipa juga tidak berhasil.

< filename | grep pattern

Padahal menggunakan kucing berfungsi seperti yang diharapkan.

cat filename | grep pattern

EDIT2: Untuk memperjelas, saya tahu saya bisa menggunakan ini

grep pattern < filename

tapi saya baca di sini /programming/11710552/useless-use-of-cat bahwa saya juga bisa menggunakannya di depan perintah. Itu tidak bekerja di depan perintah sekalipun.

bug
sumber
2
Berhasil. Apa yang Anda coba tidak sama dengan komentar Jonathan Leffler .
manatwork
"Tujuan dari kucing adalah untuk menyatukan (atau" menyatukan ") file. Jika hanya satu file, menggabungkannya dengan tidak ada sama sekali adalah buang-buang waktu, dan biaya proses Anda." partmaps.org/era/unix/award.html
Bonsi Scott

Jawaban:

22

Yang kurang dari dan simbol ( <) adalah membuka file dan melampirkannya ke pegangan perangkat input standar dari beberapa aplikasi / program. Tetapi Anda belum memberikan aplikasi apa pun untuk dilampirkan pada shell.

Contoh

2 contoh ini pada dasarnya melakukan hal yang sama tetapi mendapatkan masukan mereka dalam 2 cara yang sedikit berbeda.

membuka file

$ cat blah.txt 
hi

membuka STDIN

$ cat < blah.txt 
hi

Mengintip di balik tirai

Anda dapat menggunakan straceuntuk melihat apa yang terjadi.

Ketika kami membaca dari file

open("blah.txt", O_RDONLY)              = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=3, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(3, "", 65536)                      = 0
close(3)                                = 0
close(1)                                = 0

Ketika kami membaca dari STDIN (diidentifikasi sebagai 0)

read(0, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(0, "", 65536)                      = 0
close(0)                                = 0
close(1)                                = 0

Dalam contoh pertama kita dapat melihat bahwa catmembuka file dan membaca darinya blah.txt,. Di bagian kedua kita dapat melihat yang catmembaca isi file blah.txtmelalui deskriptor file STDIN, diidentifikasi sebagai deskriptor nomor 0.

read(0, "hi\n", 65536)                  = 3
slm
sumber
1
Jadi pembicaraan tentang penggunaan kucing yang tidak berguna ini palsu?
bug
@bug - tidak, ada kegunaan. Tetapi catumumnya disalahpahami dan digunakan saat itu tidak perlu.
slm
Tetapi apakah perlu ketika saya ingin menjaga urutan operasi dari kiri ke kanan? Saya membaca bahwa adalah mungkin untuk menggunakan konstruk yang kurang dari di depan perintah juga.
bug
@bug ya pengalihan dapat terjadi sebelum atau setelah perintah, lihat jawaban Stephane, dia menunjukkan contoh ini juga.
slm
Ah, sekarang saya mengerti. Saya harus menulis < filename command.
bug
14

Penggunaan klasik yang tidak berguna catadalah ketika Anda menggunakannya untuk memberikan input ke program yang mampu membuka file secara langsung. Sebagai contoh:

Buruk

cat file | grep foo
cat file | while read line; do echo "$line"; done
cat file | sed 's/a/b/'
cat file | awk '{print $1}'

Baik

grep foo file
while read line; do echo "$line"; done < file 
sed 's/a/b/' file
awk '{print $1}' file

Juga bagus ( <filebisa di kedua sisi perintah)

<file grep foo
 sed 's/a/b/' < file
<file awk '{print $1}' 
terdon
sumber
6
"Buruk" subyektif di sini. Saya menemukan mereka menjadi lebih baik secara keseluruhan, karena cara ini lebih konsisten dan lebih mudah dibaca. Dan aliran data sepenuhnya dari kiri ke kanan, sebagaimana mestinya jika ada lebih banyak pipa yang terlibat
Izkata
2
@Izkata mereka "buruk" dalam arti bahwa mereka tidak berguna cat.
terdon
"Turun! Turun dari meja! Kamu kucing yang buruk! ";-) Tapi serius ...
G-Man Mengatakan 'Reinstate Monica'
1
Penting baik (atau, setidaknya, berguna) penggunaan cattermasuk (1) cat file(dengan output ke layar / terminal; meskipun, jika file lebih panjang dari layar tinggi, Anda mungkin lebih suka menggunakan moreatau lessatau sesuatu seperti itu), (2) cat file1 file2 file3 > all_data( persis apa yang catdimaksudkan untuk), (3) cat f1 f2 f3 | tr …(atau pipa ke program lain yang Anda tidak ingin melewatkan file untuk langsung, misalnya, wc(misalnya, jika Anda ingin melihat grand keseluruhan saja) atau grep(misalnya, jika Anda memiliki versi lama yang tidak mendukung -h, yaitu, --no-filename)), ... (Lanjutan)
G-Man Berkata 'Reinstate Monica'
(Lanjutkan) ... (4) cat -n file | sort … -k1 | sed 's/^ *[0-9]*\t//', (5) sudo cat file600 | untrusted_program(yaitu, Anda (UID Anda) tidak dapat membaca file, dan Anda tidak ingin menjalankan program sebagai root atau bahkan UID semi-privilege). Juga, ( e ) (yaitu, angka antara 2 dan 3) program_that_generates_html | cat static_html_header - static_html_footer(yang Anda mungkin ingin redirect ke file atau pipa).
G-Man Says 'mengembalikan Monica'
13

UUOC ada di:

cat somefile | some-cmd

atau

cat < somefile | some-cmd

Di sana, some-cmdmembaca konten dari somefilepipa yang diumpankan dengan catmana ia membacanya somefile.

some-cmddapat membaca langsung dari somefile(setelah shell membukanya di stdin), tidak perlu cat:

some-cmd < somefile

atau

< somefile some-cmd

(pengalihan dapat muncul di mana saja di baris perintah sederhana).

Stéphane Chazelas
sumber