我使用 --tmux 启动 GNU Parallel,这将为每个作业启动一个 tmux 窗口。
我想将所有窗口加入为窗格,其大小在它们之间很好地分布(如平铺视图:Cb M-5)。
我尝试这样做:
seq 15 | parallel tmux -S /tmp/tmsF8j3K joinp -s {} -t 1
但它没有均匀分布高度,导致:
create pane failed: pane too small
有没有办法告诉窗口在 ing 时均匀分布高度joinp
,或者将所有窗口连接为窗格然后平铺它们?也许有什么用select-layout tiled
?
编辑
我用它作为测试程序:
seq 1000 | parallel --jobs 9 --tmux sleep
目标是在连接到 tmux 时,在一个漂亮的 3x3 窗口中显示 9 个正在运行的作业。当一项工作消亡时,它应该被下一项工作取代。
我努力了:
while [ -e "$SERVER" ] ; do
top=$(tmux -S $SERVER new-window -P -n all)
tmux -S $SERVER list-panes -a | grep -v "^$top" | cut -d':' -f1-2 |
while read p ; do
tmux -S $SERVER joinp -s $p -t $top
tmux -S $SERVER select-layout tiled
done
tmux -S $SERVER kill-pane -t $top
tmux -S $SERVER select-layout tiled
sleep 1
done
但它仍然给出:
can't find pane X
并且在附加时它不会将所有窗口保留为第一个窗口中的窗格。
答案1
您可以扩展作业命令,以便它在启动时移动自己的窗格,而不是运行单独的命令(可能在循环中)来在创建窗格后移动它们:
seq 1000 |
parallel --jobs 9 --tmux tmux joinp -t :0 \; \
tmux select-layout -t :0 tiled \; \
sleep
arranging in: tiled
这将在每个窗格中显示其他 tmux 命令(以及它们的输出)。为了避免这种情况,您可以编写一个包装脚本,例如。
#!/bin/sh
# move into the pane set
tmux joinp -t :0
tmux select-layout -t :0 tiled >/dev/null
# start the real task
sleep "$@"
然后运行
seq 1000 | parallel --tmux --jobs 9 /path/to/wrapper.sh
答案2
您的select-layout
建议是正确的,但需要在创建每个新窗格后调用。所有窗格都会立即重新组织,因此(在我的测试中 - 95x58 终端)有足够的空间进行下一次分割。
为了避免出现该can't join a pane to its own window
消息,可以创建一个附加窗口,然后将所有现有窗口移动到该窗口中,并在最后终止附加窗格。 parallel
不是合适的工具 - 你最好查询正在运行的窗口,并循环移动每个窗口:
top=$(tmux -S $SERVER new-window -P -n all)
tmux -S $SERVER list-panes -a | grep -v "^$top" | grep -o "%[0-9]\+\>" |
while read p ; do
tmux -S $SERVER joinp -s $p -t $top
tmux -S $SERVER select-layout tiled
done
tmux -S $SERVER kill-pane -t $top
tmux -S $SERVER select-layout tiled
或者,您可以将每个新窗格设置为 1 行高,并使用joinp -l 1
.根据终端的大小,这可能只需要select-layout
最后一个就足够了。
但是,parallel
不会跟踪现有tmux
窗口/窗格,而只是在新窗口中启动每个作业。旧的可能会消失,具体取决于退出时保持不变环境。因此,一段时间后,原始窗口(在窗格中显示每个作业)将不包含正在运行的作业,并且所有新作业将再次出现在它们自己的窗口中。您必须重新运行脚本才能将所有窗口(以及任何旧窗格)再次移至单个窗口中。