发送命令到分离的屏幕并获取输出


12

我一直在寻找一种将命令发送到独立屏幕会话的方法。到目前为止,一切都很好。这是我想出的:

$ screen -S test -p 0 -X stuff 'command\n'

该命令可以正常工作。但是,我也希望它的输出在我眼前回荡(不需要.log文件或其他东西,我只想要输出)。

不能使用该screen -L命令。


为什么必须如此screen?这不是为了子进程吗?
Anko 2014年

Answers:


10

使用先进先出管道:

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

1
抱歉,但这不起作用。如果我要向creen发送命令,例如“命令> / tmp / test”,则该过程必须支持> / tmp / test语法...而事实并非如此。
罗宾

对于我来说,它可以正常工作,请注意,我将“ test”作为屏幕的名称。您可以使用命令screen -ls查找屏幕名称。另外,我用命令ls测试了“命令”,然后用您的实际命令替换了。另外,我使用bash shell进行了测试。
Thorsten Staerk,2014年

我知道。而且它不起作用。例如,在屏幕窗口中启动PHP脚本,该脚本例如响应命令“状态”,该命令例如返回当前服务器负载。那就是我想做的。
罗宾

那么您将需要双向管道,我将其添加到我的答案中
Thorsten Staerk 2014年

6

我有一个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

我喜欢这个答案比接受的答案好得多,因为它不依赖于屏幕处于“ shell提示”状态,而是可以与该屏幕上运行的任何内容一起使用。
Guntram Blohm支持Monica19

但是,它要求输出适合屏幕显示。我发现screen -X logfile /tmp/something; screen -X log on; screen -X stuff "command param"; screen -X log off在这种情况下可以更好地工作。
Guntram Blohm支持Monica19

-1
screen -S myscreen

screen -R myscreen -X exec command

例:

screen -R myscreen -X exec top
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.