如何获取通过管道传输到 Bash 中另一个进程的进程的 PID?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1652680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the PID of a process that is piped to another process in Bash?
提问by Ertu? Karamatl?
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.
我正在尝试在 Bash 中实现一个简单的日志服务器。它应该将一个文件作为参数并通过 netcat 在端口上提供它。
( tail -f & ) | 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.)
但问题是当 netcat 终止时,tail 会留在后面运行。(澄清:如果我不 fork 尾部进程,即使 netcat 终止,它也将永远运行。)
If I somehow know the PID of the tail then I could kill it afterwards.
Obviously, using $! will return the PID of netcat.
如果我以某种方式知道尾部的 PID,那么我可以在之后杀死它。
显然,使用 $! 将返回netcat的PID。
How can I get the PID of the tail process?
如何获得尾部进程的PID?
采纳答案by bobbogo
Write tail's PID to file descriptor 3, and then capture it from there.
将 tail 的 PID 写入文件描述符 3,然后从那里捕获它。
( tail -f & echo $! >&3 ) 3>pid | nc -l -p 9977
kill $(<pid)
回答by VladV
Another option: use a redirect to subshell. This changes the order in which background processes are started, so $! gives PID of the tail
process.
另一种选择:使用重定向到子shell。这会改变后台进程启动的顺序,所以 $! 给出tail
进程的PID 。
tail -f > >(nc -l -p 9977) &
wait $!
回答by przemas
how about this:
这个怎么样:
jobs -x echo %1
%1
is for first job in chain, %2
for second, etc. jobs -x
replaces job specifier with PID.
%1
用于链中的第一个作业,%2
用于第二个等jobs -x
。用 PID 替换作业说明符。
回答by James Shau
This works for me (SLES Linux):
这对我有用(SLES Linux):
tail -F xxxx | tee -a yyyy &
export TAIL_PID=`jobs -p`
# export TEE_PID="$!"
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.
ps|grep|kill
如果用户可以在同一台机器上为两个“实例”运行脚本,则此线程中提到的技巧将不起作用。
jobs -x echo %1
did not work for me (man page not having the -x
flag) but gave me the idea to try jobs -p
.
jobs -x echo %1
对我不起作用(手册页没有-x
标志)但给了我尝试的想法jobs -p
。
回答by martin clayton
回答by pjil
ncat
automatically terminates tail -f
on exit (on Mac OS X 10.6.7)!
ncat
tail -f
退出时自动终止(在 Mac OS X 10.6.7 上)!
# simple log server in Bash using ncat
# cf. http://nmap.org/ncat/
touch file.log
ncat -l 9977 -c "tail -f file.log" </dev/null # terminal window 1
ncat localhost 9977 </dev/null # terminal window 2
echo hello > file.log # terminal window 3
回答by Ertu? Karamatl?
Finally, I have managed to find the tail process using ps
. Thanks to the idea from ennuikiller.
最后,我设法使用ps
. 感谢 ennukiller 的想法。
I have used the ps
to grep tail from the args and kill it. It is kind of a hack but it worked. :)
我已经使用了ps
从 args 中 grep tail 并杀死它。这有点像黑客,但它奏效了。:)
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)
这是完整的脚本:(
最新版本可以在这里找到:http: //docs.karamatli.com/dotfiles/bin/logserver)
if [ -z "" ]; then
echo Usage: coproc TAIL { tail -f ; }; exec {TAIL[1]}<&-
coproc NC { nc -v -l -p 9977; } <&"${TAIL[0]}" >&1
wait $NC_PID; echo "nc exit code: $!"
kill $TAIL_PID; echo "done"
LOGFILE [PORT]
exit -1
fi
if [ -n "" ]; then
PORT=
else
PORT=9977
fi
TAIL_CMD="tail -f "
function kill_tail {
# find and kill the tail process that is detached from the current process
TAIL_PID=$(/bin/ps -eo pid,args | grep "$TAIL_CMD" | grep -v grep | awk '{ print }')
kill $TAIL_PID
}
trap "kill_tail; exit 0" SIGINT SIGTERM
while true; do
( $TAIL_CMD & ) | nc -l -p $PORT -vvv
kill_tail
done
回答by pipe_of_sharks
You could use the coproc
command twice.
您可以使用该coproc
命令两次。
The given example translates to:
给定的示例转换为:
# terminal window 1
# using nc on Mac OS X (FreeBSD nc)
: > /tmp/foo
PID=$( { { tail -f /tmp/foo 0<&4 & echo $! >&3 ; } 4<&0 | { nc -l 9977 ;} & } 3>&1 | head -1 )
kill $PID
# terminal window 2
nc localhost 9977
# terminal window 3
echo line > /tmp/foo
(I've thrown a -v
and a couple echo
in there for troubleshooting.)
(我已经在那里扔了-v
一对夫妇echo
进行故障排除。)
Using coproc
feels a lot like using Popen() in various other scripting languages.
使用coproc
感觉很像在其他各种脚本语言中使用 Popen() 。
回答by chad
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).
您可以tail
仅使用 Bash I/O 重定向将命令的 pid 存储在变量中(请参阅如何获取管道中进程的 PID)。
nc -l -p 9977 -c "tail -f "
回答by Paused until further notice.
Have you tried:
你有没有尝试过:
##代码##(untested)
(未经测试)
Or -e
with a scriptfile if your nc
doesn't have -c
. You may have to have an nc
that was compiled with the GAPING_SECURITY_HOLE
option. Yes, you should infer appropriate caveats from that option name.
或者-e
如果你nc
没有-c
. 您可能必须有一个nc
使用该GAPING_SECURITY_HOLE
选项编译的。是的,您应该从该选项名称中推断出适当的警告。