Rob*_*bin 14 linux ubuntu gnu-screen
我一直在寻找一种将命令发送到分离的屏幕会话的方法。到现在为止还挺好。这是我想出的:
$ screen -S test -p 0 -X stuff 'command\n'
Run Code Online (Sandbox Code Playgroud)
此命令正常工作。但是,我也想要它的输出,直接在我眼前回响(不需要.log
文件或其他东西,我只想要输出)。
使用screen -L
命令,不是一个选项。
Tho*_*erk 11
使用先进先出管道:
mkfifo /tmp/test
Run Code Online (Sandbox Code Playgroud)
使用重定向运算符。将命令的输出重定向到 /tmp/test 例如像这样:
screen -S test -p 0 -X stuff 'command >/tmp/test\n'
Run Code Online (Sandbox Code Playgroud)
然后在另一个外壳中
tail -f /tmp/test.
Run Code Online (Sandbox Code Playgroud)
请注意,您可能还想使用2>&1 运算符重定向错误消息。
例子
根据评论中的要求,让我们假设我们有一个 php 脚本接受用户输入并在“状态”的输入上打印服务器负载:
# cat test.php
<?php
$fp=fopen("php://stdin","r");
while($line=stream_get_line($fp,65535,"\n"))
{
if ($line=="status") {echo "load is stub";}
}
fclose($fp);
?>
Run Code Online (Sandbox Code Playgroud)
您创建了两个 fifo:
# mkfifo /tmp/fifoin /tmp/fifoout
Run Code Online (Sandbox Code Playgroud)
你调用一个屏幕:
screen
Run Code Online (Sandbox Code Playgroud)
在另一个控制台中,我们将其称为控制台 2,您会发现屏幕的名称:
# screen -ls
There is a screen on:
8023.pts-3.tweedleburg (Attached)
1 Socket in /var/run/screens/S-root.
Run Code Online (Sandbox Code Playgroud)
在控制台 2 中,您将命令发送到屏幕:
# screen -S 8023.pts-3.tweedleburg -p 0 -X stuff 'php test.php </tmp/fifoin >/tmp/fifoout\n'
Run Code Online (Sandbox Code Playgroud)
您会看到命令出现在屏幕上。现在在控制台 2 中,您可以向 php 进程发送命令:
echo "status" >/tmp/fifoin
Run Code Online (Sandbox Code Playgroud)
并从中阅读:
# cat /tmp/fifoout
load is stub
Run Code Online (Sandbox Code Playgroud)
我有一个 python 脚本,它跟踪许多分离的屏幕会话并捕获每个会话的输出(当像free、top -bn2、iostat这样的利用率命令通过“stuff”定期发送时)。
而不是重定向到一个文件,因此,每个分离的屏幕会话管理至少一个文件......我只是重定向到我的父会话正在使用的任何 tty/pts。
第 1 步:在分离模式下开始一个新的屏幕会话(具有人类可读的名称)。
$ screen -dmS chad
Run Code Online (Sandbox Code Playgroud)
步骤#2:通过东西发送你的命令(我将使用'free -g'命令和'uname -r')。使用 -p 指定要使用的窗口(在我们的例子中是第一个也是唯一的窗口)很重要。
$ screen -r chad -p0 -X stuff "free -g; uname -r"
Run Code Online (Sandbox Code Playgroud)
第 3 步:上述步骤仅发送命令文本。我们还需要向这个分离的屏幕会话发送一个回车,让 shell 执行我们的命令。ASCII 字符 015 是大多数 *nix 系统上的回车符。
$ screen -r chad -p0 -X eval "stuff \015"
Run Code Online (Sandbox Code Playgroud)
第 4 步:将我们分离的屏幕会话的输出重定向到我们当前的 tty/pts:
$ screen -r chad -p0 -X hardcopy $(tty)
Run Code Online (Sandbox Code Playgroud)
第 4 步的输出将如下所示:
$ free -g; uname -r
total used free shared buffers cached
Mem: 7 1 6 0 0 0
-/+ buffers/cache: 0 7
Swap: 1 0 1
2.6.32-358.el6.x86_64
Run Code Online (Sandbox Code Playgroud)
尽管这看起来有点复杂,但该过程很容易编写脚本。使用 python,我可以解析步骤 #4 的输出并只捕获我关心的数据。
选择一个简单的场景,比如抓取 IP 细节,我写了一个示例脚本来演示上面的概念。随意更换和修补你认为合适的。
从分离的屏幕会话中获取 IP 详细信息的 Python 脚本示例:
#!/usr/bin/python
import pexpect, time
#spawn a new bash session
session = pexpect.spawn('/bin/bash')
#send screen commands
session.sendline('screen -dmS netIP')
session.sendline('screen -r netIP -p0 -X stuff "ifconfig eth0 | grep -v eth0 | head -1"')
session.sendline('screen -r netIP -p0 -X eval "stuff \\015"')
#give the command a chance to execute before reading the output of our detached screen
time.sleep(0.1)
#use the output of the uname command as our string to expect
session.sendline('screen -r netIP -p0 -X hardcopy $(tty); $(uname)')
session.expect('Linux')
#parse the output - only concerned with the 'inet' line
output = session.before.split('\n')
for o in output:
if 'inet' in o:
print o
#kill the screen
session.sendline('screen -r netIP -p0 -X quit')
time.sleep(0.1)
session.close()
Run Code Online (Sandbox Code Playgroud)
上面的脚本正在运行:
$ python screen-output-test.py
inet addr:192.168.1.201 Bcast:192.168.1.255 Mask:255.255.255.0
Run Code Online (Sandbox Code Playgroud)