( cmdpid=$BASHPID; (sleep 3; kill $cmdpid) & exec ./myscript )
这是有效的,但我不知道如何抑制终止消息
line 80: 30631 Terminated
( cmdpid=$BASHPID; ( sleep 3; kill $cmdpid 2> /dev/null 0<&1 2>&1 ) & exec .....
我试图重定向但没有成功。任何的想法?感谢
答案 0 :(得分:1)
我以其他方式解决了自己,我想分享......也许将来会有人需要。 这将允许./script以超时执行并捕获其输出,包括错误。
我无法解决的一个小缺点是,如果发生任何事件(如超时或其他错误),请以任何其他方式发出主$ shell信号,而不是将结果附加到$ OUT with echo。我想这是bash编程中最愚蠢的部分(在大多数其他编程中),每个()构造它自己的pid和isolate变量。无论如何,请尽情享受。
OUT=$((./script) & pid=$!
# will exit 128 + (signal number)
(sleep $RUN_TIMEOUT && kill -HUP $pid) 2>/dev/null & watcher=$!
if wait $pid; status=$?; then
if [[ $status -eq 129 ]]; then # 129 -> OK (hangup, means timeout)
echo "execution_timeout"
else
# other, including 255 -> return error
echo "execution_error"
fi
fi # 0 -> normal return, success
pkill -HUP -P $watcher
wait $watcher
) 2>&1 # + stderr
答案 1 :(得分:0)
该消息显然来自shell的作业控制功能。在父 shell中禁用它似乎有效:
set +m
( cmdpid=$BASHPID; (sleep 3; kill $cmdpid) & exec ./myscript )
消息不是来自kill
,而是来自执行kill
的后台子shell。尝试
( cmdpid=$BASHPID; (sleep 3; kill $cmdpid) 2> /dev/null & exec ./myscript )
其他尝试:
( set +m; cmdpid=$BASHPID; (sleep 3; kill $cmdpid) & sleep 5 )
( cmdpid=$BASHPID; (sleep 3; kill $cmdpid); disown %% & sleep 5 )
( cmdpid=$BASHPID; (sleep 3; kill $cmdpid); disown %1 & sleep 5 )
(我使用sleep 5
作为执行官的替身。唯一明显的区别是我只看到“终止”这个词作为通知。)
答案 2 :(得分:0)
更简单的解决方案(取决于您的平台)可能是使用timeout
命令。
$ /usr/bin/timeout 30 /path/to/exec
这将在30秒后停止进程/path/to/exec
。
如果我使用timeout 2>/dev/null 1 sleep 2
,我会收到“已杀死”回复。这可能与您使用方法的位置相同......
答案 3 :(得分:0)
如果您使用命令超时可用的Linux,则可以按如下方式实现:
timeout --foreground <time in seconds> <command>
从手册页开始:
--foreground
when not running timeout directly from a shell prompt,
allow COMMAND to read from the TTY and get TTY signals; in this mode, children of COMMAND will not be timed out
它还会抑制“终止”/“被杀”的消息。