使用Python使用Python捕获Linux进程的stdout

时间:2016-05-31 00:30:26

标签: python linux process

我在Linux上运行一个写入stdout的后台进程。 我无法在python脚本中将其作为subprocess运行。

有没有办法使用它的PID从python脚本中捕获它的标准?在bash中使用strace -p<pid> -e write排序。

编辑:

  • 我正在寻找类似python QueuesPipes的内容。
  • 我想避免更改后台进程的调用方式(例如将stdout转发到管道/文件)。
  • 后台进程和python脚本都将由同一个用户启动。

1 个答案:

答案 0 :(得分:1)

如何处理这个问题取决于一些细节,比如究竟谁拥有后台流程,以及你可以改变它如何开始。

案例1:不是您的后台流程

如果您不拥有后台进程,则无法读取其输出,除非该进程以某种方式使其输出可用。 (想象一下,如果一个进程可以捕获其他人的进程输出......其他人的脚本将能够读取您的电子邮件阅读器或文本编辑器的控制台输出。)

案例2:您的后台流程

即使你的Python脚本将由运行后台进程的同一个用户运行,调用者在启动后使用其文件描述符也为时已晚。你最好让后台进程首先将它的输出发送到你想要的地方 - 或者通过重定向它的标准输出,或者通过重写进程来记录到文件。

选项:使用tee

拆分标准输出

如果其他内容依赖于后台进程的标准输出,则可以通过tee管道输出,这将在文件中保存其所有输入的副本,然后将该输入重复为标准输出。

$ cat out.txt
cat: out.txt: No such file or directory
$ echo "This is a test." | tee out.txt | wc
      1       4      16
$ cat out.txt
This is a test.

使用tee -a <filename>附加到文件而不是覆盖它。

选项:/proc/文件系统技巧

Manuel Jacob's comment中所述,您可以尝试阅读/proc/${bg_process_pid}/fd/1。我对/proc/文件描述符符号链接的有限经验是他们很少做你想要的,但我只是尝试从命令行。

充其量,我可以在正确的终端窗口中显示字符,但它们不会被捕获为输出(也不会被视为某些子进程的输入)。我不确定这是bash还是/dev/pts/${some_number}伪终端干扰我试图做的事情,Linux中的某些安全功能,或者我只是做得不对。

案例3:守护进程

如果后台进程是完全成熟的守护进程(可疑,但有些人在说“后台进程”时会包含守护进程),它会在启动后立即完全脱离其控制终端 - 所以它赢了“通常意义上都有stdout。如果您有权获取其/proc/${pid}/fd/01的长列表,则会看到它们是/dev/null的符号链接。

我发现了一些似乎将stderr重定向到文件的服务器进程,但是他们的系统启动脚本没有这样做。我怀疑开放文件描述符2实际上是由守护进程明确打开的,只是重复使用数字2。

以下是旧版Fedora Linux服务器上Apache httpd守护程序的示例:

# ls -l /proc/1408/fd/[012]
lr-x------.  ...  /proc/1408/fd/0 -> /dev/null
l-wx------.  ...  /proc/1408/fd/1 -> /dev/null
l-wx------.  ...  /proc/1408/fd/2 -> /var/log/httpd/error_log

Samba的nmbdsmbd进程做了类似的事情。