我在Linux上运行一个写入stdout的后台进程。
我无法在python脚本中将其作为subprocess
运行。
有没有办法使用它的PID从python脚本中捕获它的标准?在bash中使用strace -p<pid> -e write
排序。
编辑:
Queues
或Pipes
的内容。 答案 0 :(得分:1)
如何处理这个问题取决于一些细节,比如究竟谁拥有后台流程,以及你可以改变它如何开始。
如果您不拥有后台进程,则无法读取其输出,除非该进程以某种方式使其输出可用。 (想象一下,如果一个进程可以捕获其他人的进程输出......其他人的脚本将能够读取您的电子邮件阅读器或文本编辑器的控制台输出。)
即使你的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中的某些安全功能,或者我只是做得不对。
如果后台进程是完全成熟的守护进程(可疑,但有些人在说“后台进程”时会包含守护进程),它会在启动后立即完全脱离其控制终端 - 所以它赢了“通常意义上都有stdout
。如果您有权获取其/proc/${pid}/fd/0
和1
的长列表,则会看到它们是/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的nmbd
和smbd
进程做了类似的事情。