如何在 Bash 中获取通过管道传输到另一个进程的进程的 PID?
我正在尝试在 Bash 中实现一个简单的日志服务器。它应该采用一个文件作为参数,并通过 netcat 在端口上提供该文件。
( tail -f $1 & ) | nc -l -p 9977
但问题是,当 netcat 终止时,tail 仍然在运行。 (澄清:如果我不分叉 tail 进程,即使 netcat 终止,它也会继续永远运行。)
如果我以某种方式知道 tail 的 PID,那么我可以在之后杀死它。
显然,使用 $!将返回netcat的PID。
如何获取尾部进程的PID?
I am trying to implement a simple log server in Bash. It should take a file as a parameter and serve it on a port with netcat.
( tail -f $1 & ) | nc -l -p 9977
But the problem is that when the netcat terminates, tail is left behind running. (Clarification: If I don't fork the tail process it will continue to run forever even the netcat terminates.)
If I somehow know the PID of the tail then I could kill it afterwards.
Obviously, using $! will return the PID of netcat.
How can I get the PID of the tail process?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
怎么样:
%1
用于链中的第一个作业,%2
用于第二个作业,等等。jobs -x
用 PID 替换作业说明符。how about this:
%1
is for first job in chain,%2
for second, etc.jobs -x
replaces job specifier with PID.这对我有用(SLES Linux):
如果用户可以在同一台计算机上运行两个“实例”的脚本,则此线程中提到的 ps|grep|kill 技巧将不起作用。
jobs -x echo %1
对我不起作用(手册页没有-x
标志),但给了我尝试jobs -p
的想法代码>.This works for me (SLES Linux):
The
ps|grep|kill
trick mentioned in this thread would not work if a user can run the script for two "instances" on the same machine.jobs -x echo %1
did not work for me (man page not having the-x
flag) but gave me the idea to tryjobs -p
.也许你可以使用 fifo,这样你就可以捕获第一个进程的 pid,例如:
Maybe you could use a fifo, so that you can capture the pid of the first process, e.g.:
最后,我设法使用 ps 找到了尾部进程。感谢 ennukiller 的想法。
我已经使用 ps 从 args 中 grep tail 并杀死它。这是一种黑客行为,但它确实有效。 :)
如果您能找到更好的方法,请分享。
这是完整的脚本:
(最新版本可以在这里找到:http://docs.karamatli.com/dotfiles/bin/日志服务器)
Finally, I have managed to find the tail process using
ps
. Thanks to the idea from ennuikiller.I have used the
ps
to grep tail from the args and kill it. It is kind of a hack but it worked. :)If you can find a better way please share.
Here is the complete script:
(Latest version can be found here: http://docs.karamatli.com/dotfiles/bin/logserver)
ncat
在退出时自动终止tail -f
(在 Mac OS X 10.6.7 上)!ncat
automatically terminatestail -f
on exit (on Mac OS X 10.6.7)!一种方法是简单地使用脚本 ppid 执行 ps -ef 和 grep for tail
One way would be to simply do a ps -ef and grep for tail with your script ppid
您是否尝试过:(
未经测试)
或者如果您的
nc
没有-c
,则使用脚本文件使用-e
。您可能必须有一个使用GAPING_SECURITY_HOLE
选项编译的nc
。是的,您应该从该选项名称中推断出适当的警告。Have you tried:
(untested)
Or
-e
with a scriptfile if yournc
doesn't have-c
. You may have to have annc
that was compiled with theGAPING_SECURITY_HOLE
option. Yes, you should infer appropriate caveats from that option name.您可以仅使用 Bash I/O 重定向将
tail
命令的 pid 存储在变量中(请参阅 如何获取管道中进程的 PID)。You may store the pid of the
tail
command in a variable using Bash I/O redirections only (see How to get the PID of a process in a pipeline).这不是一个理想的答案,但我找到了我工作的记录器守护进程的解决方法:
来自 $info tail:
Not an ideal answer, but I found a workaround for a logger daemon I worked on:
from $info tail:
您可以使用
coproc
命令两次。给定的示例翻译为:(
我在其中抛出了一个
-v
和几个echo
来进行故障排除。)使用
coproc
感觉很多就像在其他各种脚本语言中使用 Popen() 一样。You could use the
coproc
command twice.The given example translates to:
(I've thrown a
-v
and a coupleecho
in there for troubleshooting.)Using
coproc
feels a lot like using Popen() in various other scripting languages.bobbogo 答案可以工作,但需要中间pid文件。
您可以利用进程替换功能
>()
其工作方式类似于|
但无需等待tail
完成bobbogo answer works but requires a intermediary pid file.
You can leverage the process substitution feature
>()
which works like|
but without waiting fortail
to finishtail 的 --pid 选项是你最好的朋友。它将允许您完全控制在后台运行的管道。阅读 tail 命令选项以获得更大的弹性,以防您的文件被另一个进程主动轮换,这可能会让您尾随不活动的 inode。下面的示例虽然没有用于处理数据,但演示了对尾部的“强加”限制以及告诉其随时退出的能力。用于测量 httpd 上的服务压力。
The --pid option to tail is your best friend here. It will allow you total control of the pipeline running in background. read the tail command options for more resilience in case your file is actively rotated by another process which might leave you tailing a inactive inode. The example below, though not used to process the data demonstrate the "imposed" restriction on the tail and the ability to tell it to exit at any time. This is used for measuring the service pressure on httpd .
另一种选择:使用重定向到子 shell。这会更改后台进程的启动顺序,因此 $!给出
tail
进程的 PID。Another option: use a redirect to subshell. This changes the order in which background processes are started, so $! gives PID of the
tail
process.将 tail 的 PID 写入文件描述符 3,然后从那里捕获它。
Write tail's PID to file descriptor 3, and then capture it from there.