コマンドラインに組み込まれた「cd」コマンドを上書きすることは可能ですか?


22

コマンドライン(bash)を介してマシンの別のディレクトリ(この場合はMac OS X 10.6.7を実行)に「cd」するたびに、すぐに「ls」と入力してコンテンツのリストを取得しますそのディレクトリに。私は 'cd'をオーバーライドして、要求されたディレクトリに変更し、リストを一度に表示する方法を見つけようとしています。

〜/ .bash_profileに次の行を追加することで、探している基本的な機能を取得することができました

function cl() { cd "$@"; ls -l; }

これは期待どおりに機能します。要求されたディレクトリに変更し、コンテンツを表示します。私が問題に遭遇するのは、新しい「cl」コマンドを作成するのではなく、「cd」自体をオーバーライドしようとしています。

次のものがありません仕事します

##### Attempt 1 #####
# Hangs the command line

function cd() { cd "$@"; ls -l; }


##### Attempt 2 #####
# Hangs the command line

function cd() { 'cd' "$@"; ls -l; }


##### Attempt 3 #####
# Does not change directory. 
# Does list contents, but of the directory where you started.

function cd() { /usr/bin/cd "$@"; ls -l; }


#### Other attempts that fail in various ways #####
alias cd=cd "$@"; ls -la;
alias cd="cd '$@'; ls -la;"
alias cd='cd "$@"'; ls -la;
alias cd=/usr/bin/cd "$@"; ls -la;

また、リストされていない他の反復をいくつか試し、作業中の「cl」関数を指すエイリアスを作成しました。どれも機能しませんでした。

私がドキュメントで読んだことは、「cd」が外部コマンドとして実行できないという事実について語っています(これは、関数がそれを使用するのに必要な方法であると理解しています)。

そのため、現在「cl」コマンドを使用して必要なものを取得できますが、問題は次のとおりです。

「cd」の動作をオーバーライドして、要求されたディレクトリに変更し、その後何か他のことをする方法はありますか?

回答:


30

以下が動作するはずです:

function cd() { builtin cd "$@" && ls -l; }

関数は1行にあるため、;正しく機能するためには、上記のように終了するようにしてください。


パラメーターなしの呼び出しでは機能しません。
ダニエルベック

3
@DanielBeck-少なくとも私のMac OSX(10.6.7)では、これはパラメーターなしの呼び出しで正常に機能しています。動作は、ホームディレクトリに変更し、そのディレクトリのリストを実行することです。普通の「cd」の機能を、最後に追加された新しい機能で効果的に複製します。
アランW.スミス

2
@Alan True、私はそのコードをシェルにアドホックで書くことでテストしました。の行動と思われるcd ""この回答は評価すべきものに(が異なっているcd "$@"空で$@申し訳ありませんが混乱について。。
ダニエル・ベック

@DanielBeck-心配なし。
アランW.スミス

2
注:質問に対する正確な回答であるため、これを承認済みの回答に変更しています。@RichHomolkaによるものはプリンシパルのアドレス指定に最適ですが、これはまさに〜/ .bash_profileファイルに入れることができるものです。
アランW.スミス

10

ループが発生していると思います。あなたのcd関数はを呼び出しcdています。これは...関数です。

builtinコマンド検索で関数ではなくcdなどのBashビルトインを使用するキーワードはどれかを知る必要があります。

function cd
{
    builtin cd "$1"
    : do something else
}

また、/usr/bin/cdそのようなコマンドが存在しても、呼び出しは機能しません。

何が起こるだろう:

  • 私のBashシェルはdirにあり/bash/dirます。
  • コマンドを実行し/usr/bin/cd /dir/for/cdます。
  • /usr/bin/cddirに移動し/dir/for/cdます。
  • /usr/bin/cd 終了します。
  • /bash/dir子プロセス/usr/bin/cdは親に影響を与えることができないため、Bashはまだです。

また、エイリアスは単純なテキスト置換です。パラメータを持つことはできません。


私は提案するbuiltin cd $@ && ls; cd他のすべてが意味をなすために呼び出しが成功するはずだからです。また、cd(引数なし)などの特殊なケースも覚えておいてください。
ダニエルベック

サイドノート:私はこれを受け入れられた答えとしてマークしようとしましたが、それができるようになるまでさらに6分待たなければならないと言っています。それができる前に、組み込みの遅延があることを知りませんでした。
アランW.スミス

@Alan別のより良い解決策は、非常に合理的な時間枠(つまり、数分間待つ必要があります)で出てくるかもしれません。それが、システムによって遅延が義務付けられている理由だと思います。速度よりも品質を優先すべきです。それほど不便ではないはずです。
ダニエルベック

そして勝者がいます。これはチャンピオンのように機能します。@DanielBeckごとに、&&を使用するように変更し、次のように1行に圧縮しました。function cd {builtin cd "$ @" && ls -l; }
アランW.スミス

@DanielBeck-ええ、心配していません。以前は気づかなかった。私はその中の論理を見ることができます、ちょっと驚いただけです。
アランW.スミス

6

「cd」機能をハイジャックする他のスクリプト(rvmなど)があるため、cdをオーバーライドしないことをお勧めします。代わりに「d」などの別の名前を選択し、関数で「builtin」タイプを指定しない方が良いでしょう。そうしないと、ハイジャッカーは機能しません。私は以下のコードを使用しています:

function d() { cd "$@" && ls;} 

OPの質問によると、これはうまくいかないと思った。
user305964
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.