44

通知スクリプトを強化しようとしています。スクリプトが機能する方法は、長時間実行されるシェルコマンドの背後にスクリプトを配置し、長時間実行されるスクリプトが終了した後にあらゆる種類の通知が呼び出されるようにすることです。

例えば:

sleep 100; my_notify

長時間実行されているスクリプトの終了コードを取得すると便利です。問題は、呼び出しによって、変数my_notifyにアクセスできない新しいプロセスが作成されることです。$?

比較:

~ $: ls nonexisting_file; echo "exit code: $?"; echo "PPID: $PPID"
ls: nonexisting_file: No such file or directory
exit code: 1
PPID: 6203

対。

~ $: ls nonexisting_file; my_notify
ls: nonexisting_file: No such file or directory
exit code: 0
PPID: 6205

my_notifyスクリプトには次のものが含まれています。

#!/bin/sh
echo "exit code: $?"
echo "PPID: $PPID"

コマンドの構造をあまり変更せずに、前のコマンドの終了コードを取得する方法を探しています。timeたとえば、問題が解決するように変更すると、問題が解決するという事実を認識していますが、my_notify longrunning_command...実際には、コマンドの最後でそれに取り組むことができ、この2番目の解決策の複雑さを恐れています。

これを行うことはできますか、それともシェルの動作方法と根本的に互換性がありませんか?

私のシェルはZシェル(zsh)ですが、Bashでも動作するようにしたいと思います。

4

3 に答える 3

43

これを実現するには、シェル関数を使用する必要があります。このような単純なスクリプトの場合、zshとbashの両方で機能させるのは非常に簡単です。以下をファイルに入れるだけです。

my_notify() {
  echo "exit code: $?"
  echo "PPID: $PPID"
}

次に、シェルのスタートアップファイルからそのファイルを入手します。これはインタラクティブシェル内から実行されるため、$PPIDではなく$$を使用することをお勧めします。

于 2012-10-24T23:23:28.793 に答える
6

互換性がありません。現在のシェル内に$? のみ存在します。サブプロセスで使用できるようにする場合は、環境変数にコピーする必要があります。

別の方法は、代わりに何らかの方法でそれを使用するシェル関数を作成することです。

于 2012-10-21T16:39:41.707 に答える
3

これを実装する1つの方法は、EOFタグとmy_notifyスクリプトを作成するマスタースクリプトを使用することです。


#!/bin/bash

if [ -f my_notify ] ; then
rm -rf my_notify
fi

if [ -f my_temp ] ; then
rm -rf my_temp
fi

retval=`ls non_existent_file &> /dev/null  ; echo $?`
ppid=$PPID
echo "retval=$retval" 
echo "ppid=$ppid" 
cat >> my_notify << 'EOF'
#!/bin/bash

echo "exit code: $retval"
echo " PPID =$ppid"
EOF

sh my_notify 

このスクリプトは、目的に合わせて調整できます。

于 2012-10-21T19:00:53.930 に答える