获取BASH命令PID

时间:2014-01-08 13:50:51

标签: linux bash debugging pipe pid

我有这段代码

#!/bin/bash
streamURL=http://devimages.apple.com/iphone/samples/bipbop/gear4/prog_index.m3u8

(
    echo "Debugging for stream: $streamURL";
    echo "Starting debugging...";
    vlc -vvv --color $streamURL --file-caching=10000 2>&1 | sed "s/^/ `date`/";

) | tee  debug.txt &
PROCESS_PID=$!

ps -e | grep $PROCESS_PID 
echo " killing process pid: "
echo $PROCESS_PID;
kill -9 $PROCESS_PID
ps -e | grep vlc #still there

我的问题是我无法将“vlc ...”命令PID保存到变量中以便稍后将其删除。如果我在它之后移动“ PROCESS_PID = $!”,它将为空。还需要管道后面的 sed 。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

您无法在subshellget it back outside it中分配变量。

在这种情况下,如果您kill $!,您将会tee,{A}会将SIGPIPE发送到子shell并终止整个事件。因此,子shell中通常不需要PID。

我不确定,但问题可能是你nuking the process from orbit with SIGKILL而不是仅用kill $PID轻轻地杀死它。在这种情况下,tee可能

换句话说,只需使用kill $process_id即可。请注意,杀死进程并不是同步的 - 您只需向其发送信号并继续进行即可。有关详细信息,请参阅Kill bash processes “nicely”

答案 1 :(得分:2)

你可以通过twiddling文件描述符获得pid,但这很痛苦。例如:

{ PID=$({ ( 
   echo foo; 
   echo bar;
   sh -c 'echo $$ >&5; exec echo baz' ) |
   tr a o; } 5>&1 1>&3 ); } 3>&1

将指定“回声”的pid'到PID。用您的vlc替换该回音,并将tr替换为您的sed,您应该有一个解决方案。

要尝试对此处发生的事情提供一些简化的解释,请首先注意我们正在使用流程替换来分配PID$()语法只是将命令放在括号内,并将该命令的输出分配给变量。重要的是要记住"输出"这意味着"打印到文件描述符1和#34;的任何内容。在sh命令中,我们将pid打印到文件描述符5,然后执行echo。通过使用exec,该echo具有与前一个echo写的相同的pid。现在回声foo,bar和baz都写入到tr的管道中。 tr的输出被重定向到fd 3(在编辑之前,这是fd 2.使用哪个文件描述符大多是任意的,但是如果生成任何错误则修改2是个坏主意)并且文件描述符5被重定向到fd 1,使它成为"输出"分配给PID的进程替换。然后在进程替换之外,我们分配fd 3以给出最初需要的输出。希望这个段落比混淆更具说明性:如果感到困惑,请查看代码以便澄清!

不幸的是,如果你想在后台运行它会变得更加丑陋:

{ PID=$({ ( 
   echo foo; 
   echo bar;
   sh -c 'echo $$ >&5; exec 5>&-; exec echo baz' >&3 & ) |
   tr a o; } 5>&1 1>&3 ); } 3>&1

在这里,您需要关闭文件描述符5以确保进程替换完成。