ทำไม `sort <“ $ f1”` ชอบมากกว่า `sort - '$ f1' 'และทำไมถึงชอบมากกว่า` sort“ $ f1”'?


29

จาก/unix//a/458074/674

จำไว้ว่าให้ใช้-- เมื่อส่งอาร์กิวเมนต์ไปยังคำสั่งโดยพลการ (หรือใช้การเปลี่ยนเส้นทางหากทำได้) ดังนั้นsort -- "$f1"หรือดีกว่าแทนsort < "$f1"sort "$f1"

เหตุใดจึงต้องการใช้--และเปลี่ยนเส้นทาง

ทำไมถึงsort < "$f1"ชอบมากกว่าsort -- "$f1"?

ทำไมถึง sort -- "$f1"ชอบมากกว่าsort "$f1"?

ขอบคุณ


คำตอบ:


55
sort "$f1"

ล้มเหลวสำหรับค่าของการ$f1เริ่มต้นด้วย-หรือที่นี่สำหรับกรณีของsortบางอย่างที่เริ่มต้นด้วย+(สามารถมีผลกระทบรุนแรงสำหรับไฟล์ที่เรียก-o/etc/passwdเช่น)

sort -- "$f1"

(โดยที่-- สัญญาณสิ้นสุดของตัวเลือก) แก้ไขปัญหาเหล่านั้นส่วนใหญ่ แต่ยังคงล้มเหลวสำหรับไฟล์ที่เรียกว่า-(ซึ่งsortตีความว่าเป็นความหมายของ stdin แทน)

sort < "$f1"

ไม่มีปัญหาเหล่านั้น

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

และใน

sort < "$f1" > out

(ตรงกันข้ามsort -- "$f1" > out) หาก"$f1"ไม่สามารถเปิดoutได้จะไม่มีการสร้าง / ตัดทอนและsortไม่เรียกใช้

ในการล้างความสับสนที่อาจเกิดขึ้น (ดังต่อไปนี้ความคิดเห็นด้านล่าง) ซึ่งไม่ได้ป้องกันคำสั่งจากmmap()ไฟล์หรือlseek()อยู่ข้างใน (ไม่ใช่sortอย่างใดอย่างหนึ่ง) หากไฟล์นั้นสามารถค้นหาได้ ข้อแตกต่างเพียงอย่างเดียวคือไฟล์ถูกเปิดก่อนหน้านี้และบน file descriptor 0 โดยเชลล์ซึ่งตรงข้ามกับคำสั่งในภายหลังโดยใช้คำอธิบายบนไฟล์ descriptor อื่น คำสั่งยังคงสามารถค้นหา / mmap ที่ fd 0 ตามที่ต้องการ เพื่อไม่ให้สับสนกับการcat file | cmdที่cmdstdin ในครั้งนี้เป็นท่อที่ไม่สามารถ mmaped / ค้นหาได้


4
เพียงจำไว้ว่าการใช้กองกำลังเปลี่ยนเส้นทางsortเพื่ออ่านข้อมูลตามลำดับและคุณไม่สามารถmmapไฟล์ได้ ในขณะที่sortอาจจะไม่ได้มีปัญหากับมันมากพิจารณาประสิทธิภาพการทำงานของและless <file less fileในกรณีแรกlessต้องเก็บเนื้อหาทั้งหมดของไฟล์ไว้ในหน่วยความจำในกรณีที่สองอนุญาตให้อ่านเฉพาะส่วนที่ต้องการ ตอนนี้คิดว่าfileเป็นไฟล์บันทึก 100GB ...
styrofoam fly

7
@styrofoamfly: ถูกต้องที่less <fileเก็บไฟล์ทั้งหมดไว้ในหน่วยความจำ แต่มันไม่ได้ถูกบังคับเพราะนี่เป็นข้อบกพร่องน้อยกว่า เพียงcat file | lessถูกบังคับให้ ตรวจสอบless /dev/fd/0 <fซึ่งจะไม่เก็บไฟล์ในหน่วยความจำแม้ว่าจะได้รับมันใน stdin มันเป็นความเข้าใจผิดทั่วไปที่ stdin ใน Unix ไม่สามารถมองเห็นได้ ความจริงมันสามารถหาได้ขึ้นอยู่กับประเภทของไฟล์
pts

@styrofoamfly คุณหมายถึงการread()อ่านข้อมูลตามลำดับจากไฟล์ขณะที่mmap()อ่านไฟล์ทั้งหมดในหน่วยความจำพร้อมกันหรือไม่?
ทิม

1
@ JohnBollinger ไม่ว่าวันที่กลับไปอย่างน้อยที่สุดเท่าที่ได้รับกลับมาจาก SysIII ในปี 1980 ก่อนที่โครงการ GNU เริ่มต้นขึ้นและจะต้องได้รับการสนับสนุนสำหรับสาธารณูปโภคมาตรฐานส่วนใหญ่รวมถึงsortPOSIX แต่มันเป็นความจริงที่ไม่รองรับเสมอ
Stéphane Chazelas

2
คำขอโทษของฉัน @ StéphaneChazelasคุณพูดถูกเกี่ยวกับที่มาของอนุสัญญาและฉันจะกำหนดเงื่อนไข POSIX สำหรับgetopt()ฟังก์ชัน C ให้ตระหนักถึงความสำคัญของข้อโต้แย้ง--นี้ แต่ประเด็นหลักคือสิ่งที่คุณยอมรับ: การจัดการอาร์กิวเมนต์เป็นโดเมนของแต่ละโปรแกรมและไม่ใช่ทั้งหมดที่ปฏิบัติ--เป็นพิเศษ
John Bollinger

17

ปัญหาคือชื่อไฟล์ที่ขึ้นต้นด้วยเส้นประ sort "$f1"ไม่ทำงานหากค่าf1เริ่มต้นด้วย-เพราะคำสั่งจะตีความค่าเป็นตัวเลือก นี้มักจะส่งผลให้เกิดข้อผิดพลาด แต่มันก็อาจจะทำให้เกิดความปลอดภัยหลุม ด้วยsort -- "$f1", ประคู่อาร์กิวเมนต์--หมายถึง“ตัวเลือกไม่เกินกว่าจุดนี้”ดังนั้นค่าของf1จะไม่ถูกตีความว่าเป็นตัวเลือก แต่ยังมีกรณีขอบหนึ่ง: ถ้าค่าของf1เป็นเส้นประและไม่มีอะไรอื่นแล้วมันไม่ใช่ตัวเลือกมันเป็นอาร์กิวเมนต์-ซึ่งหมายถึง“ อินพุตมาตรฐาน” (เนื่องจากอาร์กิวเมนต์เป็นไฟล์อินพุตสำหรับไฟล์เอาต์พุต มันจะหมายถึง "เอาท์พุทมาตรฐาน")

การใช้การเปลี่ยนเส้นทางหลีกเลี่ยงข้อผิดพลาดเหล่านี้ทั้งหมด

sortนี้นำไปใช้คำสั่งส่วนใหญ่ไม่ได้เป็นเพียง


คุณกำลังบอกว่าsort < "$f1"จะใช้งานได้ถ้าค่าเท่ากัน-? มันไม่ได้อยู่ในเปลือกใด ๆ ที่ฉันได้ลอง
grawity

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