ทำไมเครื่องหมายตัวหนอน (~) ไม่ขยายเมื่อใช้กับอาร์กิวเมนต์ CLI ที่ขึ้นต้นด้วยขีดกลาง


9

ฉันเสียเวลาสองสามชั่วโมงในการพยายามเรียกใช้เซิร์ฟเวอร์ VNC (x0vncserver) และลูกค้าปฏิเสธที่จะเชื่อมต่อกับข้อความแปลก ๆ ที่

No password configured for VNC Auth

เซิร์ฟเวอร์ยังพิมพ์ข้อผิดพลาดนี้

 SVncAuth:    opening password file '~/.vnc/passwd' failed

ตกลงฉันเสียเวลามากจนกว่าฉันจะรู้ว่าตัวหนอนไม่ได้ถูกขยายโดยเชลล์หรือโดย x0vncserver จากนั้นฉันก็ทำการทดสอบเหล่านี้

$ echo --PasswordFile=~/.vnc/passwd
--PasswordFile=~/.vnc/passwd

แต่

$ echo PasswordFile=~/.vnc/passwd
PasswordFile=/home/tichomir/.vnc/passwd

ทำไมถึงเป็นอย่างนั้น? ทำไมเชลล์ปฏิเสธที่จะขยายตัวหนอนถ้าอาร์กิวเมนต์เริ่มต้นด้วยเส้นประ? ฉันคิดว่าตัวหนอนจะขยายตราบใดที่มันไม่ได้ยกมา แต่เห็นได้ชัดว่ามีกฎอื่นที่เข้ามาเล่น?



คำตอบ:


13

นี่เป็นลักษณะเฉพาะของbashเชลล์ที่อธิบายไว้ในคู่มือ:

Bash ยังทำการขยายตัวหนอนบนคำที่ตรงตามเงื่อนไขของการกำหนดตัวแปร (ดังที่อธิบายไว้ข้างต้นภายใต้พารามิเตอร์) เมื่อมันปรากฏเป็นอาร์กิวเมนต์ของคำสั่งง่าย ๆ Bash ไม่ได้ทำเช่นนี้ยกเว้นคำสั่งการประกาศที่แสดงข้างต้นเมื่ออยู่ในโหมด posix

ซึ่งหมายความว่าbash จะขยายตัวหนอนในPasswordFile=~/.vnc/passwdสตริงของคุณเนื่องจากมันเป็นข้อโต้แย้งechoที่ดูเหมือนการกำหนดตัวแปร

สตริง--PasswordFile=~/.vnc/passwdดูไม่เหมือนการกำหนดตัวแปรเนื่องจากสตริง--PasswordFileไม่ใช่ชื่อตัวแปรที่ถูกต้อง

โปรดทราบว่าbashไม่ทำเช่นนี้เมื่อทำงานในโหมด POSIX และหอยอื่น ๆ เช่นzsh, kshหรือyashไม่ทำเช่นนี้โดยค่าเริ่มต้น ( zshมีmagicequalsubstตัวเลือกสำหรับการขยายตัวหนอนที่จะดำเนินการหลังจากเครื่องหมายเท่ากับ unquoted ( =) แม้ว่า)

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

echo --PasswordFile="$HOME/.vnc/passwd"

"การประกาศคำสั่งดังกล่าวข้างต้น" หมายถึงในคู่มือจะถูกสร้างขึ้นในคำสั่งalias, declare, typeset, export, และreadonlylocal


1
+1 | ฉันจะไม่คิดอย่างนั้น
LinuxSecurityFreak

แม้ว่าหมายเหตุ: เอาท์พุทbash --posix -c '"export" a=~; printf "%s\n" "$a"' ~
Stéphane Chazelas

2
โปรดทราบว่า~การขยายเข้าalias a=~จะเป็นข้อผิดพลาด POSIX (และไม่มีประโยชน์) แต่นั่นเป็นวิธีที่ ksh88 ทำ (เปลี่ยนเป็น ksh93) และอาจเป็นเหตุผลว่าทำไมทุบตี zsh และ pdksh ก็ทำได้เช่นกัน ทำไมyashสิ่งที่เขียนกับข้อมูลจำเพาะ POSIX ไม่ทำ
Stéphane Chazelas

นี่เป็นคำตอบที่ถูกต้อง แต่วิธีการที่ถูกต้องน่าจะแค่ให้อาร์กิวเมนต์ตัวเลือกเป็นอาร์กิวเมนต์ที่แยกต่างหากแทนที่จะรวมกับตัวเลือกที่ใช้=เป็นอาร์กิวเมนต์หนึ่งตัว จากนั้นการขยายตัวหนอนอยู่ที่จุดเริ่มต้นของคำและคำถามที่สงสัย
JdeBP

1
@JdeBP ที่มันเกิดขึ้นในกรณีของx0vncserver, ไม่ได้ทำงานที่คุณต้องการx0vncserver --PasswordFile file --PasswordFile=file
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.