回答:
先入れ先出しパイプを使用します。
mkfifo /tmp/test
リダイレクト演算子を使用します。次の例のように、コマンドの出力を/ tmp / testにリダイレクトします。
screen -S test -p 0 -X stuff 'command >/tmp/test\n'
その後、別のシェルで
tail -f /tmp/test.
2>&1演算子を使用してエラーメッセージをリダイレクトすることもできます。
例
コメントで要求されているように、ユーザー入力を受け入れ、「status」の入力でサーバー負荷を出力する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、top -bn2、iostatなどの使用率コマンドが 'stuff'を介して定期的に送信される場合)。
ファイルにリダイレクトするのではなく、したがって、デタッチされたスクリーンセッションごとに少なくとも1つのファイルを管理します ...私は単に、親セッションが使用しているtty / ptsにリダイレクトします。
ステップ#1:デタッチモードで新しいスクリーンセッションを(人間が読める名前で)開始します。
$ screen -dmS chad
ステップ#2:スタッフを介してコマンドを送信します(「uname -r」とともに「free -g」コマンドを使用します)。使用するウィンドウ(この場合、最初で唯一のウィンドウ)を-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の詳細を取得するような単純なシナリオを選択して、上記の概念を示すスクリプト例を作成しました。交換し、必要に応じて調整してください。
デタッチスクリーンセッションから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
ですか?これは子プロセスの目的ではありませんか?