即使第一个命令的子进程仍在后台运行,也要关闭管道

exi*_*xic 5 bash pipe sh background-process

假设我有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
Run Code Online (Sandbox Code Playgroud)

并想这样称呼它./test.sh | otherprogram,例如./test.sh | cat

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

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


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

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

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

ani*_*ane 4

看看这是否符合您的目的:(我假设您对 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
Run Code Online (Sandbox Code Playgroud)