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

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

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

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

この機能の目的は、ディレクトリをスタックに自動的にプッシュすることです。これにより、pushd .毎回手動で入力する必要がある手間が少なくなります。

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

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

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

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

答え1

builtinBashには、必要な操作を正確に実行する(組み込み)コマンドがあります。関数内で置き換えると再帰が修正されcdます。builtin cd

答え2

これcommand組み込みコマンドは、コマンド名を組み込みまたは外部コマンドとして解釈します(エイリアスと関数の検索をスキップ)。 bashを含むすべてのPOSIXシェルで動作します。

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

(この例は悪い例です。相対パスでは機能しないため、最初に入力することをお勧めしますpushd。)

bashとzsh(kshではない)では、builtinforceを使用してコマンド名をエイリアス、関数、および外部コマンド以外の組み込みコマンドとして解釈できます。

答え3

「関数名を別の名前に変更したくありません」と言うのは、元のコマンドと同じ名前で関数を呼び出すことができることを意味しているようです。

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

ラッパー.sh 例:

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

たとえば、.bash_aliases では次のようになります。

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

しかし、これはかなり陳腐な表現です。command可能であれば使用するのが最善です。

答え4

相対パスを使用するには、次のものが必要です。

function cd { 
   dir="$(realpath "$@")"
   command cd "$dir"
   pushd "$dir"
}

これは、「realpath」ユーティリティを含むのに十分近代的なLinuxディストリビューションを使用していると仮定します。 (たとえば、RHEL 6の場合はそうではありません。)Perlが利用可能な場合は、次のように「realpath」をシミュレートできます。

! realpath $(pwd) > /dev/null 2>&1  && function realpath {
    perl -e "use Cwd realpath; print realpath(\"$1\") . \"\\n\";"
}

関連情報