我需要一个小脚本,它同时运行三个 vlc 命令(在 Ubuntu 服务器 14.04 上),如下所示:
#!/bin/sh
cvlc -vvv v1 --sout "#transcode{vcodec=h264,vb=999,acodec=mp3,ab=128,deinterlace channels=2,samplerate=44100}:standard{mux=ts,dst=x.x.x.x:5656,access=http}"
cvlc -vvv v2 --sout "#transcode{vcodec=h264,vb=999,acodec=mp3,ab=128,deinterlace channels=2,samplerate=44100}:standard{mux=ts,dst=x.x.x.x:5657,access=http}"
cvlc -vvv v3 --sout "#transcode{vcodec=h264,vb=999,acodec=mp3,ab=128,deinterlace channels=2,samplerate=44100}:standard{mux=ts,dst=x.x.x.x:5658,access=http}"
我需要完美的方式或方法让脚本运行 3 个 VLC 命令(所有命令必须同时在后台静默运行)。
还需要另一个脚本来检查上述脚本是否正在运行(上述脚本上的所有 vlc 命令都在运行),如果停止或崩溃则重新启动它。
提前致谢
沙塔
答案1
您可以使用 screen 在后台执行 bash 脚本。
请查看以下相关文章。
https://www.howtoforge.com/linux_screen
http://www.howtoing.com/screen-command-examples-to-manage-linux-terminals/
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/
您可以使用监控保持命令运行。如果服务崩溃它将启动。
答案2
试试这个怎么样:诺哈普 你的命令 &
“nohup”确保进程在注销后不会终止,最后的“&”确保整个命令将在后台运行。
答案3
在后台发送进程的常用方法是&
在命令之后使用运算符(按照 Glenn 的建议)。
为了在一段时间后能够区分进程的状态,您需要知道它的 PID。所以你需要找到一种方法来捕获PID
刚刚启动的进程(进程ID)。
可用在$!
变量中。
注意你需要将它存储在另一个变量中因为它会在每次命令调用后更新。在这种情况下您可以将 PID 存储在一个文件中,稍后可以在第二个脚本中使用该文件。
看来是一个存放它的好地方/var/lock/yourscripdirectory/lock
。
每次重新启动时,该目录都会自动清理。
您的第一个脚本(我们称之为s1.sh
)应该执行您的命令并存储 PID,并且可以类似于以下脚本:
#!/bin/sh
MyLockDir="/var/lock/${0##*/}"
mkdir -P # it creates if needed the directory
# /var/lock/yourscriptname without its path
cvlc -vvv v1 --sout "#transcode{vcodec=h264,vb=999,acodec=mp3,ab=128,deinterlace channels=2,samplerate=44100}:standard{mux=ts,dst=x.x.x.x:5656,access=http}" &
echo $! >${MyLockDir}/5656 # here you store in the file 5656 the PID
cvlc -vvv v2 --sout "#transcode{vcodec=h264,vb=999,acodec=mp3,ab=128,deinterlace channels=2,samplerate=44100}:standard{mux=ts,dst=x.x.x.x:5657,access=http}" &
echo $! >${MyLockDir}/5657
cvlc -vvv v3 --sout "#transcode{vcodec=h264,vb=999,acodec=mp3,ab=128,deinterlace channels=2,samplerate=44100}:standard{mux=ts,dst=x.x.x.x:5658,access=http}" &
echo $! >${MyLockDir}/5658
第二个脚本(我们称之为s2.sh
)必须检查进程是否包含PID
之前创建的文件中写入的内容。它应该检查它是否仍在运行,并在需要时更新它。从下面几行中得到一些提示:
#!/bin/sh
MyPort=$2
MyLockDir="/var/lock/s1.sh"
mypid="$(cat ${MyLockDir}/${MyPort})"
ps -p $mypid > /dev/null;
if [ $? == 0 ] ;
then # Running
echo "# It runs ... " ; # or whatever you want
else # NOT Running
cvlc -vvv $1 --sout "#transcode{vcodec=h264,vb=999,acodec=mp3,ab=128,deinterlace channels=2,samplerate=44100}:standard{mux=ts,dst=x.x.x.x:$MyPort,access=http}" &
echo $! >${MyLockDir}/$MyPort
fi
例如,您可以为您需要的每个端口运行第二个脚本./s2.sh v1 5656
(或使用...)。./s2.sh v2 5657
稍微复杂一点的方法是为每个端口创建一个具有该名称的目录锁定目录并将带有 PID 的锁定文件放入其中,在脚本本身中捕获该目录的删除命令,并稍后检查该目录是否存在...请参阅此处的提示
这种方式可以确保只有一个并发脚本可以创建它并cvlc
在该端口上运行一个实例。
更新:一条评论
问:为什么建议存储 PID,而不是使用其他命令(例如ps -ef | grep '5657'
?)来检查它。答:一般来说,进程的 PID 是唯一的,同时您无法提前知道您用于输出的字符串是否grep
未被ps
其他命令使用...因此 PID 存在:)