我试图在脚本中使用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 $!
也许有一种方法可以处理进程(使用fg
、bg
…(,但我仍然没有弄清楚。
类似的问题:
[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
控件进一步扩展它,如果进程没有按你想要的方式结束,就可以终止它。