这很天真,但我会试一试
我想用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?
答案 0 :(得分:4)
你可以给我们一个简单的管道。将发送脚本部分的命令包装到函数中,并在将其输出汇总到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的标准中
如果这是您的完整脚本,则可以在&
之后省略gimp -i
。
如果我可以关闭gimp实例,如果它的使用时间不够长,并且在需要时再次启动,那会更好。
这比使用timeout
命令要复杂得多,因为我们不想在处理某些图像时杀死gimp。我们也不想在消耗事件和发送相应命令之间杀死sendCommands
。
也许我们可以启动帮助程序来每60秒发送一次dbus事件。让所述事件称为 tick 。刻度线也由sendCommands
读取。如果有两个没有命令的刻度线,则应该杀死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"
请注意,dbus-monitor ... | while ... done
现在写为while ... done < <(dbus-monitor ...)
。两个版本在循环输出dbus方面做同样的事情,但是带有管道|
的版本创建了一个子shell,它不允许在循环内设置全局变量。有关进一步说明,请参阅SC2031。