在另一个脚本中获取上一个shell命令的退出码

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

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...,我的问题将得到解决,但我实际上喜欢将其附加在命令末尾,并担心这种第二种解决方案会带来复杂性。
这是否可行,还是与shell的工作方式根本不兼容?
我的shell是Z shell(zsh),但我也希望它能与Bash一起使用。
3个回答

44

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

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

然后从您的shell启动文件中源该文件。尽管由于此将在交互式shell内运行,因此您可能想要使用$$而不是$PPID。


6

它不兼容。$? 只存在于当前shell中;如果您想在子进程中使用它,则必须将其复制到环境变量中。

另一种选择是编写一个使用它的shell函数。


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 

您可以根据需要优化此脚本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接