如何从管道中获取我的进程ID?

时间:2012-08-08 18:40:20

标签: bash

嗨,请原谅我,如果这看起来非常恶心,我刚开始学习如何制作脚本。

我想在65秒后杀死vlc,无论发生什么,但如果它断开连接 在那段时间我想杀死它并用新的输出文件名重新启动它。

#!/bin/bash

function record {
  DATE=$(date "+%d%m%y%H%M%S%N");

  cvlc -vR rtsp://192.168.1.233 \
      --sout=file/mov:/var/www/continuous/%1/$DATE.mov 2>& 1 |

  while read event;
  do
    PID=$!
    lastevent=${event#*]}
    if [ "$lastevent" == "live555 demux warning: no data received in 10s, eof ?" ];
    then
      kill $PID
      record
    fi
  done
}

record &
sleep 65
kill $PID

问题是$!没有得到正确的pid所以我不能杀死它。我需要得到vlc的pid。

4 个答案:

答案 0 :(得分:0)

您对$!的想法是错误的。在这里使用pkill -P$$要好得多。

示例:

cvlc -vR rtsp://192.168.1.233 \
    --sout=file/mov:/var/www/continuous/%1/$DATE.mov | while read event; do
  lastevent=${event#*]}
  if [ "$lastevent" == "live555 demux warning: no data received in 10s, eof ?" ];
  then
    pkill -P$$ cvlc
  fi
done

使用pkill -P$$ cvlc,您将杀死由shell启动的cvlc

答案 1 :(得分:0)

$!仅适用于背景明确的流程。

此处提供的语法几乎可以在ksh中使用,其中|&具有不同的含义: 它将一个命令作为一个协同进程放在后台,这暗示你可以read来自 与read -p event进行协同处理。

答案 2 :(得分:0)

也许您可以将cvlc的输出写入命名管道,然后将其踢到后台,以便您可以使用$!获取pid。然后,您从命名管道中读取,并且当您的时间限制结束时cvlc被杀死。

# create the named pipe
MYPIPE=/tmp/cvlc_pipe_$$
rm -f ${MYPIPE} # remove the named pipe in case it already exist
mkfifo ${MYPIPE}

function record {
  DATE=$(date "+%d%m%y%H%M%S%N");

  # have cvlc write to the named pipe in the background, then get its pipe with $1
  cvlc -vR rtsp://192.168.1.233 \
      --sout=file/mov:/var/www/continuous/%1/$DATE.mov > ${MYPIPE} 2>& 1 &&
  PID=$!

  # read cvlc's output from the named pipe
  exec 7<>${MYPIPE}
  while read -u 7 event;
  do  
    PID=$!
    lastevent=${event#*]}
    if [ "$lastevent" == "live555 demux warning: no data received in 10s, eof ?" ];
    then
      kill $PID
      record
    fi  
  done
  exec 7>&-
}

record &
sleep 65
kill $PID
rm -f ${MYPIPE} # cleanup

答案 3 :(得分:0)

这是我使用结束的解决方案(此脚本的名称是vlcrecorder)。

它获得了自己子节点的pid(pgrep),因为函数调用自身它必须循环遍历子节点,孙子节点,曾孙子等,直到它在树的底部找到vlc的pid。

谢谢帮助我的aLL。

#!/bin/bash
function record {
DATE=$(date "+%d%m%y%H%M%S%N");
cvlc -v -R rtsp://$1/$2 --sout=file/mov:/var/www/continuous/2/$DATE.mov |&
while read event;
do
lastevent=${event#*]}
echo $lastevent
if [[ "$lastevent" == *"live555 demux warning: no data received in 10s, eof ?"* ]]; then
sleep .1
ppid=$(pgrep -P $$ -x vlcrecorder)
vlcpid=$(pgrep -P $ppid -x vlc)
until [ -z "$ppid" ]; do
vlcppid=$vlcgppid
vlcgppid=$ppid
ppid=$(pgrep -P $ppid -x vlcrecorder)
done
vlcpid=$(pgrep -P $vlcppid -x vlc)
kill $vlcpid
record $1 $2 
fi
done
}

record $1 $2 &
sleep 65
parentpid=$!
until [ -z "$parentpid" ]; do
gppid=$parentpid
parentpid=$(pgrep -P $parentpid -x vlcrecorder)
lastvlcpid=$(pgrep -P $gppid -x vlc)
if [ -n "$lastvlcpid" ]; then
kill $lastvlcpid
fi
done