Answers:
使用先进先出管道:
mkfifo /tmp/test
使用重定向运算符。例如,将命令的输出重定向到/ tmp / test,例如:
screen -S test -p 0 -X stuff 'command >/tmp/test\n'
然后在另一个外壳
tail -f /tmp/test.
请注意,您可能还想使用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);
?>
您创建两个fifos:
# mkfifo /tmp/fifoin /tmp/fifoout
您调用一个屏幕:
screen
在另一个控制台中,我们将其称为控制台2,您可以找到屏幕名称:
# screen -ls
There is a screen on:
8023.pts-3.tweedleburg (Attached)
1 Socket in /var/run/screens/S-root.
在控制台2中,将命令发送到屏幕:
# screen -S 8023.pts-3.tweedleburg -p 0 -X stuff 'php test.php </tmp/fifoin >/tmp/fifoout\n'
您会看到命令出现在屏幕上。现在在控制台2中,您可以将命令发送到php进程:
echo "status" >/tmp/fifoin
并从中读取:
# cat /tmp/fifoout
load is stub
我有一个python脚本,可以跟踪多个分离的屏幕会话并捕获每个会话的输出(当通过“材料”定期发送诸如free,top -bn2,iostat之类的利用率命令时)。
而不是重定向到文件,因此,每个分离的屏幕会话至少要管理一个文件 ……我只是重定向到我的父会话正在使用的tty / pts。
步骤#1:以分离模式启动新的屏幕会话(使用易于理解的名称)。
$ screen -dmS chad
步骤2:通过资料发送命令(我将使用“ free -g”命令和“ uname -r”)。重要的是,用-p指定要使用的窗口(在本例中,是第一个也是唯一的窗口)。
$ screen -r chad -p0 -X stuff "free -g; uname -r"
步骤#3:以上步骤仅发送命令文本。我们还需要向该分离的屏幕会话发送回车符,以使Shell执行我们的命令。在大多数* nix系统上,ASCII字符015是回车符。
$ screen -r chad -p0 -X eval "stuff \015"
步骤#4:将我们的分离屏幕会话的输出重定向到当前的tty / pts:
$ screen -r chad -p0 -X hardcopy $(tty)
步骤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
尽管这似乎有点涉及,但是该过程很容易编写脚本。使用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()
上面的脚本在起作用:
$ python screen-output-test.py
inet addr:192.168.1.201 Bcast:192.168.1.255 Mask:255.255.255.0
screen -X logfile /tmp/something
; screen -X log on
; screen -X stuff "command param"
; screen -X log off
在这种情况下可以更好地工作。
screen
?这不是为了子进程吗?