我正在努力增强我的通知脚本。脚本的工作方式是我把它放在一个长时间运行的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是zsh
,但我希望它也适用于bash
。
答案 0 :(得分:39)
您真的需要使用shell函数才能实现这一目标。对于像这样的简单脚本,它应该很容易让它在zsh和bash中工作。只需将以下内容放在文件中:
my_notify() {
echo "exit code: $?"
echo "PPID: $PPID"
}
然后从shell启动文件中获取该文件。虽然这可以从您的交互式shell中运行,但您可能希望使用$$而不是$ PPID。
答案 1 :(得分:6)
这是不相容的。当前shell中只存在$?
;如果您希望它在子进程中可用,则必须将其复制到环境变量。
另一种方法是编写一个以某种方式使用它的shell函数。
答案 2 :(得分:2)
实现此目的的一种方法可能是使用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
您可以为您的目的优化此脚本。