เครื่องหมายแบ็กสแลชหมายถึงคำสั่ง?


17

ซอฟต์แวร์ที่ฉันติดตั้งแทรกบรรทัดในโปรไฟล์ของฉันที่อ่าน:

[ -s "$SOME_FILE" ] && \. "$SOME_FILE"

ฉันรู้ว่า dot .มีความหมายเหมือนกันsourceดังนั้นฉันสงสัยว่านี่เป็นเพียงการจัดหาไฟล์ แต่ฉันไม่เคยเห็น\.มาก่อน มันทำอย่างอื่นได้ไหม

แก้ไขเกี่ยวกับ DV:การค้นหา "backslash dot" จะนำไปสู่คำถามเกี่ยวกับการ./เรียกไฟล์ที่ปฏิบัติการได้และman sourceนำไปสู่ ​​manpage ที่\.ไม่ปรากฏขึ้น ฉันไม่รู้จะลองทำยังไงดี

แก้ไข 2:ดูคำถามที่เกี่ยวข้อง

คำตอบ:


31

แบ็กสแลชที่อยู่นอกเครื่องหมายคำพูดหมายถึง“ ตีความตัวละครต่อไปอย่างแท้จริงระหว่างการวิเคราะห์คำ” เนื่องจาก.เป็นอักขระทั่วไปสำหรับ parser \.จึงถูกวิเคราะห์ในลักษณะเดียวกับ.และเรียกใช้ builtin .(ซึ่งsourceมีความหมายเหมือนกันในการทุบตี)

มีกรณีหนึ่งที่สามารถสร้างความแตกต่างในบริบทนี้ หากผู้ใช้ได้กำหนดนามแฝงที่เรียกว่า.ก่อนหน้านี้.profileและ.profileกำลังอ่านในเปลือกที่ขยายนามแฝง (ซึ่งทุบตีเท่านั้นโดยค่าเริ่มต้นเมื่อมันถูกเรียกโต้ตอบแบบโต้ตอบ) จากนั้น.จะเรียกนามแฝง แต่\.จะยังคงเรียกตัว builtin เพราะเปลือก อย่าพยายามใช้นามแฝงในการขยายคำที่ถูกยกมา แต่อย่างใด

ฉันสงสัยว่า.ได้เปลี่ยนไปเพราะผู้ใช้บ่นหลังจากที่พวกเขาต้องการทำนามแฝงสำหรับ\..

โปรดทราบว่าจะเรียกใช้ฟังก์ชั่นที่เรียกว่า\. .สันนิษฐานว่าผู้ใช้ที่เขียนฟังก์ชั่นมีความรู้มากกว่าผู้ใช้ที่เขียนชื่อแทนและจะรู้ว่าการกำหนดคำสั่งมาตรฐาน.profileเป็นความคิดที่ไม่ดีถ้าคุณจะใส่รหัสจากบุคคลที่สาม แต่ถ้าคุณต้องการข้ามทั้งนามแฝงและฟังก์ชั่นคุณสามารถเขียนcommand .ได้ ผู้เขียนตัวอย่างนี้ไม่ได้ทำเช่นนี้เพราะพวกเขาใส่ใจเกี่ยวกับเปลือกหอยโบราณที่ไม่มีcommandรูปร่างภายในหรือมีโอกาสมากขึ้นเพราะพวกเขาไม่ได้ตระหนักถึงมัน

โดยวิธีการกำหนดนามแฝงใด ๆใน.profileเป็นความคิดที่ไม่ดีเพราะ.profileเป็นสคริปต์การเริ่มต้นเซสชั่นไม่ได้เป็นสคริปต์การเริ่มต้นเชลล์ .bashrcนามแฝงสำหรับทุบตีเป็นของใน


9

\.เป็น "จุดที่แท้จริง" คือเพียงแค่จุด มันจะถูกนำมาเป็น.คำสั่งมาตรฐาน(คล้ายกับsourceในbash)

POSIX มาตรฐานมีสิ่งนี้จะพูดเกี่ยวกับเรื่องนี้ (เน้นของฉัน)

<backslash>ที่ไม่ได้ยกมาจะรักษามูลค่าที่แท้จริงของตัวละครต่อไปนี้<newline>มีข้อยกเว้นของการ หาก a <newline>ดังต่อไปนี้<backslash>เชลล์จะตีความสิ่งนี้ว่าเป็นความต่อเนื่องของบรรทัด และจะถูกลบออกก่อนที่จะแยกใส่ลงในราชสกุล เนื่องจาก Escape ถูกลบออกจากอินพุตทั้งหมดและไม่ถูกแทนที่ด้วย white space ใด ๆ จึงไม่สามารถใช้เป็นตัวคั่นโทเค็นได้<backslash><newline><newline>

อักขระจุดสามารถเป็นนามแฝงได้:

$ alias .='echo hello'
$ .
hello

ซึ่งหมายความว่า\.จะหลีกเลี่ยงการใช้รุ่น aliased ของ.คำสั่งเพราะ ,

หลังจากที่มีการคั่นโทเค็นแล้ว แต่ก่อนที่จะใช้กฎไวยากรณ์ในเชลล์แกรมไวยากรณ์คำที่เป็นผลลัพธ์ที่ระบุว่าเป็นชื่อคำสั่งของคำสั่งแบบง่ายจะถูกตรวจสอบเพื่อตรวจสอบว่าเป็นชื่อนามแฝงที่ไม่ถูกต้องหรือไม่


ฉันกำลังค้นหาแหล่งที่มาอย่างเป็นทางการเกี่ยวกับวิธีที่แบ็กสแลชในคำถูกตีความว่าเป็นการอ้างอิงและวิธีนี้ป้องกันการขยายนามแฝง ขอบคุณสำหรับการอ้างอิง!
Sheljohn

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