2016-12-30 8 views
4

私はどこからでもプロジェクトディレクトリにジャンプできるシェルスクリプト(.bashrcにあります)を持っています。シェルスクリプトは、cdを実行しているときにディレクトリが存在しないと考えています

cdp(){ 
    proj="~/dev/projects/[email protected]/" 
    builtin cd $proj 
} 

_my_cdp() 
{ 
    local cur opts 
     cur="${COMP_WORDS[COMP_CWORD]}" 
     opts=$(ls ~/dev/projects/) 
     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
} 

complete -o nospace -F _my_cdp cdp 

問題があり、3行目のcdは言う:ここ

bash: cd: ~/dev/projects/jsonparse/: No such file or directory 

がフルコンソール出力がエラーを示すとディレクトリが存在証明です。

amflare:~$ cd dev/projects/ (go to dir) 
amflare:~/dev/projects$ ls -al (look at contents) 
total 68 
drwxrwxr-x 17 www-data amflare 4096 Dec 29 13:11 . 
drwxrwxr-x 4 amflare amflare 4096 Dec 6 17:32 .. 
drwxrwxr-x 3 www-data amflare 4096 Dec 22 17:33 bot 
drwxrwxr-x 3 www-data amflare 4096 Dec 20 15:17 jsonparse 
drwxrwxr-x 3 www-data amflare 4096 Dec 28 19:58 magic 
drwxrwxr-x 2 www-data amflare 4096 Nov 11 14:42 test 
amflare:~/dev/projects$ cd (go to home) 
amflare:~$ cdp (run autocomplete) 
bot   jsonparse magic  test 
amflare:~$ cdp jsonparse (pick target) 
bash: cd: ~/dev/projects/jsonparse/: No such file or directory 
amflare:~$ (still in home) 

私は、私は考えることができるすべてのものと、Googleは他のディストリビューション(私はUbuntuのGnomeの16.04によ)のために戻ったいくつかのことを試してみました。私が何をしても、シェルスクリプトは~/dev/projects/の中に何かの存在を認めません。さらに、それは私自身が.bashrcの機能を持っていると動作しないので、サブシェルの問題ではないと思います。これ以上の情報が必要な場合はお知らせください。ありがとう。

+0

チルダが展開されていないためです。 'proj =〜/" dev/projects/$ @/"'を引用符のうちのチルダで置き換えてください。あるいは、変数 'HOME'を使用してください:' proj = "$ HOME/dev/projects/$ @" 'しかし、 '$ @ 'を使うことは本当に良いことではないことに注意してください。いくつかの議論がある場合、あなたは何を望みますか? –

+0

http://shellcheck.net/でこのコードを実行することを検討してください。それはすべてを捕らえないかもしれませんが、始める場所です。 –

+0

...参照、f/e、[ParsingLs](http://mywiki.wooledge.org/ParsingLs) - 'ls'はプログラム的な使用には不適切なツールです。そして引用全体の欠如は、それ自身の問題につながります。 –

答えて

5

チルダが展開されていないためです。引用符で囲まれたティルダを使用してproj=~/"dev/projects/[email protected]/"を使用してください。または、変数HOMEproj="$HOME/dev/projects/[email protected]"を使用します。ただし、[email protected]を使用すると、実際にはうまくいかないことに注意してください。いくつかの議論がある場合、あなたは何を望みますか?


また、opts=$(ls ~/dev/projects/)を使用しないでください。そのように直接compgenを使用します。完了すると

cdp() { 
    local proj=~/dev/projects/ 
    builtin cd "$proj$1" 
} 

_my_cdp() { 
    local proj=~/dev/projects/ 
    local i p 
    COMPREPLY=() 
    while IFS= read -r i; do 
     printf -v p '%q' "${i#"$proj"}" 
     COMPREPLY+=("$p") 
    done < <(compgen -d -- "$proj$2") 
} 

、補完機能_my_cdpがパラメータ$2完成されている単語として持つことになります。我々はそれをcompgen -d(接頭辞は$proj)にして、結果をループします(結果は1行に1つ出力されるので、ディレクトリに改行があれば壊れます)。各名前が見つかったら、printf '%q'を使用して引用符を付け、パラメータ拡張を使用して接頭辞$projを削除します。ディレクトリ名にスペースや面白い文字(グロブ文字など)が含まれている場合は引用符を使用しないでください。COMPREPLYを一度に1つずつ入力します。それは完璧に対処するためのかなり堅牢な方法です(ただし、100%は解消できませんが、あなたの非狂ったディレクトリ名のために仕事をするでしょう)。

+0

それが問題でした。ありがとう。 $ @に関しては、私はこれを他の人のコードから外して、それを変更しようとはしませんでした。私は今でも持っている。 – amflare

+1

@tbirrell:回答が少し上手くいって完成しました! –

+0

Ah。乾杯!私は実際にそれを理解しようとしている途中でした。私は理解していないここに多くの可動部分があります。それはあまりにも多くのトラブル、コードゴルフスタイルを実行して取得するか? – amflare

関連する問題