簡單解決方案
您可以使用簡單的管道。總結腳本的命令發送部分爲功能和調用功能,而其輸出作爲管道到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
之後省略&
。
殺死並重啓瘸子
甚至會更好,如果,如果它不是用足夠長的時間,我可以關閉瘸子實例,並在需要時重新啓動。
這比使用timeout
命令稍微複雜一些,因爲我們不想在處理某些圖像時殺死gimp。我們也不想在消耗事件和發送相應命令之間終止sendCommands
。
也許我們可以啓動一個幫助程序來每60秒發送一次dbus事件。讓我們說的事件被稱爲勾號。刻度也由sendCommands
讀取。如果兩個滴答聲之間沒有命令,則應該殺死芯片。
我們使用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。
謝謝@Socowi,這是一個很好的答案!我只需要添加兩個註釋:首先,我犯了一個錯誤,它是一個'gimp -i -b - '不僅僅是'gimp -i',它運行gimp並等待來自stdin的用戶輸入。其次,你答案的最後部分適用於任何通用應用程序,不僅僅是gimp。但是在gimp的情況下,我們有一個優勢 - 我們可以使用'(gimp-message(string-append「處理已完成!))''來打印警告。所以我想我們可以強迫gimp來傳達它現在處於空閒模式的事實。 – truf
我想我應該可以運行類似'sendCommands |的東西gimp -i -b - 3>&1 1>&2 2>&3 | processReply&'和grep有關處理結束的消息在'processReply()'中結束。與'gimpIsRunning'之間因此我應該能夠得到'gimpIsWorking'全球varaiable與'timeout'辦法堅持下去。當然這種方法只能用gimp而不是一般情況。我想知道在這種情況下結果代碼是否會更簡單? – truf
好點。不幸的是,當掃描gimp的stderr時,事情並沒有多少簡單。因爲我們不知道提前超時(這取決於傳入作業從未來)'timeout'是沒有用的依然。 'sendCommands | gimp ... | processReply&'也不能使用。我們不能停止並用新的gimp過程替換管道中間的gimp進程。掃描gimp的stderr只有好處:我們可以確保一次只運行一個gimp進程。 – Socowi