如何获取一个进程的PID到Bash中的另一个进程?

我正在试图在Bash中实现一个简单的日志服务器。 它应该把一个文件作为参数,并通过netcat在一个端口上提供。

( tail -f $1 & ) | nc -l -p 9977 

但是问题是,当netcat终止时,尾部被遗忘运行。 (澄清:如果我不分叉尾部进程,它将继续运行,即使netcat终止。)

如果我以某种方式知道尾巴的PID,那么我可以在之后杀死它。
显然,使用$! 将返回netcat的PID。

我怎样才能得到尾部进程的PID?

将尾部的PID写入文件描述符3,然后从那里捕获。

 ( tail -f $1 & echo $! >&3 ) 3>pid | nc -l -p 9977 kill $(<pid) 

另一个select:使用redirect到subshel​​l。 这改变了后台进程开始的顺序,所以$! 给出tail过程的PID。

 tail -f $1 > >(nc -l -p 9977) & wait $! 

这个怎么样:

 jobs -x echo %1 

%1代表链中的第一份工作, %2代表第二份等等。 jobs -x用PID代替作业说明符。

这适用于我(SLES Linux):

 tail -F xxxx | tee -a yyyy & export TAIL_PID=`jobs -p` # export TEE_PID="$!" 

如果用户可以在同一台机器上运行两个“实例”的脚本,则此线程中提到的ps|grep|kill技巧将不起作用。

jobs -x echo %1没有为我工作(手册页没有-x标志),但给了我想法尝试jobs -p

也许你可以使用fifo ,这样你可以捕获第一个进程的pid,例如:

 FIFO=my_fifo rm -f $FIFO mkfifo $FIFO tail -f $1 > $FIFO & TAIL_PID=$! cat $FIFO | nc -l -p 9977 kill $TAIL_PID rm -f $FIFO 

最后,我设法使用psfind了尾部进程。 感谢ennuikiller的想法。

我已经用ps从greg尾巴,并杀死它。 这是一种黑客,但它的工作。 🙂

如果你能find更好的方式,请分享。

这是完整的脚本:
(最新版本可以在这里find: http : //docs.karamatli.com/dotfiles/bin/logserver )

 if [ -z "$1" ]; then echo Usage: $0 LOGFILE [PORT] exit -1 fi if [ -n "$2" ]; then PORT=$2 else PORT=9977 fi TAIL_CMD="tail -f $1" 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 $1 }') kill $TAIL_PID } trap "kill_tail; exit 0" SIGINT SIGTERM while true; do ( $TAIL_CMD & ) | nc -l -p $PORT -vvv kill_tail done 

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 

一种方法是简单地用你的脚本ppid做一个ps -ef和grep

你有没有尝试过:

 nc -l -p 9977 -c "tail -f $1" 

(另)

或者如果您的nc没有-c ,则使用脚本文件。 您可能需要使用GAPING_SECURITY_HOLE选项编译的nc 。 是的,你应该从该选项名称推断适当的警告。

您可以使用Bash I / Oredirect将tail命令的pid存储在一个variables中(请参阅如何获取stream水线中进程的PID )。

 # 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 

不是一个理想的答案,但我find了一个解决scheme,我工作的logging器守护进程:

 #!/bin/sh tail -f /etc/service/rt4/log/main/current --pid=$$ | grep error 

从$信息尾巴:

 --pid=PID with -f, terminate after process ID, PID dies 

尾巴的–pid选项是你最好的朋友。 它将允许您完全控制在后台运行的pipe道。 阅读tail命令选项以获得更大的恢复能力,以防您的文件被另一个进程主动旋转,从而导致您无用的inode。 下面的例子虽然没有用来处理数据,但是certificate了对尾部的“强加”限制以及随时告诉它退出的能力。 这用于测量httpd上的服务压力。

  # Set the tail to die in 100 second even if we die unexpectedlly. sleep 100 & ; ctlpid=$! tail -q -n 0 --follow=name --retry --max-unchanged-stats=1 --pid=$ctlpid -f /var/log/httpd/access_log 2>/dev/null | wc –l > /tmp/thisSampleRate & …. Do some other work …. Can kill the pipe at any time by killing $ctlpid …. Calculate preassure if /tmp/thisSampleRate is ready