เสร็จสิ้นแท็บ Bash: '-bash: EOF ที่ไม่คาดคิดขณะค้นหาการจับคู่ `)' -bash: ข้อผิดพลาดทางไวยากรณ์: สิ้นสุดไฟล์ที่ไม่คาดคิด


18

ฉันพยายามเข้าสู่irbเซสชันที่มีตัวแปรสภาพแวดล้อมเฉพาะจากไฟล์ด้วยคำสั่งนี้:

$ env $(cat env.sh) irb

แต่เมื่อฉันลองกดTabหลังจากพิมพ์env.เสร็จฉันได้รับข้อผิดพลาดต่อไปนี้:

$ env $(cat env.-bash: unexpected EOF while looking for matching `)'
-bash: syntax error: unexpected end of file

อีกสิ่งที่น่าสนใจคือถ้าฉันเข้าสู่ระบบในฐานะ root ข้อผิดพลาดนี้ไม่เกิด

นี่คือผลลัพธ์ของfind ~ -uid 0:

$ find ~ -uid 0
/home/(redacted)/.rpmdb
/home/(redacted)/.rpmdb/Group
/home/(redacted)/.rpmdb/Conflictname
/home/(redacted)/.rpmdb/Installtid
/home/(redacted)/.rpmdb/Sha1header
/home/(redacted)/.rpmdb/Providename
/home/(redacted)/.rpmdb/__db.002
/home/(redacted)/.rpmdb/Requirename
/home/(redacted)/.rpmdb/Sigmd5
/home/(redacted)/.rpmdb/__db.001
/home/(redacted)/.rpmdb/Obsoletename
/home/(redacted)/.rpmdb/.dbenv.lock
/home/(redacted)/.rpmdb/Name
/home/(redacted)/.rpmdb/Basenames
/home/(redacted)/.rpmdb/Triggername
/home/(redacted)/.rpmdb/Packages
/home/(redacted)/.rpmdb/Dirnames
/home/(redacted)/.rpmdb/__db.003

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


คุณเข้าสู่ระบบในฐานะ root ได้อย่างไร?
muru

@muru sudo suฉันเข้าสู่ระบบโดยใช้ราก
eldosoa

find ~ -uid 0โปรดแก้ไขคำถามของคุณเพื่อเพิ่มการส่งออกของ
muru

@muru เรียบร้อยแล้ว เพิ่มผลลัพธ์ในคำถามของฉัน
eldosoa

ขออภัยเกี่ยวกับสิ่งนั้น แต่ไม่ใช่ในฐานะรูท! ฉันหมายความว่าเป็นผู้ใช้ปกติของคุณเพื่อให้เป็น~ /home/something
muru

คำตอบ:


33

คุณพบข้อผิดพลาดในไลบรารีBash Completion ที่ใช้โดย Ubuntu

สิ่งนี้หมายความว่า?

Ubuntu ใช้ไลบรารี bash completion เพื่อทำให้ bash เสร็จอย่างชาญฉลาด /usr/share/bash-completion/bash_completionห้องสมุดนี้อาศัยอยู่ใน

โดยพื้นฐานแล้วไลบรารี่นี้จะประกาศฟังก์ชั่นที่ชาญฉลาดบางอย่างที่รู้เกี่ยวกับคำสั่งทั่วไปและวิธีการทำให้สมบูรณ์ เมื่อใดก็ตามที่คุณกดTabฟังก์ชั่นภายในไลบรารีนี้จะถูกเรียกและพยายามทำให้บรรทัดคำสั่งปัจจุบันของคุณสมบูรณ์ ดังนั้นสำหรับตัวอย่างเช่นถ้าคุณพิมพ์มันจะเสร็จสิ้นว่าapt-get iTab apt-get installหากคุณไม่ได้แหล่งไลบรารีนั้นคุณจะมีการทำ bash แบบมาตรฐานดั้งเดิมเท่านั้นดังนั้นตัวอย่างเช่นถ้าคุณพิมพ์apt-get iTabโดยไม่ต้องมีที่มา 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สับก็ควรที่จะแก้ไขปัญหาอื่นแต่ผมคิดว่าจะนำข้อผิดพลาดอื่น ๆ ในกระบวนการ

ฉันจะแก้ไขได้อย่างไร

ปรากฎว่าข้อผิดพลาดนี้ได้รับการรายงานแล้ว หลังจากอ่านรายงานข้อผิดพลาดฉันเห็นสามวิธีในการแก้ไข:

  1. แก้ไขได้:หนึ่งในความคิดเห็นในรายงานข้อผิดพลาดนั้นมีบางคนแนะนำให้แทนที่บรรทัด

    [[ ${!2} == \$* ]] && eval $2=${!2}

    ภายในฟังก์ชั่น_quote_readline_by_refในไฟล์/usr/share/bash-completion/bash_completionโดยบรรทัด

    [[ ${!2} == \$\'* ]] && eval $2=${!2}

    ฉันไม่แนะนำให้ทำเช่นนี้ คนที่เขียนความคิดเห็นที่ไม่ปรากฏที่จะเป็นนักพัฒนาของทุบตีเสร็จ โปรแกรมแก้ไขด่วนนี้จะทำให้ตัวถูกดำเนินการด้านซ้ายของคำสั่งประเมินเป็นเท็จและป้องกันไม่ให้evalเกิดขึ้น อย่างไรก็ตามหากไม่มีความรู้ที่ดีเกี่ยวกับสิ่งที่ฟังก์ชั่นนั้นควรจะทำและในสิ่งที่เรียกว่าบริบทมันก็ไม่มีความชัดเจนว่ามันจะไม่ทำลายฟังก์ชันการทำงานอื่น ๆ

  2. รับรุ่นใหม่ล่าสุด:ดังที่ได้กล่าวไว้ในรายงานข้อผิดพลาดข้อผิดพลาดนี้ไม่ปรากฏในส่วนหัว 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

  1. เอนหลังแล้วรอ:ไม่ช้าก็เร็วเวอร์ชั่นใหม่จะออกวางจำหน่าย (ซึ่งอาจแก้ไขการทุบตีเสร็จสิ้นภายในการแทนที่คำสั่ง) และคุณจะได้รับเวอร์ชัน Ubuntu ในอนาคต นั่นคือสิ่งที่ฉันจะทำ ;-)

1
@ con-f-use ใช่นั่นแหล่ะ! repo Git ยังเชื่อมโยงจากเว็บไซต์หลักของ bash-completion ซึ่งเป็นสาเหตุที่ฉันไม่ได้เชื่อมโยงกับคำตอบของฉัน
Malte Skoruppa

2
@ con-f-use ความคิดเห็นของคุณทำให้ฉันต้องทำการวิจัยเพิ่มเติมเกี่ยวกับข้อผิดพลาดนี้ ปรากฎว่ามันไม่ใช่และไม่เคยเป็นบั๊กต้นน้ำ แต่จริงๆแล้วมันเป็นข้อผิดพลาดที่แนะนำโดยโปรแกรมปรับปรุงของ Ubuntu ที่ใช้กับเวอร์ชันอัปสตรีม ดูเหมือนว่าไม่มีใครหรี่ลงบั๊กนี้กับแพทช์นั้นจนถึงตอนนี้ ดังนั้นผมจึงได้รายงานการค้นพบของฉันในรายงานข้อผิดพลาดที่สอดคล้องกัน Ubuntu: bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1312243
Malte Skoruppa

2
การทำงานที่ดี Malte
Barry Kelly

1
ขอบคุณสำหรับคำอธิบาย จากการเขียนนี้เวอร์ชันของ git head ได้ลบข้อผิดพลาดและการเติมข้อความอัตโนมัติตามที่ต้องการ แก้ไข: ที่จริงไม่เป็นไรมันไม่ได้
user3391564

1
@MaxvonHippel ฉันพูดว่าเมื่อคุณใช้sudo suเพื่อเป็นรูทมันไม่ได้มาจากไลบรารี แต่จะได้รับแหล่งที่มาเมื่อคุณใช้sudo -iแทนซึ่งเป็นวิธีที่ตั้งใจจะได้รับเซสชันรูทแบบโต้ตอบ สำหรับคำถามของคุณ: เนื่องจาก bash shell ใด ๆ อ่าน~/.bashrcซึ่งในที่สุดก็มาที่ไลบรารีและไม่มีวิธี "un-source" ไฟล์ฉันไม่เห็นวิธีที่ตรงไปตรงมาอย่างสมบูรณ์ นี่คือสับที่เป็นไปได้: ให้การจัดหาเงื่อนไขห้องสมุดตัวแปรสภาพแวดล้อมบางพูดNOCOMPL, ไม่ได้ถูกกำหนดไว้ในของคุณ~/.bashrc...
Malte Skoruppa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.