在新的后台tmux窗口中运行命令,等待进程完成



我试图在脚本中使用tmux,这样它就可以在一个新的隐藏窗格中运行一个需要一些时间的命令(例如"ping-c 5 8.8.8.8"(,同时阻塞当前脚本本身,直到ping结束。

所谓"隐藏窗格",我的意思是在一个新窗格中运行命令,该窗格将在后台发送,并且仍然可以通过切换窗格进行访问,以便监视和/或与之交互(不一定是ping(
(参见EDIT(

下面是一些伪bash代码,可以更清楚地显示我要做的事情:

echo "Waiting for ping to finish..."
echo "Ctrl-b + p to switch pane and see running process"
tmux new-window -d 'ping -c 5 8.8.8.8' # run command in new "background" window
tmux wait-for                          # display "Done!" only when ping command has finished
echo "Done!"

我知道这里的tmux命令实际上没有任何意义,但这只是为了说明。

我已经研究了不同的解决方案,以便在后台发送命令,或者在另一个窗格中等待进程完成,但我仍然没有找到正确的方法。

编辑

感谢Nicholas Marriott指出,在创建新窗口时存在-d选项,以避免自动切换到该选项。现在唯一的问题是阻塞主脚本,直到命令结束。

我尝试了以下方法,希望它能起作用,但也不行(脚本没有恢复(。

tmux new-window -d 'ping -c 5 8.8.8.8; tmux wait -S ping' &
tmux wait $!

也许有一种方法可以处理进程(使用fgbg…(,但我仍然没有弄清楚。

类似的问题:
[1]使tmux阻塞直到程序完成
[2]Bash-在tmux中执行阻塞脚本
[3]如何隐藏tmux窗格
[4]如何等待第一个命令完成?

您可以使用wait-for,但您需要给它一个通道,并在流程完成时发出该通道的信号,例如:

tmux neww -d 'ping blah; tmux wait -S ping'
tmux wait ping
echo done

如果您认为可以并行运行该脚本几次,我建议使用mktemp或类似的方法创建一个通道名称(并在wait-for返回时删除该文件(。

wait-for不能自动等待窗格或窗口退出、窗格中的静音等等,但我希望在某个时候实现这一点。

只有当您已经在tmux会话中时,其他答案才有效。但如果你在它之外,你必须使用这样的东西:

tmux new-session -d 'vi /etc/passwd' ; split-window -d 'vi /etc/group' ; attach

如果你想在脚本中调用它,你应该检查是否"$TMUX";已设置。(或者只是取消设置以强制使用嵌套的tmux窗口(。

#!/bin/sh
export com1="vi /etc/passwd"
export com2="vi /etc/group"
if [ -z $TMUX ]
then
export doNewSession="new-session -d 'exit 0'"
else
export doNewSession=""
fi
tmux $doNewSession ; split-window -d $com1 ; split-window -d $com2 ; attach;
[ -z $TMUX ] && exit 0

我的解决方案是制作一个命名管道,然后使用read:等待输入

#!/bin/sh 
rm -f /wait
mkfifo /wait
tmux new-window -d '/bin/sh -c "ping -c 5 8.8.8.8; echo . > /wait"'
read -t 10 WAIT <>/wait
[ -z "$WAIT" ] && 
echo 'The operation failed to complete within 10 seconds.' ||
echo 'Operation completed successfully.'

我喜欢这种方法,因为你可以设置一个超时,如果你愿意,你可以用其他tmux控件进一步扩展它,如果进程没有按你想要的方式结束,就可以终止它。

最新更新