私は、切り離された画面セッションにコマンドを送信する方法を見つけるために検索してきました。ここまでは順調ですね。これは私が思いついたものです:
$ screen -S test -p 0 -X stuff 'command\n'
このコマンドは正常に機能します。しかし、私もそこからの出力を望んでいます。目の前に直接エコーします(.log
ファイルなどは必要ありません。出力が必要です)。
screen -L
コマンドの使用はオプションではありません。
先入れ先出しのパイプを使用します。
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);
?>
2つのfifoを作成します。
# 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のような使用率コマンドを使用した場合、free、top -bn2、iostat 'stuff'を介して定期的に送信されます)。
ファイルにリダイレクトする代わりに、切り離されたスクリーンセッションごとに少なくとも1つのファイルを管理する代わりに...親のtty/ptsにリダイレクトするだけですセッションが使用しています。
ステップ#1:デタッチモードで新しい画面セッションを(人間が読める名前で)開始します。
$ screen -dmS chad
ステップ#2:コマンドを介してコマンドを送信します( 'free -g'コマンドと 'uname -r'を併用します)。 -pを使用して、使用するウィンドウ(この場合は、最初で唯一のウィンドウ)を指定することが重要です。
$ screen -r chad -p0 -X stuff "free -g; uname -r"
ステップ#3:上記のステップでは、コマンドテキストのみが送信されます。また、シェルにコマンドを実行させるには、この切り離されたスクリーンセッションにキャリッジリターンを送信する必要があります。 ASCII文字015は、ほとんどの* nixシステムではキャリッジリターンです。
$ 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の詳細を取得するような単純なシナリオを選択して、上記の概念を説明するためのサンプルスクリプトを書きました。必要に応じて、交換したり、いじったりしてください。
例pythonデタッチスクリーンセッションからIP詳細を取得するスクリプト:
#!/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