Anda menemukan bug di perpustakaan Bash Completion yang digunakan oleh Ubuntu.
Apa artinya ini?
Ubuntu menggunakan pustaka penyelesaian bash untuk membuat penyelesaian bash pintar. Perpustakaan ini tinggal di /usr/share/bash-completion/bash_completion
.
Pada dasarnya, pustaka ini mendeklarasikan beberapa fungsi pintar yang tahu tentang perintah-perintah tipikal dan bagaimana menyelesaikannya. Setiap kali Anda menekan Tab, fungsi-fungsi dalam perpustakaan ini dipanggil dan berusaha untuk menyelesaikan baris perintah Anda saat ini. Jadi misalnya jika Anda mengetiknya apt-get i
Tabakan menyelesaikan itu untuk apt-get install
. Jika Anda tidak sumber perpustakaan itu, Anda hanya memiliki standar, penyelesaian bash primitif - jadi misalnya jika Anda mengetik apt-get i
Tabtanpa membuatnya, bash hanya akan mencari file di direktori saat ini dimulai dengan i
dan mencoba untuk menyelesaikan perintah Anda sesuai dengan nama file ini.
Mengapa itu tidak terjadi sebagai root?
Karena ketika Anda menggunakan sudo su
untuk membuat sendiri root
, pustaka penyelesaian bash tidak bersumber. Ini akan berbeda jika Anda sudo -i
membuat sendiri root
. Saya yakin Anda melihat bug itu, bukan? Lihat misalnya 'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - kapan itu penting yang digunakan, atau apakah itu penting sama sekali? jika Anda tidak terbiasa dengan perbedaan.
Dalam kasus saya, sebagai pengguna normal, pustaka akan bersumber ketika saya memulai Bash shell karena ~/.bashrc
sumber /etc/bash_completion
yang sumbernya /usr/share/bash-completion/bash_completion
.
Jika saya gunakan sudo -i
untuk masuk sebagai root
, perpustakaan akan bersumber karena /etc/profile
sumber /etc/profile.d/bash_completion.sh
yang sumbernya /usr/share/bash-completion/bash_completion
.
Mengapa bug itu terjadi?
Cobalah untuk menjalankan perintah ini:
$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Terlihat tidak asing? ;-) Memang, itulah yang terjadi di balik layar ketika Anda menekan Tabdalam konteks yang Anda gambarkan. Lebih tepatnya, bug ada dalam fungsi yang _quote_readline_by_ref
dideklarasikan oleh /usr/share/bash-completion/bash_completion
. Jika Anda membuat sumber file itu, Anda harus memiliki fungsi itu tersedia. Jadi selanjutnya coba ini:
$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Dengan argumen-argumen ini, fungsi _quote_readline_by_ref
melakukan, antara lain, yang eval
disebutkan di atas. Anda dapat melihatnya jika mau. Dan ketika Anda mengetik env $(cat env.
Tab, di balik layar yang berfungsi dipanggil dengan tepat argumen itu. Jadi itulah yang terjadi.
Ini eval
hack seharusnya untuk memperbaiki masalah lain , tapi saya kira itu diperkenalkan bug lain ini dalam proses.
Bagaimana saya memperbaikinya?
Ternyata bug ini sudah dilaporkan . Setelah membaca laporan bug itu, saya melihat tiga cara untuk memperbaikinya:
Menambalnya: Di salah satu komentar dalam laporan bug itu, seseorang menyarankan untuk mengganti baris
[[ ${!2} == \$* ]] && eval $2=${!2}
dalam fungsi _quote_readline_by_ref
dalam file /usr/share/bash-completion/bash_completion
dengan garis
[[ ${!2} == \$\'* ]] && eval $2=${!2}
Saya merekomendasikan untuk tidak melakukan ini. Orang yang menulis komentar itu tampaknya bukan pengembang penyelesaian-bash . Perbaikan terbaru ini hanya akan menyebabkan operan kiri pernyataan untuk mengevaluasi ke salah dan dengan demikian mencegah hal itu eval
terjadi. Namun tanpa pengetahuan yang baik tentang apa fungsi yang seharusnya dilakukan dan dalam konteks apa namanya, tidak jelas apakah ini tidak akan berpotensi merusak beberapa fungsi yang dimaksudkan lainnya.
Dapatkan versi terbaru: Seperti yang juga disebutkan dalam laporan kutu itu, kutu ini tidak ada di git head (di mana di antara perubahan lainnya fungsi _quote_readline_by_ref
tersebut telah disederhanakan). Anda dapat mengkloning revisi saat ini dari Git:
git clone https://salsa.debian.org/debian/bash-completion.git
... lalu salin versi terbaru bash_completion
skrip ke /usr/share/bash-completion
(tidak perlu segera mencadangkan versi lama kecuali jika itu membuat Anda merasa lebih aman - jika Anda mengalami beberapa masalah, sudo apt-get install --reinstall bash-completion
kembalikan perubahan yang Anda buat dengan baik.) Ini adalah cara saya merekomendasikan jika Anda sedang terburu-buru untuk memperbaikinya. :-)
Perhatikan bahwa tidak ada solusi yang akan membuat penyelesaian bash di dalam pekerjaan substitusi perintah: seperti yang disebutkan dalam laporan bug yang sama, ini rusak di Bash 4.3.
- Duduk dan tunggu: Cepat atau lambat versi baru akan dirilis (yang bahkan dapat memperbaiki penyelesaian bash di dalam substitusi perintah) dan Anda akan mendapatkannya dengan beberapa versi Ubuntu di masa depan. Itulah tujuan saya ;-)