คุณพบข้อผิดพลาดในไลบรารีBash Completion ที่ใช้โดย Ubuntu
สิ่งนี้หมายความว่า?
Ubuntu ใช้ไลบรารี bash completion เพื่อทำให้ bash เสร็จอย่างชาญฉลาด /usr/share/bash-completion/bash_completion
ห้องสมุดนี้อาศัยอยู่ใน
โดยพื้นฐานแล้วไลบรารี่นี้จะประกาศฟังก์ชั่นที่ชาญฉลาดบางอย่างที่รู้เกี่ยวกับคำสั่งทั่วไปและวิธีการทำให้สมบูรณ์ เมื่อใดก็ตามที่คุณกดTabฟังก์ชั่นภายในไลบรารีนี้จะถูกเรียกและพยายามทำให้บรรทัดคำสั่งปัจจุบันของคุณสมบูรณ์ ดังนั้นสำหรับตัวอย่างเช่นถ้าคุณพิมพ์มันจะเสร็จสิ้นว่าapt-get i
Tab apt-get install
หากคุณไม่ได้แหล่งไลบรารีนั้นคุณจะมีการทำ bash แบบมาตรฐานดั้งเดิมเท่านั้นดังนั้นตัวอย่างเช่นถ้าคุณพิมพ์apt-get i
Tabโดยไม่ต้องมีที่มา bash จะค้นหาไฟล์ในไดเรกทอรีปัจจุบันที่เริ่มต้นด้วยi
และพยายามที่จะทำตามคำสั่งของคุณให้สมบูรณ์ ชื่อไฟล์เหล่านี้
ทำไมมันไม่เกิดขึ้นเป็นราก
เพราะเมื่อคุณใช้sudo su
เพื่อทำให้ตัวเองroot
ห้องสมุด bash complete ไม่ได้มีที่มา นี้จะแตกต่างกันถ้าคุณใช้เพื่อให้ตัวเองsudo -i
root
ฉันพนันได้เลยว่าคุณเห็นบั๊กแล้วใช่มั้ย ดูตัวอย่าง'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - เมื่อใดที่มันมีความสำคัญต่อการใช้งานหรือเมื่อไรก็ตาม หากคุณไม่คุ้นเคยกับความแตกต่าง
ในกรณีของฉันเป็นผู้ใช้ปกติห้องสมุดที่ได้รับมาเมื่อฉันเริ่มต้นเปลือกทุบตีเพราะ~/.bashrc
แหล่งที่มาซึ่งแหล่งที่มา/etc/bash_completion
/usr/share/bash-completion/bash_completion
หากฉันใช้sudo -i
เข้าสู่ระบบเป็นroot
ห้องสมุดที่ได้รับมาเพราะ/etc/profile
แหล่งที่มาซึ่งแหล่งที่มา/etc/profile.d/bash_completion.sh
/usr/share/bash-completion/bash_completion
เหตุใดข้อผิดพลาดจึงเกิดขึ้น
ลองใช้คำสั่งนี้:
$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
ดูคุ้น ๆ เหรอ? ;-) แน่นอนว่าเป็นสิ่งที่เกิดขึ้นหลังฉากเมื่อคุณเข้ามาTabในบริบทที่คุณอธิบาย แม่นยำมากขึ้นมีข้อบกพร่องอยู่ในฟังก์ชั่นการประกาศโดย_quote_readline_by_ref
/usr/share/bash-completion/bash_completion
หากคุณจัดหาไฟล์ดังกล่าวคุณควรมีฟังก์ชันนั้นให้ใช้งาน ดังนั้นลองต่อไปนี้:
$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
รับข้อโต้แย้งเหล่านี้ฟังก์ชั่น_quote_readline_by_ref
ดำเนินการเหนือสิ่งอื่นใดที่eval
กล่าวถึงข้างต้น คุณสามารถดูถ้าคุณชอบ และเมื่อคุณพิมพ์env $(cat env.
Tabหลังฉากที่ฟังก์ชั่นได้รับการเรียกพร้อมกับข้อโต้แย้งเหล่านั้น นั่นคือสิ่งที่เกิดขึ้น
นี้eval
สับก็ควรที่จะแก้ไขปัญหาอื่นแต่ผมคิดว่าจะนำข้อผิดพลาดอื่น ๆ ในกระบวนการ
ฉันจะแก้ไขได้อย่างไร
ปรากฎว่าข้อผิดพลาดนี้ได้รับการรายงานแล้ว หลังจากอ่านรายงานข้อผิดพลาดฉันเห็นสามวิธีในการแก้ไข:
แก้ไขได้:หนึ่งในความคิดเห็นในรายงานข้อผิดพลาดนั้นมีบางคนแนะนำให้แทนที่บรรทัด
[[ ${!2} == \$* ]] && eval $2=${!2}
ภายในฟังก์ชั่น_quote_readline_by_ref
ในไฟล์/usr/share/bash-completion/bash_completion
โดยบรรทัด
[[ ${!2} == \$\'* ]] && eval $2=${!2}
ฉันไม่แนะนำให้ทำเช่นนี้ คนที่เขียนความคิดเห็นที่ไม่ปรากฏที่จะเป็นนักพัฒนาของทุบตีเสร็จ โปรแกรมแก้ไขด่วนนี้จะทำให้ตัวถูกดำเนินการด้านซ้ายของคำสั่งประเมินเป็นเท็จและป้องกันไม่ให้eval
เกิดขึ้น อย่างไรก็ตามหากไม่มีความรู้ที่ดีเกี่ยวกับสิ่งที่ฟังก์ชั่นนั้นควรจะทำและในสิ่งที่เรียกว่าบริบทมันก็ไม่มีความชัดเจนว่ามันจะไม่ทำลายฟังก์ชันการทำงานอื่น ๆ
รับรุ่นใหม่ล่าสุด:ดังที่ได้กล่าวไว้ในรายงานข้อผิดพลาดข้อผิดพลาดนี้ไม่ปรากฏในส่วนหัว git (ในบรรดาการเปลี่ยนแปลงอื่น ๆ ฟังก์ชัน_quote_readline_by_ref
ได้ง่ายขึ้น) คุณสามารถโคลนการแก้ไขปัจจุบันจาก Git:
git clone https://salsa.debian.org/debian/bash-completion.git
... จากนั้นคัดลอกbash_completion
สคริปต์เวอร์ชันล่าสุดไปที่/usr/share/bash-completion
(ไม่จำเป็นต้องสำรองข้อมูลเวอร์ชันเก่าอย่างเร่งด่วนเว้นแต่จะทำให้คุณรู้สึกปลอดภัย - หากคุณประสบปัญหาsudo apt-get install --reinstall bash-completion
ควรเปลี่ยนการเปลี่ยนแปลงใด ๆ ที่คุณทำไป) นี่คือวิธีที่ฉันใช้ แนะนำถ้าคุณรีบแก้ไขปัญหานี้ :-)
โปรดทราบว่าไม่มีวิธีแก้ปัญหาใดที่จะทำให้การทุบตีเสร็จสิ้นภายในการทดแทนคำสั่ง: ดังที่กล่าวไว้ในรายงานข้อผิดพลาดเดียวกันนี้จะถูกทำลายใน Bash 4.3
- เอนหลังแล้วรอ:ไม่ช้าก็เร็วเวอร์ชั่นใหม่จะออกวางจำหน่าย (ซึ่งอาจแก้ไขการทุบตีเสร็จสิ้นภายในการแทนที่คำสั่ง) และคุณจะได้รับเวอร์ชัน Ubuntu ในอนาคต นั่นคือสิ่งที่ฉันจะทำ ;-)