44

我正在尝试加强我的通知脚本。脚本的工作方式是我将它放在一个长时间运行的 shell 命令后面,然后在长时间运行的脚本完成后调用各种通知。

例如:

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...我的问题将得到解决,但我实际上喜欢我可以在命令结束时解决它,并且我担心第二种解决方案的复杂性。

可以做到这一点,还是从根本上与 shell 的工作方式不兼容?

我的 shell 是 Z shell ( zsh),但我希望它也可以与 Bash 一起使用。

4

3 回答 3

43

你真的需要使用一个shell函数来完成它。对于像这样的简单脚本,让它在 zsh 和 bash 中运行应该很容易。只需将以下内容放入文件中:

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

然后从您的 shell 启动文件中获取该文件。尽管这将在您的交互式 shell 中运行,但您可能希望使用 $$ 而不是 $PPID。

于 2012-10-24T23:23:28.793 回答
6

这是不兼容的。$? 仅存在于当前 shell 中;如果您希望它在子流程中可用,则必须将其复制到环境变量中。

另一种方法是编写一个以某种方式使用它的 shell 函数。

于 2012-10-21T16:39:41.707 回答
3

实现这一点的一种方法是使用 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 回答