ผมทำงานผ่านการกวดวิชาและเห็นการใช้งานของทั้งสองและcat myfile.txt cat < myfile.txtมีความแตกต่างระหว่างสองคำสั่งเหล่านี้หรือไม่? ดูเหมือนว่าทั้งคู่จะพิมพ์เนื้อหาของไฟล์ลงในเชลล์
ผมทำงานผ่านการกวดวิชาและเห็นการใช้งานของทั้งสองและcat myfile.txt cat < myfile.txtมีความแตกต่างระหว่างสองคำสั่งเหล่านี้หรือไม่? ดูเหมือนว่าทั้งคู่จะพิมพ์เนื้อหาของไฟล์ลงในเชลล์
คำตอบ:
ในกรณีแรกให้catเปิดไฟล์และในกรณีที่สองเชลล์จะเปิดไฟล์โดยส่งผ่านเป็นcatอินพุตมาตรฐาน
ในทางเทคนิคแล้วพวกเขาอาจมีผลกระทบที่แตกต่างกัน ตัวอย่างเช่นมันเป็นไปได้ที่จะมีการใช้งานเชลล์ที่มีสิทธิพิเศษ (หรือน้อยกว่า) มากกว่าcatโปรแกรม สำหรับสถานการณ์สมมติที่หนึ่งอาจล้มเหลวในการเปิดไฟล์ในขณะที่อื่น ๆ ได้
นั่นไม่ใช่สถานการณ์ปกติ แต่บอกว่าชี้ให้เห็นว่าเชลล์และcatไม่ใช่โปรแกรมเดียวกัน
sudo cat myfile.txtใช่และตัวอย่างเช่นคุณสามารถทำได้ แต่sudo cat < myfile.txtจะไม่ทำงานหากคุณไม่มีสิทธิ์ในการอ่านไฟล์
ksh93มีcatbuiltin (ไม่ได้เปิดใช้งานโดยค่าเริ่มต้นเว้นแต่คุณจะมี/opt/ast/binในช่วงต้นของคุณ$PATHแม้ว่า)
wcจะพิมพ์ชื่อไฟล์ก่อนการนับเมื่อได้รับการโต้แย้ง
ไม่มีความแตกต่างที่เห็นได้ชัดเจนในกรณีทดสอบของคุณ สิ่งที่ชัดเจนที่สุดคือข้อความแสดงข้อผิดพลาดที่คุณได้รับหากไม่มีชื่อไฟล์myfile.txtในไดเรกทอรีปัจจุบันหรือหากคุณไม่ได้รับอนุญาตให้อ่าน
ในกรณีก่อนหน้าcatจะบ่นและในกรณีหลังเชลล์ของคุณจะแสดงให้เห็นอย่างชัดเจนว่ากระบวนการใดที่พยายามเปิดไฟล์catในอดีตและเชลล์ในกรณีหลัง
$ cat myfile.txt
cat: myfile.txt: No such file or directory
$ cat < myfile.txt
ksh93: myfile.txt: cannot open [No such file or directory]
ในกรณีทั่วไปมากขึ้นความแตกต่างที่สำคัญคือการใช้การเปลี่ยนเส้นทางไม่สามารถใช้พิมพ์เนื้อหามากกว่าหนึ่งไฟล์ซึ่งอยู่หลังวัตถุประสงค์ดั้งเดิมทั้งหมดของคำสั่งcat(เช่นcat enate) โปรดทราบว่าเชลล์จะพยายามเปิดไฟล์ทั้งหมดที่ส่งผ่านเป็นอินพุตที่เปลี่ยนเส้นทาง แต่จะส่งผ่านไฟล์ล่าสุดไปcatจนกว่าคุณจะใช้zshและmultios"zshism"
$ echo one > one
$ echo two > two
$ cat one two # cat opens one, shows one, opens two, shows two
one
two
$ cat < one < two # sh opens one then opens two, cat shows stdin (two)
two
$ rm one two
$ echo one > one
$ cat one two # cat opens and shows one, fails to open two
one
cat: two: No such file or directory
$ cat < one < two # the shell opens one then opens two, fails and
# displays an error message, cat gets nothing on stdin
# so shows nothing
ksh93: two: cannot open [No such file or directory]
บนระบบมาตรฐานเชลล์และcatไม่มีความแตกต่างในสิทธิ์การเข้าถึงไฟล์ดังนั้นทั้งสองจะประสบความสำเร็จในการล้มเหลวอย่างเท่าเทียมกัน การใช้sudoเพื่อยกระดับcatสิทธิ์ของผู้ใช้จะสร้างความแตกต่างอย่างมากในการทำงานตามที่ Thomas Dickey ตอบและแสดงความคิดเห็นที่แนบมาแล้ว
kshจากความตั้งใจของคุณเองและถ้าเป็นเช่นนั้น ... ทำไม ?
bash, ksh93อยู่ไกลออกไปเปลือกที่ดีกว่า มันเป็นเปลือกเกือบ
cat myfile.txtอ่านไฟล์myfile.txtจากนั้นพิมพ์ไฟล์ไปยังเอาต์พุตมาตรฐาน
cat < myfile.txtที่นี่catไม่ได้รับไฟล์ใด ๆ ที่จะเปิดดังนั้นคำสั่ง Unix ที่เหมือนกันจะอ่านข้อมูลจากอินพุตมาตรฐานซึ่งส่งตรงจากfile.txtเชลล์และพิมพ์ไปยังเอาต์พุตมาตรฐาน
@Thomas Dickeyคำตอบนั้นยอดเยี่ยม
ฉันแค่ต้องการเพิ่มข้อเท็จจริงที่ชัดเจนเกี่ยวกับกรณีที่อ่านไฟล์หลายไฟล์ (เกี่ยวข้องกับคำถามของคุณอย่างหลวม ๆ แต่ก็ยัง):
cat <file1 <file2 <file3จะอ่านเฉพาะไฟล์ 3 อย่างน้อยก็เป็น bash (อันที่จริงมันขึ้นอยู่กับเชลล์ แต่เชลล์ส่วนใหญ่จะทำซ้ำทุกไฟล์ที่ระบุเป็น stdin ซึ่งทำให้ไฟล์ล่าสุดมีผล)cat file1 file2 file3จะอ่านไฟล์ทั้งหมดที่ระบุตามลำดับ (อันที่จริงcatเป็นรูปแบบย่อของคำต่อกัน )cat file1 file2 file3 <file4 <file5 <file6 จะอ่านเฉพาะ file1, file2, file3 (เนื่องจาก cat ละเว้น stdin เมื่ออาร์กิวเมนต์ของชื่อไฟล์ถูกส่งผ่าน)
cat file1 file2 - file3 <file4 <file5 <file6 จะอ่าน file1, file2, file6, file3 (เนื่องจากยัติภังค์บังคับให้แมวไม่ต้องสนใจ stdin)และเกี่ยวกับข้อผิดพลาด ในกรณีที่ไม่สามารถเปิดไฟล์บางไฟล์ที่ระบุว่าเป็นอาร์กิวเมนต์ (โดยไม่มี<), cat จะข้ามไฟล์ที่ล้มเหลว (โดยการส่งข้อความที่เกี่ยวข้องไปยัง stderr) แต่ยังคงอ่านไฟล์อื่น ๆ ในกรณีที่ไม่สามารถเปิดไฟล์อย่างน้อยหนึ่งไฟล์ที่ระบุว่าเป็นการเปลี่ยนเส้นทาง (ด้วย<), เชลล์จะไม่เริ่ม cat (สิ่งนี้เกิดขึ้นแม้สำหรับการเปลี่ยนเส้นทางที่ไม่ได้ใช้โดย cat จริง ๆ ) ในทั้งสองกรณีรหัสทางออกที่ผิดพลาดจะถูกส่งคืน
catจะยังคงเปิดfile1และfile2เหมือนกันกับfile4และfile5ในตัวอย่างที่สามของคุณ มันจะแสดงเฉพาะการตอบfile3สนอง file6เนื้อหาถ้าคำแนะนำการเปิดก่อนหน้านี้ประสบความสำเร็จ
เราสามารถใช้คำสั่งอื่นเพื่อสังเกตเห็นความแตกต่างระหว่าง:
wc –w food2.txt.
เอาต์พุตที่เป็นไปได้:
6 food2.txt.
คำสั่งจะบอกชื่อไฟล์เนื่องจากมันรู้จัก (ผ่านเป็นอาร์กิวเมนต์)
wc –w < food2.txt.
เอาต์พุตที่เป็นไปได้:
6.
อินพุตมาตรฐานถูกเปลี่ยนเส้นทางไปยังไฟล์ food2.txt โดยไม่ต้องมีคำสั่งรู้