2013-05-27 29 views
10

シェル関数をオーバーライドして元のものへの参照を保持することは可能ですか?シェル関数をオーバーライドし、元のものへの参照を保持する

f() { echo original; } 
f() { echo wrapper; ...; } 
f 

これの出力は次のようになります。

wrapper 
original 

が、これは半ポータブルな方法で可能ですか?

根拠:プログラムの一部を、呼び出しをログファイルに記録するシェル関数で置き換えてプログラムをテストしようとしています。これは、コマンドや組み込み関数をラップするだけで、無差別なログを気にしない限り、うまく動作します。今度は、各テストで興味深い部分を記録するだけで、テストスイートをよりメンテナンス可能にしたいと思っています。

は、それでは、私のプログラムはfghは、すべてのシェル関数です

f 
g 
h 

で構成しましょう、と私はちょうどgの実行をトレースしたいと思います。

+0

何がなく、非常に移植性、行うことができますしたいです。 –

答えて

3

多くのシェル(zsh、ksh、少なくともbash)は、f()の内容をダンプするためにtypeset -f fをサポートしています。 これを使用して、現在の定義をファイルに保存します。必要に応じてf()と定義します。 typesetで作成したファイルを使用してf()を復元します。

あなたは少し(最初の行に_f()f()の名前を変更し、少しトリッキーfは()再帰的であるか、同じようにfrobbed他の関数を呼び出すとき)ダンプ機能を変更した場合、あなたはおそらくこれを生成するために取得することができますあなたが望む出力。

+0

もう一つのそのようなコマンド: 'declare -f f'どちらが移植性が高いのかわからない... – anishsane

+0

' typeset'も 'declare'もPOSIX(Issue 8、2013)ではありません。 – Jens

+0

@Jens:Issue 7 TC1(2013版)を意味します。第8号はまだ発行されていない。 :) –

4

ジェンスの答えは正しいです。完全性のために以下のコードを追加するだけです。

あなたは、単に以下のようにそれを使用することができます。

eval "`declare -f f | sed '1s/.*/_&/'`" #backup old f to _f 

f(){ 
    echo wrapper 
    _f # pass "[email protected]" to it if required. 
} 

私はここで同じロジックを使用していました:https://stackoverflow.com/a/15758880/793796

+0

+1のアイデアはevalです。 – Jens

+1

+1。私はまたこのテクニックを使用しました[ここ](http://askubuntu.com/questions/73262/how-do-i-teach-bash-in-ubuntu-some-curse-words/73282#73282) –

+0

@glennjackman:私alias_functionというアイデアが好きだった:) – anishsane

関連する問題