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

もう1つの興味深い点は、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を使用してrootにログインしましたsudo su
eldosoa

質問を編集して、の出力を追加してくださいfind ~ -uid 0
ムル

@muru完了。私の質問に出力を追加しました。
eldosoa

申し訳ありませんが、ルートとしてではありません!私はあなたの通常のユーザーとして意図したので、それ~/home/somethingです。
ムル

回答:


33

Ubuntuで使用されるBash Completionライブラリにバグを発見しました。

これは何を意味するのでしょうか?

Ubuntuはbash補完ライブラリを使用してbash補完をスマートにします。このライブラリはにあり/usr/share/bash-completion/bash_completionます。

基本的に、このライブラリは、典型的なコマンドとそれらを完了する方法を知っているいくつかの巧妙な関数を宣言します。を押すたびにTab、このライブラリ内の関数が呼び出され、現在のコマンドラインを完了しようとします。したがって、たとえば、入力apt-get iTabすると、それが完了しapt-get installます。そのライブラリをソース化しない場合、標準のプリミティブなbash補完しかありません-たとえば、apt-get iTabソース化せずに入力すると、bashは現在のディレクトリ内のファイルを探してi、コマンドに従ってコマンドを完了しようとしますこれらのファイル名。

なぜrootとして起こらないのですか?

あなたsudo suが自分自身を作るために使用するときroot、bash補完ライブラリがソースされていないためです。あなたsudo -iが自分自身を作るために使用する場合、これは異なりますroot。バグが表示されると思いますか?たとえば、「sudo su-」と「sudo -i」と「sudo / bin / bash」を参照してください-どちらが使用されるか、または何が問題になるか 違いに慣れていない場合。

私の場合は、通常のユーザーとして、ライブラリは、私は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ハックは別の問題を修正するはずでしたが、プロセスにこの他のバグが導入されたと思います。

どうすれば修正できますか?

このバグはすでに報告されていることが判明しています。そのバグレポートを読んだ後、それを修正する3つの方法があります。

  1. パッチを当てる:そのバグレポートのコメントの1つで、誰かが行を置き換えることを提案します

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

    _quote_readline_by_refファイル内/usr/share/bash-completion/bash_completionの行内の関数内

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

    これをしないことをお勧めします。そのコメントを書いた人はbash-completionの開発者ではないようです。この修正プログラムは、ステートメントの左側のオペランドをfalseに評価するだけで、それが発生しないようにevalします。ただし、その関数が何をするのか、どのコンテキストで呼び出されるのかについての十分な知識がなければ、これが他の意図された機能を破壊しないかどうかは不明です。

  2. 最新バージョンを入手する:そのバグレポートでも述べたように、このバグはgit headには存在しません(他の変更の中でも、関数_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を完了させないことに注意してください。同じバグレポートで述べたように、これはBash 4.3で壊れています。

  1. 座って待ってください:遅かれ早かれ、新しいバージョンがリリースされ(コマンド置換内のbashの完了も修正される可能性があります)、将来のUbuntuバージョンで入手できます。それが私が目指していることです;-)

1
@ con-f-useうん、それだ!Gitレポジトリはbash-completionのメインサイトからもリンクされているため、回答ではリンクしていませんでした。
マルテスコルッパ

2
@ con-f-useあなたのコメントにより、このバグについてさらに調査することになりました。それは、アップストリームのバグではなく、かつ決してなかったことが判明しました。代わりに、実際にはアップストリームバージョンに対して適用されたUbuntuパッチによって導入されたバグです。これまでのところ、このバグを特定のパッチに絞り込んでいる人はいないようです。そのため、対応するUbuntuのバグレポート:bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1312243で発見したことを報告しました
マルテスコルッパ

2
素敵な仕事マルテ。
バリーケリー

1
説明してくれてありがとう。これを書いている時点で、git headバージョンはバグ削除し、必要に応じてオートコンプリートしました。編集:実際には、気にしないで、そうではありません。
user3391564

1
@MaxvonHippel私はあなたが使用した場合と言ったsudo suルートになるために、それはライブラリをソースしませんが、それはなりますあなたが使用している場合にソースを取得sudo -i代わりにインタラクティブルートセッションを取得することを目的と方法です。あなたの質問に関して:bashシェルは~/.bashrc最終的にライブラリをソースし、ファイルを「ソース解除」する方法がないため、完全に簡単な方法はありません。ここで可能なハックだ:いくつかの環境変数のライブラリ条件の調達を行い、たとえば、NOCOMPLないあなたに定義されている~/.bashrc、...
マルタSkoruppa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.