web-dev-qa-db-ja.com

組み込みのシェルを明示的に呼び出す方法は?

必要に応じて、cdコマンドの機能をカスタマイズしたい。

次の関数を定義しました-function cd () { cd "$@" && pushd "$@"; }

この関数の目的は、ディレクトリをスタックに自動的にプッシュして、毎回手動でpushd .を入力する手間を省くことです。

ただし、上記の関数は無限に再帰的な関数です。cdへの呼び出しは、cd組み込み関数ではなく関数自体として解釈されるためです。

この関数で組み込みのcdを参照するにはどうすればよいですか?

エイリアスは\を使用してエスケープできることを知っています。より明示的な方法で関数をエスケープするか、組み込みを参照する方法は何ですか?

注:関数の名前を他の名前に変更したくありません。

15
Kshitiz Sharma

command ビルトインは、コマンド名をビルトインまたは外部コマンドとして解釈するように強制します(エイリアスと関数ルックアップをスキップします)。 bashを含むすべてのPOSIXシェルで使用できます。

cd () { command cd "$@" && pushd "$@"; }

(この例は悪い例であることに注意してください。これは相対パスでは機能せず、最初にpushdと入力することもできます。)

Bashおよびzsh(kshではない)では、builtinを使用して、エイリアス、関数、および外部コマンドを除いて、コマンド名を組み込みとして解釈させることができます。

Bashには(ビルトイン)コマンドbuiltinがあり、これはまさに必要なことを行います。関数内でcdbuiltin cdに置き換えると、再帰が修正されます。

16
Petr Uzel

「関数の名前を他の名前に変更したくない」と言ったとき、元のコマンドと同じ名前で関数を呼び出せるようにしたいのではないでしょうか。

したがって、組み込みでないものでも機能する別の方法は、関数に別の名前を付け、ラップされたコマンドのエイリアスを定義することです。これは、エイリアスが関数の実行コンテキストに存在しないため機能します。

Wrapper.shの例:

#!/bin/bash
function my_wrapper() { wrapped_program $@ && dostuff }

そして、例えば、.bash_aliases:

source /path/to/wrapper.sh
alias wrapped_program="my_wrapper"

しかし、これはかなりハッキーです。可能であれば、commandを使用することをお勧めします。

1
matt2000