外部プロセスから既存のプロセスのSTDIN
にデータを書き込む方法を探していて、同様の質問が見つかりました Pythonのさまざまなローカル/リモートプロセスからプログラムのSTDINにデータをストリーミングする方法? スタックオーバーロー。
そのスレッドで、@ Michaelは以下のようなパスで既存のプロセスのファイル記述子を取得でき、Linuxでそれらにデータを書き込むことが許可されていると言います。
_/proc/$PID/fd/
_
そこで、以下の簡単なスクリプトを作成して、外部プロセスからスクリプトのSTDIN
(およびTTY
)へのデータの書き込みをテストしました。
_#!/usr/bin/env python
import os, sys
def get_ttyname():
for f in sys.stdin, sys.stdout, sys.stderr:
if f.isatty():
return os.ttyname(f.fileno())
return None
if __name__ == "__main__":
print("Try commands below")
print("$ echo 'foobar' > {0}".format(get_ttyname()))
print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid()))
print("read :: [" + sys.stdin.readline() + "]")
_
このテストスクリプトは、STDIN
とTTY
のパスを表示し、STDIN
が書き込まれるのを待ちます。
このスクリプトを起動して、以下のメッセージを受け取りました。
_Try commands below
$ echo 'foobar' > /dev/pts/6
$ echo 'foobar' > /proc/3308/fd/0
_
そのため、他の端末から_echo 'foobar' > /dev/pts/6
_および_echo 'foobar' > /proc/3308/fd/0
_コマンドを実行しました。両方のコマンドを実行した後、メッセージfoobar
がテストスクリプトが実行されているターミナルに2回表示されますが、それだけです。行print("read :: [" + sys.stdin.readline() + "]")
は実行されませんでした。
外部プロセスから既存のプロセスのSTDIN
(または他のファイル記述子)にデータを書き込む、つまり他のプロセスからlineprint("read :: [" + sys.stdin.readline() + "]")
の実行を呼び出す方法はありますか?
コードは機能しません。/proc/pid/fd/0
は/dev/pts/6
ファイルへのリンクです。
$ echo 'foobar'>/dev/pts/6
$ echo 'foobar'>/proc/pid/fd/0
どちらのコマンドも端末に書き込むため。この入力は、プロセスではなく端末に送られます。
Stdinが最初はパイプである場合に機能します。
たとえば、test.py
は:
#!/usr/bin/python
import os, sys
if __name__ == "__main__":
print("Try commands below")
print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid()))
while True:
print("read :: [" + sys.stdin.readline() + "]")
pass
これを次のように実行します。
$ (while [ 1 ]; do sleep 1; done) | python test.py
別の端末から何かを/proc/pid/fd/0
に書き込むと、test.py
に送信されます
ここで、私が役に立ったと思う例を残したいと思います。それは、私のマシンで断続的に失敗した上記の真のトリックのわずかな変更です。
# pipe cat to your long running process
( cat ) | ./your_server &
server_pid=$!
# send an echo to your cat process that will close cat and in my hypothetical case the server too
echo "quit\n" > "/proc/$server_pid/fd/0"
特定の理由でmkfifo
を使用できなかったので、このシナリオに最適でした。