4

假设我有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,例如./test.sh | cat

管道没有关闭,因为后台进程仍然存在并且可能会产生一些输出。我怎样才能告诉管道在结束时关闭test.shpidfile有没有比在调用管道命令之前检查是否存在更好的方法?

作为一种变体,我尝试在 结尾处使用#!/bin/bashand ,但它仍在等待管道关闭。disowntest.sh


我实际尝试实现的目标:我有一个“状态”脚本,它收集各种脚本(uptimefreedateget-xy-from-dbus等)的输出,与test.sh此处类似。脚本的输出被传递给我的窗口管理器,它会显示它。它也用于我的 GNU 屏幕底线。

由于使用的某些脚本可能需要一些时间来创建输出,我想将它们从输出集合中分离出来。所以我把它们放在一个while true; do script; sleep 1; done循环中,如果它还没有运行,它就会启动。

现在的问题是我不知道如何告诉调用脚本“真正”分离守护进程。

4

3 回答 3

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
于 2012-10-25T14:12:36.177 回答
2

如果您想显式关闭文件描述符,例如标准输出 1,您可以这样做:

exec 1<&-

这对 POSIX shell 有效,请参阅:here

于 2012-10-02T12:32:33.910 回答
0

当您将 while 循环放在显式子外壳中并在后台运行子外壳时,它将提供所需的行为。

(while true; do
    echo "something" >> somewhere
    sleep 1
done)&
于 2012-10-02T11:34:54.650 回答