ทำไม echo“ bar” -n ต่างจาก echo -n“ bar”?


10

เปรียบเทียบ

echo -n "bar"

กับ

echo "bar" -n

อดีตทำในสิ่งที่ฉันคิดว่าควรจะทำ (พิมพ์ "บาร์" โดยไม่มีการขึ้นบรรทัดใหม่) ในขณะที่หลังไม่ นี่เป็นข้อบกพร่องหรือจากการออกแบบ? ทำไมมันถึงแตกต่างจากโปรแกรม cli หลาย ๆ ตัวที่คุณไม่สามารถย้ายตัวเลือกต่างๆได้? ยกตัวอย่างเช่นเป็นเหมือนกับtail -f /var/log/messages tail /var/log/messages -fบางครั้งผมทำหลังเมื่อฉันลืมฉันอยากอดีตเพราะภายในตัวเลือกและข้อโต้แย้งที่มีการปรับปรุงใหม่โดยปกติgetopt

ปรับปรุง:ใช่ฉันเดิมคำถามของฉันไม่ดี ฉันลบ nerf คุณจะต้องดูประวัติเพื่อให้คำตอบบางอย่างเหมาะสม


3
จากสิ่งที่ฉันเห็นความแตกต่างเป็นที่เห็นได้ชัดทันที echo -n "bar"ให้ "bar" ในขณะที่echo "bar" -nให้ "bar -n"
phunehehe

คำตอบ:


18

ดังที่คนอื่น ๆ ส่วนใหญ่ได้สังเกตว่า "-n" จะถูกตีความอย่างแท้จริงหากวางไว้ที่ใดก็ได้ แต่ทันทีหลังจากechoคำสั่ง

ในอดีตยูทิลิตี้ UNIX ทุกคนเป็นแบบนี้ - พวกเขามองหาตัวเลือกเฉพาะหลังชื่อคำสั่งเท่านั้น เป็นไปได้ว่า BSD หรือ GNU ซึ่งเป็นผู้บุกเบิกรูปแบบที่ยืดหยุ่นมากขึ้น (แม้ว่าฉันจะผิดพลาด) เนื่องจากPOSIX ยังระบุวิธีเก่า ๆ ที่ถูกต้อง (ดู Guideline 9 และman 3 getoptบนระบบ Linux) อย่างไรก็ตามแม้ว่ายูทิลิตี้ส่วนใหญ่ในสมัยนี้จะใช้รูปแบบใหม่ แต่ก็มีบางสิ่งที่ค้างไว้เช่นechoกัน

Echoเป็นระเบียบมาตรฐานที่มีอยู่อย่างน้อยสองรุ่นที่ขัดแย้งกันพื้นฐานในการเล่นตามเวลา POSIX มาเป็น ในอีกด้านหนึ่งคุณมีสไตล์ SYSV ซึ่งตีความอักขระที่หลบหลีกแบ็กสแลช อีกด้านหนึ่งคุณมีสไตล์ BSD ซึ่งถือว่า-nเป็นกรณีพิเศษและให้ผลลัพธ์ทุกอย่างอย่างแท้จริง และเนื่องจากechoสะดวกมากคุณมีเชลล์สคริปต์นับพันที่ขึ้นอยู่กับพฤติกรรมหนึ่งหรืออย่างอื่น:

echo Usage: my_awesome_script '[-a]' '[-b]' '[-c]' '[-n]'
echo -a does a thing.
echo -b does something else.
echo -c makes sure -a works right.
echo -- DON\'T USE -n -- it\'s not finished! --

เนื่องจากความหมาย "จัดการทุกสิ่งอย่างแท้จริง" จึงไม่สามารถแม้แต่จะเพิ่มตัวเลือกใหม่ให้echoโดยไม่ทำลายสิ่งใด ๆ หาก GNU ใช้รูปแบบตัวเลือกที่ยืดหยุ่นในนั้นนรกจะแตกหัก

อนึ่งสำหรับการทำงานร่วมกันที่ดีที่สุดระหว่างบอร์นการใช้งานที่เปลือกใช้printfechoมากกว่า

อัปเดตเพื่ออธิบายว่าทำไมechoโดยเฉพาะไม่ใช้ตัวเลือกที่ยืดหยุ่น


upvote เนื่องจากคุณเป็นเพียงคนเดียวที่พูดถึงว่าเป็นพฤติกรรม getopt ที่คาดหวัง
Geoffrey Bachelet

@jander ทำไมเสียงก้อง "ถือ"? ฉันคิดว่ามันเป็น gnu coreutil?
xenoterracide

@xeno: ฉันได้อัปเดตคำตอบของฉันแล้ว โดยพื้นฐานแล้ว GNU ไม่ต้องการทำลายสิ่งต่าง ๆ
Jander

1
ตัวเลือกการยอมรับหลังจากที่ครั้งแรกที่ไม่ใช่ตัวเลือกเป็นเฉพาะกับGNUสาธารณูปโภคและโปรแกรมการใช้GNU libc 's getoptสิ่งอำนวยความสะดวก POSIXLY_CORRECTผู้ใช้สามารถได้รับพฤติกรรมย้อนกลับกันได้โดยการตั้งค่าตัวแปรสภาพแวดล้อม
Gilles 'หยุดความชั่วร้าย'

1
สำหรับกรณีที่เฉพาะเจาะจงของechoนอกจากนี้ยังมีการใช้งานที่รู้จัก-eหรือ-Eเป็นตัวเลือก สำหรับการพกพาไม่ได้เริ่มต้นด้วยหรือใช้สิ่งที่ต้องการ- printf %s -e
Gilles 'หยุดความชั่วร้าย'

9

คำตอบอื่น ๆ มาถึงจุดที่คุณสามารถดู man page เพื่อดูว่า -n กำลังกลายเป็นส่วนหนึ่งของสตริงที่จะสะท้อน อย่างไรก็ตามฉันแค่ต้องการชี้ให้เห็นว่ามันง่ายต่อการตรวจสอบโดยไม่ต้อง md5sum และทำให้สิ่งที่เกิดขึ้นเป็นความลับน้อยลงเล็กน้อย

[11:07:44][dasonk@Chloe:~]: echo -n "bar"
bar[11:07:48][dasonk@Chloe:~]: echo "bar" -n
bar -n

3
+1 อย่างแน่นอน หากท่อส่งไม่ได้ทำตามที่คุณคาดหวังให้ทดสอบแต่ละส่วนแยกกัน
Mikel

6

ว้าวคำอธิบายของทุกคนนั้นยาว

มันง่ายนี้:

-n เป็นตัวเลือกหากปรากฏขึ้นต่อหน้าสตริงมิฉะนั้นจะเป็นเพียงอีกหนึ่งสตริงที่จะถูกสะท้อน

ลบ| md5sum และคุณจะเห็นผลลัพธ์ที่แตกต่าง


5

จากการตรวจสอบอย่างง่ายนี่ไม่ใช่ข้อผิดพลาดจากการออกแบบ ...

echo "bar" -n | md5sum

a3f8efa5dd10e90aee0963052e3650a1

ลองใช้คำสั่งนี้ด้วยตัวคุณเอง:

echo "bar -n" | md5sum

คุณจะสังเกตได้ว่า md5 ที่ได้คือ

a3f8efa5dd10e90aee0963052e3650a1

คุณเพิ่งผสมการใช้ -n ใน echo

ในรหัสตัวอย่างแรกของคุณ

echo -n "bar" | md5sum

-n ใช้เพื่อบอกว่าอย่าใส่บรรทัดใหม่หลังจากเสียงสะท้อนนี้

ตัวอย่างที่สองของคุณ

echo "bar" -n | md5sum

กำลังดำเนินการ -n เป็นข้อความตัวอักษร

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