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


13

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

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

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

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

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

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

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


3
どうしてalias cd=pushd?絶対パスではないもの(例:)にcdしたときに何が起こると思いますcd ../か?
パトリック

@Patrick pushdはをサポートしていません-P。しかし、あなたは正しいです、質問に示されているように、function cdディレクトリを2回変更したため、少し間違っているように見えます。
ティノ

回答:


5

command組み込み軍コマンド名は、組み込みまたは外部コマンド(エイリアスと関数のルックアップをスキップ)と解釈されます。bashを含むすべてのPOSIXシェルで使用できます。

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

(この例は悪い例であることに注意してください:相対パスでは動作しないのでpushd、最初に入力するだけでも構いません。)

bashおよびzsh(kshではありません)では、builtinエイリアス、関数、外部コマンドを除いて、コマンド名を強制的にビルトインとして解釈させることができます。


16

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


1

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

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

wrapper.shの例:

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

そして、例えば、.bash_aliases:

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

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


-1

これが相対パスで機能するには、次のものが必要です。

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\";"
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.