Ubuntu日本語フォーラム
ログインしていません。
ubuntu 10.10
bash 4.1.5
端末上で
$ cd ~/Doc
としてTabを押すと、
$ cd /home/hoge/Documents/
となって、チルダがホームディレクトリに展開されてしまいます。希望としては
$ cd ~/Documents/
となって欲しいです(単に見やすいからです)。
http://homepage2.nifty.com/takaaki024/tips/computers/unix/linux.html
を見ると「bash-completion を入れてるとそうなる」から削除しろということですが、
bash-completionをapt-get removeで削除しても、症状は改善されませんでした
(OSを再起動してないからでしょうか)。
なにか設定方法があるのでしょうか。
ご存じの方、よろしくお願いします。
オフライン
そのような仕様です(/homeで表示されるのはログインしたユーザのディレクトリ・ファイル等です)。
マルチユーザーシステムなので、/homeの直下はuserのホルダーになります。
つまり、ログイン名がDocでないかぎり、/home/Docはできません。
オフライン
実際に「bash-completion」を削除して、PCを再起動してみました。
たしかに、tabを使った補完機能はなくなりますが、『cd ~/』は『cd /home/hogehoge/』に展開されました。
Docが”/”以下にあれば、単に『cd /Doc』と入力すれば良いことなのではないでしょうか?
オフライン
> つまり、ログイン名がDocでないかぎり、/home/Docはできません。
それはよく分かります。私がしたいのはそのようなことではありません。
tab補完のときに「~」が「/home/hoge」に展開されてしまうのが嫌なのです。
例えば・・・
私のホームディレクトリが/home/uchan_nos/だとします。
/home/uchan_nos/Documents/workspace/まで移動したいとします。
現在の設定では
/$ cd ~/Doc[tab]
/$ cd /home/uchan_nos/Documents/
/$ cd /home/uchan_nos/Documents/w[tab]
/$ cd /home/uchan_nos/Documents/workspace/[enter]
workspace$
となります。やりたいのは
/$ cd ~/Doc[tab]
/$ cd ~/Documents/
/$ cd ~/Documents/w[tab]
/$ cd ~/Documents/workspace/[enter]
workspace$
ということです。どちらにしても、目的のディレクトリは
/home/uchan_nos/Documents/workspace/
なのです。
オフライン
~/.bashrcあたりの最後の方に、
_expand() { return 0; } __expand_tilde_by_ref() { return 0; }
とか追記すれば、~の展開は抑制できそうです。
/etc/bash_completion
とかの内容も見てみて下さい。
オフライン
Ubuntu10.04,bash 4.1.5の環境ですが、Tabを押してもチルダのままで表示されます。
/etc/bash_completionを調べてみたら、何やら怪しいコメント(FIXME: Why was this here?)が…。
# This function expands tildes in pathnames # _expand() { # FIXME: Why was this here? #[ "$cur" != "${cur%\\}" ] && cur="$cur\\"
上の記述を探して、
[ "$cur" != "${cur%\\}" ] && cur="$cur\\"
の行の先頭に「#」が入っていなければ追加して保存してみて下さい。
※ 10.10の環境がないのですが、11.04(開発版)でも同じ記述が見られます。
※ hmatsueさんの方法でも可能かと思います。
オフライン
hmatsueさんに示していただいた解決策で無事解決しました。ありがとうございました。
それにしても関数を上書き(と言うのかよく分かりませんが。)してしまうなんて凄い方法ですね。勉強になります。
ところで/etc/bash_completionの_expand()関数の中にはこんな文章がありました。
# Expand ~username type directory specifications. We want to expand
# ~foo/... to /home/foo/... to avoid problems when $cur starting with
# a tilde is fed to commands and ending up quoted instead of expanded.
なぜ展開するのか、その理由が示されているらしいですが、あまり意味は分かりません。
展開しないと何か問題が起こる場合があることは分かりました。
vine_userさんが指摘されていた行は、当方のbash_completionにおいても
コメントアウトされておりました。FIXMEの行もちゃんとありました。
展開しないとどんな問題があるか気になりますが、とりあえず今のところはいい感じです。
みなさんありがとうございました。
オフライン
『/home/uchan_nos/Documents/workspace/』のうちの
「/home/uchan_nos」を表示させたくないだけなら、「bash-completion」を削除して、PCを再起動すればできますね。
オフライン
Bug #622403に関係していそうですね。この報告のコメントを見ると、/etc/bash_completionを下記のように書き換えればいいみたいですけど、僕の環境では変更前の状態でもチルダで表示されます(謎
変更前
_expand() { # FIXME: Why was this here? #[ "$cur" != "${cur%\\}" ] && cur="$cur\\" # Expand ~username type directory specifications. We want to expand # ~foo/... to /home/foo/... to avoid problems when $cur starting with # a tilde is fed to commands and ending up quoted instead of expanded. if [[ "$cur" == \~*/* ]]; then eval cur=$cur elif [[ "$cur" == \~* ]]; then cur=${cur#\~} COMPREPLY=( $( compgen -P '~' -u "$cur" ) ) [ ${#COMPREPLY[@]} -eq 1 ] && eval COMPREPLY[0]=${COMPREPLY[0]} return ${#COMPREPLY[@]} fi }
変更後
_expand() { # FIXME: Why was this here? #[ "$cur" != "${cur%\\}" ] && cur="$cur\\" # Expand ~username type directory specifications. We want to expand # ~foo/... to /home/foo/... to avoid problems when $cur starting with # a tilde is fed to commands and ending up quoted instead of expanded. if [[ "$cur" == \~*/* ]]; then if [ $(bind -v|grep 'set expand-tilde on'> /dev/null) ]; then eval cur=$cur else return 0; fi elif [[ "$cur" == \~* ]]; then cur=${cur#\~} COMPREPLY=( $( compgen -P '~' -u "$cur" ) ) [ ${#COMPREPLY[@]} -eq 1 ] && eval COMPREPLY[0]=${COMPREPLY[0]} return ${#COMPREPLY[@]} fi }
ちなみに、次のコマンドでexpandが有効になっているかどうか確かめられるようです。
$ bind -v | grep tilde
set expand-tilde off ←expandが無効の場合
set expand-tilde on ←expandが有効の場合
オフライン
実は、私の環境でもvine_userさんと同じく、標準では~/はtab機能では展開されませんでしたので、
『「bash-completion」を削除して、PCを再起動したら〜』私の書き込みは確認できません。無視してください。
オフライン
vine_userさんに示していただいたBug #622403によると、第一の解決方法だと解決しない人がいるみたいです。自分もその一人です。
自分の環境では
$ bind -v | grep tilde
set expand-tilde off
となりました。
先程のバグ情報の会話によれば、_expand()はset expand-tilde onのときに呼び出される関数で、
__expand_tilde_by_ref()がset expand-tilde offのときに呼び出されるのではないかと思います。
ということで自分なりに/etc/bash_completionを編集し、__expand_tilde_by_ref()を以下のようにしてみました。
__expand_tilde_by_ref() { # Does $1 start with tilde (~)? #if [ "${!1:0:1}" = "~" ]; then if [ "${!1:0:1}" = "~" ] && _rl_enabled expand-tilde; then ... fi } # __expand_tilde_by_ref()
if文が二つありますが、下のほうが自分のものです。上がオリジナル。
これは先のバグ情報の会話でVictor Zamanianさんが示していた修正方法を若干変えたものです。
この変更により、(~/.bashrcで関数を上書きする方法をとらなくても)チルダが展開されなくなりました。
ちなみに_expand()はオリジナルのままです。
オフライン
#11で投稿した修正を行った状態で、
$ bind 'set expand-tilde on'
$ bind 'set expand-tilde off'
とすることで、チルダの展開有り無しを切り替えることができました。
ずっとチルダの展開有り無しを設定するには、~/.inputrcに
set expand-tilde [on|off]
を書いておけばよさそうですね(未検証)
オフライン
Bug #622403のコメント欄を最後までよく見ていませんでした。すみません。
uchan_nosさんのおっしゃるとおり、expand-tilde offの際に呼び出されるのは、__expand_tilde_by_ref()の方のようですね。
今回もいろいろ調べる過程で勉強になりました。正直、個人的にはチルダでもフルパスでもどっちでもいいんですけど、こういう細かいことからしくみがわかってくるのは面白いです。
ちなみに、
.inputrcに「set expand-tilde [on|off]を追記」
ではなく、
.bashrcに「bind 'set expand-tilde [on|off]'を追記」
ですね。実際にやってみたら、expandのon/offを制御できました。
オフライン
vine_user による投稿:
ちなみに、
.inputrcに「set expand-tilde [on|off]を追記」
ではなく、
.bashrcに「bind 'set expand-tilde [on|off]'を追記」
ですね。実際にやってみたら、expandのon/offを制御できました。
とのことですが、当方の環境で検証したところ(遅っ!)、.inputrcに書いてもうまく制御できました。
bindコマンドの引数は、オプションがない場合.inputrcに書くのと等価だと書いてありました。
vine_userさんの.bashrcに書く方法でもいいですね。
両方に書いた場合、.bashrcの設定が優先されるようです。
オフライン
あ、端末を再起動していませんでした。
.inputrcでもOKですね。すみません。
オフライン