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

これが最後に使用したソリューションです (このスクリプトの名前は vlcrecorder です)。

関数は自分自身を呼び出すため、ツリーの下部にある 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から、それをバックグラウンドにキックして、 を使用して 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
于 2012-08-09T18:38:05.870 に答える
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$$ cvlcyou を使用するとcvlc、シェルによって開始されたものを強制終了します。

于 2012-08-08T18:45:24.610 に答える
0

$!明示的にバックグラウンドに置かれたプロセスでのみ機能します。

ここに示す構文は、ksh でほとんど機能しますが、ここで|&は意味が異なります。コマンドをコプロセスとしてバックグラウンドに配置します。これはread、コプロセスからread -p event.

于 2012-08-08T19:07:54.103 に答える