ช่องว่างถัดจากท่อ


17

ฉันเคยเห็นhistory | grep blahและhistory |grep blah; และใช้history|grep blahงานได้แม้ว่าจะไม่มีใครดูเหมือนจะใช้มัน

มีความสำคัญในช่องว่างหรือไม่ (เช่นการไพพ์ไปยัง / จากคำสั่งที่แตกต่างกันต้องใช้การเว้นวรรคที่แตกต่างกัน) หรือมันเป็นกฎเกณฑ์เสมอ?


13
การอ่านส่วนใหญ่
jasonwryan

1
|;ไพพ์หรืออัฒภาคถูกใช้โดยเชลล์ส่วนใหญ่ (bash, ksh, tcsh) เป็นตัวคั่นของคำสั่ง เมื่อไม่ได้อยู่ในพื้นที่สีขาวที่อ้างถึงก่อนและหลังจะไม่เคารพ
Archemar

คำตอบ:


24

bashกำหนดหลายmetacharacters จากman bash:

metacharacter
ตัวละครที่แยกคำออกมา หนึ่งในสิ่งต่อไปนี้:
| &; () <> แท็บช่องว่าง

เนื่องจากอักขระเมตาเซอร์แยกคำจึงไม่สำคัญว่าจะถูกล้อมรอบด้วยช่องว่างหรือไม่ สัญลักษณ์ไปป์|เป็นตัวอักษรและด้วยเหตุนี้ตามที่คุณสังเกตเห็นมันไม่จำเป็นต้องมีช่องว่างรอบ ๆ

โปรดทราบว่า[, ], {, }และ=มีไม่ metacharacters ตรงกันข้ามความหมายของพวกเขาขึ้นอยู่กับว่าพวกเขาถูกล้อมรอบด้วยช่องว่างหรือไม่

ตัวอย่างของช่องว่างเมื่อใดและไม่จำเป็น

ดังที่คุณสังเกตเห็นว่าไม่สำคัญว่าจะ|ถูกล้อมรอบด้วยช่องว่างหรือไม่ ให้เราพิจารณาตัวอย่างบางอย่างที่ทำให้ผู้ใช้ bash สับสนโดยทั่วไป พิจารณา:

$ (date)
Sun Mar  1 12:47:07 PST 2015

parens ด้านบนบังคับให้dateคำสั่งรันเป็น subshell เพราะ(และ)เป็นเมตาแท็กจึงไม่ต้องมีช่องว่าง ตรงกันข้าม:

$ {date}
bash: {date}: command not found

ตั้งแต่{และ}มีไม่ metacharacters ที่เปลือกถือว่า{date}เป็นหนึ่งคำ แทนที่จะมองหาคำสั่งจะมองหาคำสั่งที่มีชื่อว่าdate {date}เนื่องจากไม่พบหนึ่งข้อผิดพลาดผลลัพธ์

อีกปัญหาที่พบบ่อยคือtestคำสั่ง การทำงานต่อไปนี้สำเร็จ:

$ [ abc ] && echo Yes
Yes

ลบช่องว่างและเกิดข้อผิดพลาด:

$ [abc] && echo Yes
bash: [abc]: command not found

เพราะ[และ]มีไม่ metacharacters ที่เปลือกถือว่า[.bashrc]เป็นคำเดียวและผลเช่นเดียวกับในdateตัวอย่างเช่นเป็นข้อผิดพลาด

งบการมอบหมายยังมีความอ่อนไหวต่อช่องว่าง การมอบหมายต่อไปนี้สำเร็จ:

$ v=date
$ echo $v
date

เพิ่มช่องว่างและการมอบหมายล้มเหลว:

$ v= date
Sun Mar  1 12:55:05 PST 2015

ในข้างต้นเชลล์ตั้งค่าvให้ว่างเปล่าชั่วคราวแล้วดำเนินการdateคำสั่ง

เพิ่มช่องว่างก่อน=ยังทำให้เกิดความล้มเหลว แต่ด้วยเหตุผลอื่น:

$ v =date
bash: v: command not found

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


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

3

ไพพ์อนุญาตให้คุณใช้เอาต์พุตของโปรแกรมเป็นอินพุตของอีกอันหนึ่ง ...

เท่าที่มีช่องว่างมันเป็นเรื่องของการอ่าน / การตั้งค่าบุคลากรเช่น @jasonwryan กล่าวถึง

หนึ่งสเปซบาร์ก่อนและหลัง "|" เป็นบรรทัดฐาน ....

คุณยังสามารถใช้มันกับคอลัมน์ -t, เพื่อไม่เพียงทำให้ซับของคุณเรียบร้อย แต่ยังให้ผลลัพธ์ของคุณ

lnydex99uhc:depot_r user$ lsof | grep my | column -t
Microsoft  290  user  txt  REG  1,4  9515016  170972    /Library/Fonts/PCmyoungjo.ttf
bash       359  user  cwd  DIR  1,4  714      12246074  /Users/zatef/hw2/base/active/myapp

2

มีกรณีหนึ่งที่สามารถมีประโยชน์ในการไม่ใช้ช่องว่างได้ หากคุณไม่ได้ใช้เลย์เอาต์ US-American คุณอาจถูกบังคับให้ใช้ชุดค่าผสมบางอย่างเช่น AltShiftLเพื่อป้อนไพพ์ ในขณะที่นี่ไม่ใช่ปัญหาต่อ se ผลที่ตามมาอย่างหนึ่งคือบางครั้งคุณยังป้อนอักขระที่ไม่พิมพ์ก่อนหรือหลังอักขระนั้น ยกตัวอย่างเช่นในฝรั่งเศส Macbook Pro แป้นพิมพ์ผมต้องใช้การป้อนข้อมูลAltShiftL |เมื่อคุณพิมพ์อย่างรวดเร็วคุณสามารถพิมพ์สิ่งนี้: AltShift( L, Space)

$ sudo dmesg | tail
zsh: command not found:  tail

echo "sudo dmesg | tail" | od -a
0000000    s   u   d   o  sp   d   m   e   s   g  sp   |         t   a
0000020    i   l  nl

หากคุณไม่ทราบว่าAltShiftSpaceอินพุตเป็นช่องว่างอื่น (ช่องว่างไม่ใช่ ( U + 00A0 )) ข้อผิดพลาดต่อไปนี้อาจยากต่อการเข้าใจ:zsh: command not found:  tail


1

ความสำคัญของช่องว่างในกรณีนี้คือความสวยงาม
หรือกล่าวอีกนัยหนึ่งก็เป็นประโยชน์ในการทำให้คำสั่งอ่านได้ง่ายขึ้นสำหรับมนุษย์

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