我希望创建一个shell脚本,以便在我开始工作日时打开一组应用程序。我找到了几个帖子like this,这似乎是我正在寻找的。问题是,当我双击它时脚本不起作用。
如果我从终端启动脚本,它会完全执行,但我不想总是从终端调用它,我想双击一个快捷方式。如果我添加一个"睡眠1"到最后,它大部分时间都有效,但这里的问题是1秒并不总是足以执行所有事情。而且,它感觉非常不精确。当然,我可以说"睡10"并且完成它,但是,作为开发人员,这感觉就像一个黑客解决方案。
这是我当前的脚本,我打算随着时间的推移将我的应用程序添加到此列表中,但现在这已经足够了:
#!/bin/bash
skype &
/opt/google/chrome/google-chrome &
geany &
mysql-workbench &
所以问题是:我怎样才能确保一切都开始但不要让临时终端窗口打开的时间超过需要的时间?
如果重要,要创建此脚本,我只需将.sh文件保存到桌面并检查"允许执行文件作为程序"在文件属性中。
答案 0 :(得分:3)
使用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
是否有消息。
答案 1 :(得分:1)
首先,您似乎有一个 TRAILING&符号(&
) ...这可能会导致一些问题。
其次,您可以执行以下操作,以确保您在成功时仅退出shell(即执行):
#!/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
答案 2 :(得分:1)
我认为这个问题的原因是过早关闭的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
运行上述任何程序来查看它。在列表末端,应该有kill(PID,SIGHUP)
非常大的PID编号作为参数 - 实际上它是负数,因此SIGHUP被发送到pgroup中的所有进程。
我会假设许多X11忽略了SIGHUP。问题是在更改默认行为之前发送/接收SIGHUP。使用sleep
您需要一些时间来更改SIGHUP处理。
我已尝试disown
(bash builtin),但它没有帮助(从终端发送到群组的SIGHUP,而不是shell)。
编辑:
一种可能的解决方案是创建script.desktop
文件(您可以使用一些现有的.desktop文件作为模板,在Ubuntu上这些文件位于/usr/share/applications
)并从此文件启动您的脚本。看起来即使是X11程序,也不会忽略SIGHUP(xclock
)也是正常的。
答案 3 :(得分:0)
(注意我在下面的答案末尾添加了&符号&
)
你可以做一个单行。以下将按顺序一次一个地运行所有命令,每个命令仅在前一个命令结束时运行。如果&
之间的任何单个命令失败,则命令行语句将终止。
(skype && /opt/google/chrome/google-chrome && geany && mysql-workbench) && echo "Success!" || echo "fail" &