[英]Linux shell script not executing completely as desktop shortcut
我希望創建一個Shell腳本,以便在我每天上班時打開一組應用程序。 我發現了幾條類似的帖子,這似乎是我想要的。 問題是,當我雙擊該腳本時,該腳本不起作用。
如果我從終端啟動腳本,它會完全執行,但是我不想總是從終端調用它,我想雙擊一個快捷方式。 如果我在末尾添加“ sleep 1”,則它大多數時候都可以工作,但是這里的問題是1秒並不總是足夠的時間來執行所有操作。 而且,這感覺非常不精確。 當然,我可以說“ sleep 10”並完成它,但是,作為開發人員,這感覺就像是一個hack解決方案。
這是我當前的腳本,我打算隨着時間的推移將我的應用程序添加到該列表中,但是現在就足夠了:
#!/bin/bash
skype &
/opt/google/chrome/google-chrome &
geany &
mysql-workbench &
所以問題是:如何確保一切開始,但不讓臨時終端窗口打開的時間超過需要的時間呢?
如果很重要,要創建此腳本,我只需將.sh文件保存到桌面,然后在文件屬性中選中“允許以程序形式執行文件”。
嘗試在每個命令之前加上nohup
:
#!/bin/bash nohup skype & nohup /opt/google/chrome/google-chrome & nohup geany & nohup mysql-workbench &
更好的是,使用循環:
#!/bin/bash apps="skype /opt/google/chrome/google-chrome geany mysql-workbench" for app in $apps; do nohup $app & done
如果發生任何錯誤,請檢查nohup.out
以獲取消息。
我認為此問題的原因是太早關閉了I / O文件(很可能是ttys)。 您可以嘗試重定向所有I / O(stdin,stdout,stderr),例如:
skype < /dev/null > /dev/null 2 > /dev/null &
這樣的事情也應該起作用:
#!/bin/sh
{
skype &
/opt/google/chrome/google-chrome &
geany &
mysql-workbench &
} < /dev/null > /dev/null 2 > /dev/null &
編輯:
我可以在Ubuntu 12.04上重現它。 關閉時似乎終端程序會殺死其pgroup
所有進程。 嘗試過:
/usr/bin/gnome-terminal -x /bin/sh -c ./test.sh
xterm -e ./test.sh`
結果是一樣的-沒有sleep
程序就不會顯示。 看來終端,當腳本完成時將SIGHUP
發送到shell腳本的pgroup
。 您可以通過strace -f
運行以上任何程序來查看它。 在列表末尾應該有帶有非常大的PID編號作為參數的kill(PID,SIGHUP)
-實際上它是負數,因此SIGHUP被發送到pgroup中的所有進程。
我會假設許多X11忽略了SIGHUP。 問題是SIGHUP在更改默認行為之前已發送/接收。 有了sleep
您將花一些時間來更改SIGHUP處理。
我嘗試過disown
(內置bash),但沒有幫助(SIGHUP到pgroup是從終端而不是shell發送的)。
編輯:
一種可能的解決方案是制作script.desktop
文件(您可以使用一些現有的.desktop文件作為模板,在Ubuntu上,這些文件位於/usr/share/applications
),然后從該文件啟動您的腳本。 看來,即使是不忽略SIGHUP( xclock
)的X11程序也通常以這種方式啟動。
首先,您似乎有一個“ &”號( &
) ,這可能會引起一些問題。
其次,您可以執行以下操作以確保僅在成功后退出外殼程序(即執行):
#!/bin/bash skype & /opt/google/chrome/google-chrome & geany & mysql-workbench if [ $? -eq 0 ] then echo "Successfully completed operation (launched files, etc...)" #use if you don't want to see anything/be notified if successful ## 'exit 0' will exit TERMINAL, therefore the SCRIPT AS WELL ## indicating to the shell that there was NO ERROR (success) #exit 1 exit 0 ## 'return 0' will allow the "successful" message to be written ## to the command-line and then keep the terminal open, if you ## want confirmation of success. The SCRIPT then exits and ## control returns to terminal, but it will not be forced close. return 0 else echo "Operation failed!" >&2 ## 'exit 1' will exit the TERMINAL, and therefore the SCRIPT AS ## WELL, indicating an ERROR to the shell #exit 1 ## 'return 1' will exit the SCRIPT only (but not the terminal) and ## will indicate an ERROR to the shell return 1 fi
(請注意,我添加了一個符號&
對我的回答結束下文)
你可以做一線。 下面的命令將一次一次順序地運行所有命令,只有前一個命令結束時,每個命令才運行。 如果在&
任何單個命令中的AND失敗,則命令行語句終止。
(skype && /opt/google/chrome/google-chrome && geany && mysql-workbench) && echo "Success!" || echo "fail" &
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.