0

嗨,如果这看起来很恶心,请原谅我刚刚开始学习如何编写脚本。

无论发生什么,我都想在 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

4 回答 4

0

$!仅适用于显式置于后台的进程。

这里介绍的语法几乎可以在 ksh 中使用,其中|&具有不同的含义:它将命令作为协同进程置于后台,这意味着您可以read从协同进程中使用read -p event.

于 2012-08-08T19:07:54.103 回答
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你将杀死cvlc由 shell 启动的那个。

于 2012-08-08T18:45:24.610 回答
0

这是我最后使用的解决方案(这个脚本的名字是vlcrecorder)。

它获取自己的子进程 (pgrep) 的 pid,因为该函数调用自己,所以它必须遍历子进程、孙子进程、曾孙子进程等,直到在树的底部找到 vlc 的 pid。

感谢所有帮助过我的人。

#!/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
于 2012-08-29T19:44:49.320 回答
0

也许您可以将 的输出写入cvlc命名管道,然后将其踢到后台,这样您就可以使用$!. 然后,您从命名管道中读取并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
于 2012-08-09T18:38:05.870 回答