Linux Bash写入后台作业';在它发布之后

Linux Bash写入后台作业';在它发布之后,linux,bash,gimp,Linux,Bash,Gimp,这很幼稚,但我要试一试。 我想使用gimp-I-b-&从bash启动gimp,然后在无限循环中读取dbus信号,并将从这些信号获得的数据发布回我启动的gimp。gimp-i-b-启动命令行gimp并等待用户输入,如gnuplot等。但是在命令执行后是否可以从bash访问其stdin 理想情况下,我希望这样的工作: gimp -i -b - & dbus-monitor --profile "..." --monitor | while read -r line; do gimp -b

这很幼稚,但我要试一试。
我想使用
gimp-I-b-&
从bash启动gimp,然后在无限循环中读取dbus信号,并将从这些信号获得的数据发布回我启动的gimp。
gimp-i-b-
启动命令行gimp并等待用户输入,如gnuplot等。但是在命令执行后是否可以从bash访问其stdin

理想情况下,我希望这样的工作:

gimp -i -b - &

dbus-monitor --profile "..." --monitor |
while read -r line; do
gimp -b '(mycommand '$line')' &
done

gimp -b '(gimp-quit 0)' &
其中所有
gimp cmd&
都被发送到同一个gimp实例。 如果我可以关闭gimp实例(如果它没有使用足够长的时间)并在需要时重新启动它,那就更好了

使用bash是否可以不编写一些守护程序应用程序?

简单的解决方案 你可以给我们一个简单的烟斗。将脚本的命令发送部分包装到一个函数中,并在将其输出传输到gimp时调用该函数:

#! /bin/bash

sendCommands() {
    dbus-monitor --profile "..." --monitor |
    while read -r line; do
        echo "(mycommand $line)"
    done
    echo "(gimp-quit 0)"
}

sendCommands | gimp -i &
sendCommands
gimp-i
将并行运行。每次
sendCommands
打印某个内容时,该内容都会出现在gimp的stdin中。
如果这是您的完整脚本,您可以在
gimp-i
之后省略
&

终止和重新启动Gimp 如果我可以关闭gimp实例(如果它没有使用足够长的时间)并在需要时重新启动它,那就更好了

这比仅仅使用
timeout
命令要复杂一些,因为我们不想在gimp仍在处理某些图像时杀死它。我们也不希望在消耗事件和发送相应命令之间终止
sendCommands

也许我们可以启动一个助手进程,每60秒发送一个dbus事件。让所述事件称为滴答声。勾号也可通过
send命令
读取。如果有两个记号之间没有命令,那么应该终止gimp

我们使用FIFO(也称为命名管道)向gimp发送命令。每次新的gimp进程启动时,我们也会创建一个新的FIFO。这确保了针对新gimp进程的命令也被发送到新进程。如果gimp无法在60秒内完成挂起的操作,则可能同时有两个gimp进程

#! /bin/bash

generateTicks() {
     while true; do
         # send tick over dbus
         sleep 60
     done
}

generateTicks &

gimpIsRunning=false
wasActive=false
sleepPID=
fifo=

while read -r line; do
    if eventIsTick; then # TODO replace "eventsIsTick" with actual code
        if [[ "$wasActive" = false ]]; then
            echo '(gimp-quit 0)' > "$fifo" # gracefully quit gimp
            gimpIsRunning=false
            [[ "$sleepPID" ]] && kill "$sleepPID" # close the FIFO
            rm -f "$fifo"
        fi
        wasActive=false
    else
        if [[ "$gimpIsRunning" = false ]]; then
            fifo="$(mktemp -u)"
            mkfifo "$fifo"
            sleep infinity > "$fifo" & # keep the FIFO open
            sleepPID="$!"
            gimp -i < "$fifo" &
            gimpIsRunning=true
        fi
        echo "(mycommand $line)" > "$fifo"
        wasActive=true
    fi
done < <(dbus-monitor --profile "..." --monitor)

echo '(gimp-quit 0)' > "$fifo" # gracefully quit gimp
[[ "$sleepPID" ]] && kill "$sleepPID" # close the FIFO
rm -f "$fifo"
#/bin/bash
生成技术(){
虽然是真的;做
#通过dbus发送勾号
睡60
完成
}
生成学&
万向节运行=错误
wasActive=false
昏昏欲睡的=
先进先出=
而read-r行;做
如果是事件论者;然后#TODO将“eventsIsTick”替换为实际代码
如果[[“$wasActive”=false]];然后
echo'(gimp退出0)>“$fifo”#优雅地退出gimp
万向节运行=错误
[[“$sleepPID”]&&kill“$sleepPID”#关闭FIFO
rm-f“$fifo”
fi
wasActive=false
其他的
如果[[“$gimpIsRunning”=false]];然后
fifo=“$(mktemp-u)”
mkfifo“$fifo”
sleep infinity>“$fifo”&#保持fifo打开
sleepPID=“$!”
gimp-i<“$fifo”&
万向节运行=真
fi
echo“(mycommand$line)”>“$fifo”
wasActive=true
fi
完成<“$fifo”#优雅地退出gimp
[[“$sleepPID”]&&kill“$sleepPID”#关闭FIFO
rm-f“$fifo”
注意,
dbus监视器…|虽然“完成”
现在写为
,而。。。完成<简单解决方案
你可以给我们一个简单的烟斗。将脚本的命令发送部分包装到一个函数中,并在将其输出传输到gimp时调用该函数:

#! /bin/bash

sendCommands() {
    dbus-monitor --profile "..." --monitor |
    while read -r line; do
        echo "(mycommand $line)"
    done
    echo "(gimp-quit 0)"
}

sendCommands | gimp -i &
sendCommands
gimp-i
将并行运行。每次
sendCommands
打印某个内容时,该内容都会出现在gimp的stdin中。
如果这是您的完整脚本,您可以在
gimp-i
之后省略
&

终止和重新启动Gimp 如果我可以关闭gimp实例(如果它没有使用足够长的时间)并在需要时重新启动它,那就更好了

这比仅仅使用
timeout
命令要复杂一些,因为我们不想在gimp仍在处理某些图像时杀死它。我们也不希望在消耗事件和发送相应命令之间终止
sendCommands

也许我们可以启动一个助手进程,每60秒发送一个dbus事件。让所述事件称为滴答声。勾号也可通过
send命令
读取。如果有两个记号之间没有命令,那么应该终止gimp

我们使用FIFO(也称为命名管道)向gimp发送命令。每次新的gimp进程启动时,我们也会创建一个新的FIFO。这确保了针对新gimp进程的命令也被发送到新进程。如果gimp无法在60秒内完成挂起的操作,则可能同时有两个gimp进程

#! /bin/bash

generateTicks() {
     while true; do
         # send tick over dbus
         sleep 60
     done
}

generateTicks &

gimpIsRunning=false
wasActive=false
sleepPID=
fifo=

while read -r line; do
    if eventIsTick; then # TODO replace "eventsIsTick" with actual code
        if [[ "$wasActive" = false ]]; then
            echo '(gimp-quit 0)' > "$fifo" # gracefully quit gimp
            gimpIsRunning=false
            [[ "$sleepPID" ]] && kill "$sleepPID" # close the FIFO
            rm -f "$fifo"
        fi
        wasActive=false
    else
        if [[ "$gimpIsRunning" = false ]]; then
            fifo="$(mktemp -u)"
            mkfifo "$fifo"
            sleep infinity > "$fifo" & # keep the FIFO open
            sleepPID="$!"
            gimp -i < "$fifo" &
            gimpIsRunning=true
        fi
        echo "(mycommand $line)" > "$fifo"
        wasActive=true
    fi
done < <(dbus-monitor --profile "..." --monitor)

echo '(gimp-quit 0)' > "$fifo" # gracefully quit gimp
[[ "$sleepPID" ]] && kill "$sleepPID" # close the FIFO
rm -f "$fifo"
#/bin/bash
生成技术(){
虽然是真的;做
#通过dbus发送勾号
睡60
完成
}
生成学&
万向节运行=错误
wasActive=false
昏昏欲睡的=
先进先出=
而read-r行;做
如果是事件论者;然后#TODO将“eventsIsTick”替换为实际代码
如果[[“$wasActive”=false]];然后
echo'(gimp退出0)>“$fifo”#优雅地退出gimp
万向节运行=错误
[[“$sleepPID”]&&kill“$sleepPID”#关闭FIFO
rm-f“$fifo”
fi
wasActive=false
其他的
如果[[“$gimpIsRunning”=false]];然后
fifo=“$(mktemp-u)”
mkfifo“$fifo”
sleep infinity>“$fifo”&#保持fifo打开
sleepPID=“$!”
gimp-i<“$fifo”&
万向节运行=真
fi
echo“(mycommand$line)”>“$fifo”
wasActive=true
fi
完成<“$fifo”#优雅地退出gimp
[[“$sleepPID”]&&kill“$sleepPID”#关闭FIFO
rm-f“$fifo”
注意,
dbus监视器…|虽然完成
现在写为
while