通知スクリプトを強化しようとしています。スクリプトの動作方法は、長時間実行されているシェルコマンドの背後に配置し、長時間実行されたスクリプトが終了した後、あらゆる種類の通知が呼び出されることです。
例えば:
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
vs.
~ $: 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番目の解決策の合併症を恐れています。
これを行うことはできますか、それともシェルの動作方法と根本的に互換性がありませんか?
私のシェルはzsh
ですが、bash
でも動作するようにしたいです。
それを実現するには、実際にシェル関数を使用する必要があります。このような単純なスクリプトの場合、zshとbashの両方で動作させるのはかなり簡単です。以下をファイルに配置するだけです。
my_notify() {
echo "exit code: $?"
echo "PPID: $PPID"
}
次に、シェル起動ファイルからそのファイルを入手します。これは対話型シェル内から実行されるため、$ PPIDではなく$$を使用することもできます。
互換性がありません。 $?
のみ現在のシェル内に存在します。サブプロセスで使用できるようにする場合は、環境変数にコピーする必要があります。
別の方法は、代わりに何らかの方法で使用するシェル関数を記述することです。
これを実装する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
このスクリプトを目的に合わせて調整できます。