![如何在屏幕内运行命令以便可以返回该命令的父 shell?](https://linux22.com/image/42149/%E5%A6%82%E4%BD%95%E5%9C%A8%E5%B1%8F%E5%B9%95%E5%86%85%E8%BF%90%E8%A1%8C%E5%91%BD%E4%BB%A4%E4%BB%A5%E4%BE%BF%E5%8F%AF%E4%BB%A5%E8%BF%94%E5%9B%9E%E8%AF%A5%E5%91%BD%E4%BB%A4%E7%9A%84%E7%88%B6%20shell%EF%BC%9F.png)
在屏幕会话中运行命令以便可以访问其父 shell 的最佳方法是什么?我希望能够从同一屏幕会话中重新启动它。
我想出的最好的办法如下:
$ cat mr-t.sh
#!/bin/bash
top
exec /bin/bash
进而:
screen -e'^\\\' -S top-in-screen ./mr-t.sh
然后,如果 top 停止运行,我至少会在可以使用的同一屏幕会话中获得一个新的 shell。不过,这不是很优雅,而且我无法完全说服自己,如果我按抄送,信号将可靠地发送到正确的进程。而且,Cz根本不起作用。
我在 OSX 上使用 bash 3.2.48,在 Linux 上使用 bash 3.2.39。两者都可能由操作系统供应商修补。
top
当然,这里的命令没有什么特别的。
[顺便说一句,-e'^\\\'
将 Magick 屏幕键从 Ca(如果有的话,这是一个糟糕的默认值)重新分配给 C-\。]
答案1
创建一个~/.screenrc.top
像这样:
screen
stuff "top\015"
现在运行screen -c ~/.screenrc.top
。没有比赛条件!
答案2
这是我发现的一个不完美的解决方案。
screen -e'^\\\' -dmS top-in-screen
然后你可以运行:
screen -S top-in-screen -p 0 -X stuff 'top^M'
(请注意,虽然您只会看到^M
您实际上应该键入,C-v
然后立即键入C-m
。)
它是不完美的,因为(我认为)屏幕的第一次和第二次调用之间存在竞争条件。
从http://aperiodic.net/screen/faq#how_to_send_a_command_to_a_window_in_a_running_screen_session_from_the_commandline,其中还有很多其他有用的信息。
答案3
自从提出这个问题以来,我采用了一种不同但更有效的解决方案:使用tmux。
启动一个新的命名的、分离的会话:
$ tmux new -d -s top
向其第 0 个窗口发送命令。
$ tmux send-keys -t top:0 "top" C-m
C-m
相当于按回车键。很多时候,这就是你想要的;有时你会想把它忽略掉。
tmux 的命令集有详细记录。因此很容易编写更复杂的脚本来驱动它。
通常这将是一个非常令人讨厌的答案,但由于这是我的问题,我会给自己一些余地,特别是因为我从未真正得到任何其他方法可靠地工作。相比之下,我第一次尝试就能够正确编写 tmux 脚本。