通常、スクリプトのすべてのデバッグ出力をファイルに保存したいので、次のようになります。
exec 2> somefile
set -xv
これは bash でも問題なく動作しますが、ksh では関数に関して異なる動作をすることに気づきました。ksh でこれを実行すると、出力には関数のトレースが表示されず、関数が呼び出されたことだけが表示されることに気付きました。
追加のテストを行うと、次の ksh 構文を使用する場合、関数の宣言方法によって動作も異なることに気付きました。
function doSometime {....}
私が見ているのは関数呼び出しだけですが、他の方法で関数を宣言すると、例えば
doSomething() {....}
トレースは期待どおりに動作します。set -xv
両方のタイプの関数宣言で同じように動作させることは可能ですか? 試してみましたexport SHELLOPTS
が、違いはありませんでした。
Solaris 11 で ksh93 を使用しています。
答え1
ドキュメントより:
定義される関数関数 名前構文と名前で呼び出されたものは、呼び出し元と同じプロセスで実行され、すべてのファイルと現在の作業ディレクトリを呼び出し元と共有します。 呼び出し元によってキャッチされたトラップは、関数内のデフォルトのアクションにリセットされます。
一方
関数は名前() 構文と関数名構文で定義された関数は、. 特殊組み込み関数で呼び出され、呼び出し元の環境で実行され、すべての変数とトラップを呼び出し元と共有します。
解決策は、function
キーワードを使用せず、関数定義の標準形式に従うことです。
あるいは、いくつかの関数のみに関心がある場合は、typeset -tf fname
関数のみをトレースしますfname
(キーワードで定義されている場合function
)。
トレースを停止するには:typeset +tf fname
ksh93 でこのような関数をすべてトレースするには:typeset -tf $(typeset +f)
トレースされる関数を確認するには:typeset +tf
すべての関数のトレースを停止するには:typeset +tf $(typeset +tf)