假设我有test.sh
,如下所示。目的是通过此脚本运行一些后台任务,不断更新某些文件。如果后台任务因某种原因而终止,则应该再次启动它。
#!/bin/sh
if [ -f pidfile ] && kill -0 $(cat pidfile); then
cat somewhere
exit
fi
while true; do
echo "something" >> somewhere
sleep 1
done &
echo $! > pidfile
并希望将其称为./test.sh | otherprogram
,e。 G。 ./test.sh | cat
。
管道未关闭,因为后台进程仍然存在并可能产生一些输出。如何在test.sh
结束时告知管道关闭?有没有比在调用管道命令之前检查pidfile
是否存在更好的方法?
作为一种变体,我尝试在#!/bin/bash
的末尾使用disown
和test.sh
,但它仍在等待管道关闭。
我实际尝试实现的目标:我有一个“状态”脚本,用于收集各种脚本的输出(uptime
,free
,date
,get-xy-from-dbus
等。),类似于此test.sh
。脚本的输出传递给我的窗口管理器,窗口管理器显示它。它也用在我的GNU屏幕底线。
由于使用的某些脚本可能需要一些时间来创建输出,我想将它们从输出集合中分离出来。所以我把它们放在一个while true; do script; sleep 1; done
循环中,如果它还没有运行就会启动它。
现在的问题是我不知道如何告诉调用脚本“真正”分离守护进程。
答案 0 :(得分:3)
看看这是否符合您的目的: (我假设你对while循环中的任何stderr命令都不感兴趣。你会调整代码,如果你。:-))
#!/bin/bash
if [ -f pidfile ] && kill -0 $(cat pidfile); then
cat somewhere
exit
fi
while true; do
echo "something" >> somewhere
sleep 1
done >/dev/null 2>&1 &
echo $! > pidfile
答案 1 :(得分:2)
答案 2 :(得分:0)
当您将while循环放在显式子shell中并在后台运行子shell时,它将提供所需的行为。
(while true; do
echo "something" >> somewhere
sleep 1
done)&