Zenity 進度對話框的取消按鈕功能如何?
在嘗試使
Cancel
Zenity--progress
視窗上的按鈕適用於我的腳本時,我意識到我根本不了解Cancel
Zenity 手冊頁面上給出的範例中的按鈕是如何工作的:https ://help.gnome.org/users /zenity/stable/progress.html.en#!/bin/sh ( echo "10" ; sleep 1 echo "# Updating mail logs" ; sleep 1 echo "20" ; sleep 1 echo "# Resetting cron jobs" ; sleep 1 echo "50" ; sleep 1 echo "This line will just be ignored" ; sleep 1 echo "75" ; sleep 1 echo "# Rebooting system" ; sleep 1 echo "100" ; sleep 1 ) | zenity --progress \ --title="Update System Logs" \ --text="Scanning mail logs..." \ --percentage=0 if [ "$?" = -1 ] ; then zenity --error \ --text="Update canceled." fi
當該腳本執行時,為什麼在
Cancel
沒有exit
或break
或任何其他命令可見時按下按鈕時程序停止?我認為 Zenity 只是一個顯示圖形界面並返回退出程式碼的程序,可用於啟動所需的實際命令(如
exit
取消等),但似乎 Zenity 必須做一些更複雜的事情,因為沒有似乎是範例中的命令在按下按鈕時實際停止的任何原因。Zenity 是在做一些更複雜的事情,還是我誤解了什麼?我是 bash/sh 腳本的新手,所以看起來我可能誤解了。如果它只是 Zenity 獨有的複雜功能,則無需對其工作原理進行完整的技術描述;我想要的只是足夠的解釋,因此可以可靠地使用它。謝謝你。
(我還想問一下為什麼官方手冊中的這個例子實際上不起作用
$$ on Ubuntu 14.04 $$因為
--error
從來沒有顯示 Zenity 視窗,但我認為 StackExchange 不喜歡聯合問題,所以沒關係,除非它與我可能會誤解有關。) 相關文章: 使用 zenity 進度條終止腳本(不回答我的問題,因為--auto-kill
在此範例中,當程序取消而不使用時,上面的答案說要使用--auto-kill
腳本中的
()
語法sh
允許您啟動subshel l 。您可以將 subshell 視為以下兩行相同的行:(echo foo) sh -c "echo foo"
即,在您的 shell 腳本中有第二個程序處理
()
. 通過管道符號(“|
”),該子外殼的標準輸出連接到 zenity 的標準輸入。當您在 zenity 視窗中點擊“取消”按鈕時,將導致 zenity 立即退出。此時,子shell 的標準輸出變為無效。這不會立即殺死子shell;但是,當該
echo
子外殼中的下一個命令要寫入標準輸出時,它將收到一個SIGPIPE
信號,表示它正在嘗試寫入的管道沒有讀取器。程序的標準行為SIGPIPE
是終止。您會注意到,如果您從終端啟動腳本並在將更新發送到 zenity後點擊“取消”按鈕,您的 shell 提示不會立即返回;由於 sleep 命令仍在執行,並且由於 sleep 不產生輸出,因此需要一段時間才能產生任何輸出並
SIGPIPE
發出。如果你不想要這種行為,那麼你應該告訴 shell 在收到 SIGPIPE 時不要退出:
#!/bin/sh ( trap -- '' PIPE echo "10"; sleep 1 # ... etc, your normal script goes here ) | zenity --progress ...
此版本將忽略
SIGPIPE
,並在 zenity 退出時繼續愉快地執行。但是,請注意,在這種情況下,“取消”按鈕會讓使用者感到非常困惑;它會導致 zenity 退出,但不會導致操作中止。最好只是通過--no-cancel
而不是。