gpt4 book ai didi

linux - Bash 在启动后写入后台作业的标准输入

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:55:56 25 4
gpt4 key购买 nike

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

理想情况下,我希望这样的东西能够工作:

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 &

sendCommandsgimp -i将并行运行。每次sendCommands打印一些东西,一些东西将落在 gimp 的标准输入中。
如果那是你的完整脚本,你可以省略 &gimp -i 之后.

杀死并重启 Gimp

Would be even better if I could close gimp instance if it's not used for long enough and start again when it's needed.

这比使用 timeout 稍微复杂一点命令,因为我们不想在 gimp 仍在处理一些图像时杀死它。我们也不想杀sendCommands在事件的消耗和相应命令的发送之间。

也许我们可以启动一个辅助进程来每 60 秒发送一个 dbus-event。让所述事件称为 ticksendCommands 也读取刻度线。 .如果有两个 ticks 之间没有命令,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 .

关于linux - Bash 在启动后写入后台作业的标准输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42839215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com