如何设置一个通过进程替换重定向其输出的进程,以便它可以在父脚本退出后继续存在?
我正在尝试设置一个 Bash 脚本来监视进程启动时的输出,然后释放该进程,以便它可以正常继续(我想在其他脚本中调用此脚本并让它阻止进一步执行,直到启动做完了)。
现在,我正在使用该http.server
模块作为我的测试用例。下面的代码正确启动 Python 模块并检查其输出以查找请求GET
,然后退出。然而,当它退出时,该http.server
进程也会终止。我怎样才能使这个进程在 bash 退出后仍然存在?
exec 3< <(python3 -u -m http.server 2>&1 )
while true; do
read -t 2 line
echo "reading..."
echo "$line"
if [[ "$line" =~ .*GET.* ]]; then
break
fi
done <&3
我认为该进程正在死亡,因为当 bash 退出时文件描述符3
被关闭,而当 Python 看到其输出文件关闭时,它正在退出。我尝试过各种重定向3
,但没有帮助。也许需要修改该流程的其他内容才能使其生存?基本上我想要相当于执行python3 -u -m http.server 2>&1 &
,但能够在进程第一次启动时临时监视进程的输出。
答案1
从 bash 脚本中,启动一个子进程(运行 Python 程序),并创建从它到 bash 脚本的管道。
bash 脚本退出后,不再有任何进程打开管道进行读取。因此,下次 Python 脚本向管道写入内容时,它会收到 SIGPIPE 信号并终止。如果您仅将标准输出重定向到管道而不是标准错误,您将看到生成的错误。
即使Python脚本忽略了SIGPIPE信号,在写入管道时它仍然会死掉,因为写入管道会失败,这会触发异常。
如果您只想查看告诉您服务器已准备就绪的行,或者直到有关第一个请求的行,一个简单的方法是让阅读器保持运行:
exec 3< <(python3 -u -m http.server 2>&1 )
{ while true; do
…
done;
exec cat;
} <&3
您可能希望将标准错误重定向到某个位置的日志文件,而不是幸福地忽略错误消息。
另一种方法是编写几行 Python,重写BaseHTTPRequestHandler.log_request
仅在第一次发出日志条目的方法。