web-dev-qa-db-ja.com

Bashタブの完了: '-bash:予期しないEOF一致する `)'の検索中-bash:構文エラー:予期しないファイルの終わり

このコマンドを使用して、ファイルから特定の環境変数でirbセッションにアクセスしようとしています。

$ env $(cat env.sh) irb

しかし、env.と入力してTabを押して完了しようとすると、次のエラーが表示されます。

$ 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ユーザーではないときにどのように修正しますか?

18
eldosoa

Ubuntuで使用されている Bash Completion ライブラリにバグが見つかりました。

これはどういう意味ですか?

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

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

なぜrootとして実行されないのですか?

Sudo suを使用して自分をrootにすると、bash補完ライブラリが提供されないためです。 Sudo -iを使用して自分をrootにした場合、これは異なります。バグが表示されると思いますか?例えば 'Sudo su-' vs 'Sudo -i' vs 'Sudo/bin/bash'-どちらが使用されるか、それともまったく問題になるか あなたがそうでない場合違いに精通しています。

私の場合、通常のユーザーとして、~/.bashrc/etc/bash_completionをソースする/usr/share/bash-completion/bash_completionであるため、Bashシェルを起動するとライブラリがソースになります。

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バージョンでそれを取得します。それが私が目指していることです;-)
33
Malte Skoruppa