我需要在后台运行一些(未知的)命令,如下所示:
nohup some_command &
由于这样的命令将在后台运行并(希望)完成,我无法立即获取其退出状态;没关系。
但是,我需要获得“错误”退出状态立即地如果some_command
未找到(即,当来自 bash 的错误消息为No such file or directory
或 时command not found
)。
我可以使用的最短、最简单的解决方法是什么?
评论中提出的问题的一些背景信息:这是一个与用户交互的 GUI“前端”程序。用户输入一些命令(例如gedit some_file
),我的 GUI 程序执行此命令并立即返回循环以接受用户的下一个命令。因此,输入的命令应该与 GUI 程序“分离”运行。但是,如果用户输入了一些错误的命令(例如),geditxyz
我想立即提醒用户未找到该命令。
答案1
由于这样的命令将在后台运行并(希望)完成,我无法获取其退出状态;没关系。
这种说法从一开始就是错误的:
#!/bin/bash
some_command &
pid="$!"
wait -n "$pid"
echo "Status was ${?}."
如果您想立即收到通知,可以使用一些基于信号的技巧。
处理SIGCHLD
将是最明显的选择,但(1)它在 Bash 中的支持有缺陷(2)尽管如此set -b
,trap
处理程序实际上仍会等待命令边界。
也就是说,下一个最佳选择(也会中断长时间运行的前台处理立即地当some_command
失败时)相当于为整个进程组生成 Ctrl+C。该命令会立即发送并执行,如果需要,shell 本身可以处理信号并继续,而前台进程可能会默认退出等。
#!/bin/bash
set -e
handler() {
echo 'command failure signalled'
trap - INT
}
trap handler INT
background() {
local -ir pid="$1"
shift
"$@" || kill -INT -- -"$pid"
}
background "$$" some_command &
# long-running foreground task
echo 'before long processing'
sleep 5 || echo 'long processing interrupted'
echo 'after long processing'
some_command
尝试用(例如)替换sleep 2
来测试“成功”的情况。