ทำไมเครื่องหมายน้อยกว่าไม่ทำงานแทนแมวในทุบตี?


17

ฉันได้ยินเกี่ยวกับ "การใช้แมวที่ไร้ประโยชน์" และพบคำแนะนำบางอย่าง แต่ผลลัพธ์ต่อไปนี้ไม่มีอะไรในเปลือก bash ของฉัน

< filename

การใช้แมวทำงานได้ตามที่คาดหวัง

cat filename

ฉันใช้ Fedora Core 18 และ GNU ทุบตีรุ่น 4.2.45 (1)

แก้ไข: การใช้งานที่ด้านหน้าของไปป์ไม่ทำงานเช่นกัน

< filename | grep pattern

ในขณะที่ใช้แมวทำงานตามที่คาดไว้

cat filename | grep pattern

แก้ไข 2: เพื่อชี้แจงฉันรู้ว่าฉันสามารถใช้สิ่งนี้

grep pattern < filename

แต่ฉันอ่านที่นี่/programming/11710552/useless-use-of-catว่าฉันยังสามารถใช้หน้าคำสั่ง มันไม่ทำงานต่อหน้าคำสั่งแม้ว่า


2
มันได้ผล. เพียงแค่สิ่งที่คุณพยายามที่จะไม่เหมือนกันเป็นความคิดเห็นของโจนาธาน Leffler ของแสดงให้เห็น
จัดการ

"วัตถุประสงค์ของแมวคือการเชื่อมไฟล์ (หรือ" catenate ") เข้าด้วยกันหากเป็นไฟล์เดียวการต่อไฟล์โดยไม่มีอะไรเลยเป็นการเสียเวลาและค่าใช้จ่ายในการดำเนินการ" partmaps.org/era/unix/award.html
Bonsi Scott

คำตอบ:


22

สัญลักษณ์ที่น้อยกว่าและ ( <) กำลังเปิดไฟล์ขึ้นมาแล้วแนบไปที่อุปกรณ์ป้อนข้อมูลมาตรฐานของแอพพลิเคชั่น / โปรแกรมบางตัว แต่คุณยังไม่ได้ให้แอปพลิเคชั่นใด ๆ ของเปลือกเพื่อแนบอินพุต

ตัวอย่าง

ตัวอย่างที่ 2 เหล่านี้ทำสิ่งเดียวกัน แต่รับข้อมูลในลักษณะที่แตกต่างกันเล็กน้อย 2

เปิดไฟล์

$ cat blah.txt 
hi

เปิด STDIN

$ cat < blah.txt 
hi

มองหลังม่าน

คุณสามารถใช้straceเพื่อดูว่าเกิดอะไรขึ้น

เมื่อเราอ่านจากไฟล์

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

เมื่อเราอ่านจาก STDIN (ระบุเป็น 0)

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

ในตัวอย่างแรกเราจะเห็นว่าเปิดไฟล์และอ่านจากมันcat blah.txtในครั้งที่สองเราจะเห็นว่าcatอ่านเนื้อหาของไฟล์blah.txtผ่านตัวอธิบายไฟล์ STDIN ซึ่งระบุว่าเป็นตัวบอกหมายเลข 0

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

1
ดังนั้นการพูดคุยเกี่ยวกับการใช้แมวที่ไร้ประโยชน์นั้นเป็นการหลอกลวง?
ข้อผิดพลาด

@bug - ไม่มีประโยชน์ แต่catโดยทั่วไปแล้วจะเข้าใจผิดและใช้เมื่อไม่จำเป็น
slm

แต่มันเป็นสิ่งจำเป็นเมื่อฉันต้องการรักษาลำดับของการดำเนินการจากซ้ายไปขวา ฉันอ่านว่ามันเป็นไปได้ที่จะใช้โครงสร้างที่น้อยกว่าคำสั่งด้านหน้าเช่นกัน
ข้อผิดพลาด

@bug ใช่การเปลี่ยนเส้นทางอาจเกิดขึ้นก่อนหรือหลังคำสั่งดูคำตอบของ Stephane เขาแสดงตัวอย่างนี้เช่นกัน
slm

อาตอนนี้ฉันเข้าใจแล้ว < filename commandฉันจะต้องเขียน
ข้อผิดพลาด

14

การใช้งานแบบคลาสสิกที่ไร้ประโยชน์catคือเมื่อคุณใช้เพื่อให้อินพุตกับโปรแกรมที่สามารถเปิดไฟล์ได้โดยตรง ตัวอย่างเช่น:

ไม่ดี

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

ดี

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

ยังดี ( <fileสามารถอยู่ทั้งสองข้างของคำสั่ง)

<file grep foo
 sed 's/a/b/' < file
<file awk '{print $1}' 

6
"แย่" เป็นอัตนัยที่นี่ ผมพบว่าผู้ที่จะดีขึ้นโดยรวมเพราะมันเป็นวิธีที่มากขึ้นสอดคล้องและง่ายต่อการอ่าน และการไหลของข้อมูลที่เป็นซ้ายไปขวาได้อย่างเต็มที่ตามที่มันควรจะเป็นถ้ามีท่ออื่น ๆ ที่เกี่ยวข้อง
Izkata

2
@Izkata พวกเขากำลัง "เลวร้าย" catในแง่ที่ว่าพวกเขาจะใช้ของไร้ประโยชน์
terdon

"ลง! ลงจากโต๊ะ! คุณเป็นแมวที่ไม่ดี! ” ;-) แต่อย่างจริงจัง…
G-Man พูดว่า 'Reinstate Monica'

1
ดีที่น่าสังเกต (หรืออย่างน้อยมีประโยชน์) ใช้catรวมถึง (1) cat file(กับการส่งออกไปยังหน้าจอ / ขั้วแม้ว่าถ้าไฟล์มีความยาวมากกว่าหน้าจอสูงคุณอาจชอบที่จะใช้moreหรือlessหรือสิ่งที่ต้องการ) (2) cat file1 file2 file3 > all_data( ว่าสิ่งที่catมีความหมายสำหรับ) (3) cat f1 f2 f3 | tr …(หรือท่อลงในโปรแกรมอื่น ๆ ที่คุณไม่ต้องการที่จะผ่านไฟล์ไปยังโดยตรงเช่นwc(เช่นหากคุณต้องการที่จะดูยอดแกรนด์เท่านั้น) หรือgrep(เช่นหากคุณมีเวอร์ชั่นเก่าที่ไม่รองรับ-hเช่น--no-filename)), … (ต่อ)
G-Man พูดว่า 'Reinstate Monica'

(ต่อ) ... (4) cat -n file | sort … -k1 | sed 's/^ *[0-9]*\t//', (5) sudo cat file600 | untrusted_program(เช่นคุณ (UID ของคุณ) ไม่สามารถอ่านไฟล์ได้และคุณไม่ต้องการรันโปรแกรมในฐานะรูทหรือแม้แต่ UID ที่มีสิทธิ์แบบกึ่ง) นอกจากนี้ ( e ) (เช่นตัวเลขระหว่าง 2 ถึง 3) program_that_generates_html | cat static_html_header - static_html_footer(ซึ่งคุณอาจต้องการเปลี่ยนเส้นทางไปยังไฟล์หรือไพพ์)
G-Man กล่าวว่า 'Reinstate Monica'

13

UUOC อยู่ใน:

cat somefile | some-cmd

หรือ

cat < somefile | some-cmd

นั่นsome-cmdคือการอ่านเนื้อหาของsomefileจากท่อที่ถูกเลี้ยงโดยที่ตัวเองอ่านได้จากcatsomefile

some-cmdสามารถอ่านได้โดยตรงจากsomefile(หลังจากเชลล์เปิดเพื่อใช้งานบน stdin) ไม่จำเป็นต้องมีcat:

some-cmd < somefile

หรือ

< somefile some-cmd

(การเปลี่ยนเส้นทางสามารถปรากฏที่ใดก็ได้ในบรรทัดคำสั่งแบบง่าย)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.