Bash Sekmesi Tamamlama: '-bash: eşleştirme aranırken beklenmeyen EOF `)' -bash: sözdizimi hatası: beklenmeyen dosya sonu


18

irbBu komut ile bir dosyadan belirli ortam değişkenleri ile bir oturuma gitmeye çalışıyorum :

$ env $(cat env.sh) irb

Ama tamamlamak için Tabyazdıktan sonra basın denediğimde env., şu hatayı alıyorum:

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

Bir başka ilginç şey de root olarak giriş yaparsam bu hatanın oluşmamasıdır.

İşte çıktı 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

Herkes bana bunun neden olduğunu açıklayabilir ve eğer öyleyse, kök kullanıcı olmadığımda bunu nasıl düzeltebilirim?


Nasıl root olarak giriş yaparsınız?
muru

@muru kullanarak root'a giriş yaptım sudo su.
eldosoa

Çıktısını eklemek için lütfen sorunuzu düzenleyin find ~ -uid 0.
muru

@muru Tamamlandı. Sorumu çıktıma ekledim.
eldosoa

Bunun için üzgünüm, ama kök olarak değil! Böylece, normal kullanıcı olarak geliyordu ~olduğunu /home/something.
muru

Yanıtlar:


33

Ubuntu tarafından kullanılan Bash Tamamlama kütüphanesinde bir hata buldunuz .

Ne anlama geliyor?

Ubuntu, bash tamamlanmasını akıllı hale getirmek için bash tamamlama kütüphanesini kullanır. Bu kütüphane yaşıyor /usr/share/bash-completion/bash_completion.

Temel olarak, bu kütüphane tipik komutlar ve bunların nasıl tamamlanacağını bilen birkaç akıllı işlev bildirir. Düğmesine her bastığınızda Tab, bu kitaplıktaki işlevler çağrılır ve geçerli komut satırınızı tamamlamaya çalışır. Örneğin, apt-get iTabyazdığınızda bunu tamamlayacaktır apt-get install. Bu kütüphaneyi kaynaklamazsanız, yalnızca standart, ilkel bash tamamlama işlemine apt-get iTabsahip olursunuz - örneğin , kaynak oluşturmadan yazıyorsanız , bash geçerli dizindeki dosyaları arar ive komutunuzu buna göre tamamlamaya çalışır. bu dosya adları.

Neden kök olarak gerçekleşmiyor?

Çünkü sudo sukendinizi yapmak için kullandığınızda root, bash tamamlama kütüphanesi kaynaklanmıyor. sudo -iKendiniz yaparsanız bu farklı olurdu root. Bahse girerim bug'u görürsün, değil mi? Örneğin, bkz. 'Sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - hangisinin ne zaman kullanıldığı önemli mi, yoksa hiç önemi var mı? Eğer farklılıkları bilmiyorsanız.

Benim durumumda, normal bir kullanıcı olarak, bir Bash kabuğuna başladığımda kütüphane kaynaklanıyor çünkü ~/.bashrckaynaklar /etc/bash_completionhangi kaynaklar /usr/share/bash-completion/bash_completion.

Eğer sudo -ioturum açmak için kullanırsam root, kütüphane kaynaklanır çünkü /etc/profilekaynaklar /etc/profile.d/bash_completion.shhangi kaynaklar /usr/share/bash-completion/bash_completion.

Bu hata neden oluyor?

Bu komutu yürütmeyi deneyin:

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

Tanıdık geliyor? ;-) Gerçekten de, Tabtanımladığınız bağlamda vurduğunuzda perde arkasında tam olarak olan buydu . Daha doğrusu, hata _quote_readline_by_reftarafından bildirilen işlevdedir /usr/share/bash-completion/bash_completion. Eğer o dosyayı kaynakladıysanız, o fonksiyonun mevcut olması gerekir. Şimdi şunu deneyin:

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

Bu argümanlar göz önüne alındığında, işlev _quote_readline_by_ref, diğer şeylerin yanı sıra, evalyukarıda belirtilenleri yerine getirir . İsterseniz bir göz atabilirsiniz. Ve yazdığınızda env $(cat env.Tab, bu fonksiyonun arkasında tam olarak bu argümanlarla çağrıldı. İşte böyle oldu.

Bu evalkesmek başka bir sorunu düzeltmek gerekiyordu , ama sanırım bu süreçte bu diğer hatayı tanıttı.

Nasıl düzeltebilirim?

Bu hatanın zaten bildirildiği ortaya çıktı . Bu hata raporunu okuduktan sonra düzeltmenin üç yolunu görüyorum:

  1. Düzeltme eki: Bu hata raporundaki yorumlardan birinde, birisi satırı değiştirmenizi önerir

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

    _quote_readline_by_refdosyadaki /usr/share/bash-completion/bash_completionsatır içinde fonksiyon içinde

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

    Bunu yapmamanızı tavsiye ederim. Bu yorumu yazan kişi bash-tamamlama geliştiricisi gibi görünmüyor . Bu düzeltme, deyimin sol işleneninin false olarak değerlendirilmesine neden olur ve böylece bunun olmasını önler eval. Bununla birlikte, bu işlevin ne yapması gerektiği ve hangi bağlamlarda adlandırıldığı hakkında iyi bir bilgi olmadan, bunun potansiyel olarak başka bir amaçlanan işlevselliği bozmayacağı belirsizdir.

  2. En yeni sürümü edinin: Bu hata raporunda da belirtildiği gibi, bu hata git head'ta mevcut değildir (burada diğer değişikliklerin yanı sıra fonksiyon _quote_readline_by_refbasitleştirilmiştir). Geçerli düzeltmeyi Git'ten klonlayabilirsiniz:

    git clone https://salsa.debian.org/debian/bash-completion.git

    ... ve daha sonra bash_completionkomut dosyasının en yeni sürümünü kopyalayın /usr/share/bash-completion(sizi daha güvenli hissettirmedikçe eski sürümü yedeklemeye hiç gerek yok - bazı sorunlarla karşılaşırsanız, sudo apt-get install --reinstall bash-completionyaptığınız değişiklikleri geri almalısınız.) Bu şekilde bunu düzeltmek için acele ediyorsanız tavsiye edin. :-)

Bu çözümlerin hiçbirinin komut değiştirme işi içinde bash tamamlamasını yapmayacağını unutmayın: aynı hata raporunda belirtildiği gibi, bu Bash 4.3'te bozuldu.

  1. Arkanıza yaslanın ve bekleyin: Er ya da geç yeni bir sürüm çıkacak (hatta komut değiştirme içinde bash tamamlamayı bile düzeltebilir) ve gelecekteki Ubuntu sürümüyle birlikte alacaksınız. Ben bunun için gidiyorum ;-)

1
@ con-f-use Yep, hepsi bu! Git repo da bash tamamlama ana sitesinden bağlantılıdır , bu yüzden cevabımda buna bağlanmamıştım.
Malte Skoruppa

2
@ con-f-use Yorumunuz bu hata hakkında biraz daha araştırma yapmama neden oldu. Görünüşe göre bir yukarı akış hatası değil ve asla. Bunun yerine, aslında yukarı akış sürümüne uygulanan bir Ubuntu yaması tarafından sunulan bir hatadır. Kimse bu hatayı şimdiye kadar söz konusu yamaya kadar daraltmadı. Bu yüzden bulgularımı ilgili Ubuntu hata raporunda bildirdim: bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1312243 .
Malte Skoruppa

2
İyi iş Malte.
Barry Kelly

1
Açıklama için teşekkürler. Bu yazıdan sonra, git head sürümü hatayı kaldırdı ve istendiği gibi otomatik tamamladı. EDIT: aslında, boşver, değil.
user3391564

1
@MaxvonHippel ı kullandığınızda söyledi sudo sukök olmak, onu kütüphane kaynak değil, olacak kullandığınızda kaynaklı olsun sudo -iinteraktif kök oturumu almak için amaçlanan yolu olan yerine. Sorunuza gelince: Herhangi bir bash kabuğu ~/.bashrcnihayetinde kütüphaneyi kaynaklayan okuduğu ve bir dosyanın "kaynağını kaldırmanın" bir yolu olmadığından, tamamen basit bir yol görmüyorum. İşte muhtemel kesmek: Bazı ortam değişkeni üzerinde kütüphane koşulun kaynak yapın, diyelim ki, NOCOMPL, değil senin tanımlanan varlık ~/.bashrc, ...
Malte Skoruppa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.