2

我希望创建一个 shell 脚本,以便在我开始工作日时打开一组应用程序。我发现了一些这样的帖子,这似乎是我正在寻找的。问题是,当我双击它时脚本不起作用。

如果我从终端启动脚本,它会完全执行,但我不想总是从终端调用它,我想双击一个快捷方式。如果我在末尾添加“睡眠 1”,它大部分时间都可以工作,但这里的问题是 1 秒并不总是足够的时间来执行所有操作。此外,它只是感觉非常不精确。当然,我可以说“睡眠 10”并完成它,但是,作为开发人员,这感觉就像一个 hack 解决方案。

这是我当前的脚本,我打算随着时间的推移将我的应用程序添加到此列表中,但这对于现在来说已经足够了:

#!/bin/bash
skype &
/opt/google/chrome/google-chrome &
geany &
mysql-workbench &

所以问题是:我怎样才能确保一切都开始了,但又不会让临时终端窗口的打开时间超过它需要的时间?

万一这很重要,要创建此脚本,我只需将 .sh 文件保存到桌面并在文件属性中选中“允许将文件作为程序执行”。

4

4 回答 4

3

尝试在每个命令前加上nohup

#!/bin/bash
nohup Skype &
nohup /opt/google/chrome/google-chrome &
nohup geany &
nohup mysql-工作台 &

更好的是,使用循环:

#!/bin/bash

应用程序="skype /opt/google/chrome/google-chrome geany mysql-workbench"

$apps 中的应用程序;做
  nohup $app &
完毕

如果发生任何错误,请检查nohup.out消息。

于 2014-12-19T21:23:36.980 回答
2

我认为这个问题的原因是太早关闭了 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当脚本完成发送到pgroupshell 脚本时,它似乎是终端。您可以通过运行上述任何程序来查看它strace -f。在列表末尾应该kill(PID,SIGHUP)有一个非常大的 PID 号作为参数 - 实际上它是负数,所以 SIGHUP 被发送到 pgroup 中的所有进程。

我会假设许多 X11 忽略 SIGHUP。问题是 SIGHUP 在更改默认行为之前已发送/接收。有了sleep你给了一些时间来改变 SIGHUP 处理。

我已经尝试过disown(bash 内置),但它没有帮助(SIGHUP 到 pgroup 是从终端发送的,而不是 shell)。

编辑:

一种可能的解决方案是制作script.desktop文件(您可以使用一些现有的 .desktop 文件作为模板,在 Ubuntu 上,这些文件位于/usr/share/applications)并从此文件启动您的脚本。似乎即使是不忽略 SIGHUP ( xclock) 的 X11 程序也通常以这种方式启动。

于 2014-12-19T22:15:43.547 回答
1
  1. 首先,您似乎有一个TRAILING & 符号 ( &) ...这可能会导致一些问题。

  2. 其次,您可以执行以下操作以确保仅在成功时退出 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
    
于 2014-12-19T15:40:13.303 回答
0

** 更新 **

(请注意&,我在下面的答案末尾添加了一个&符号)

你可以做一个单行。以下将依次运行所有命令,一次一个,每个命令仅在前一个结束时/当前一个结束时运行。如果 AND WHEN 任何单个命令 BETWEEN&失败,则命令行语句终止。

(skype && /opt/google/chrome/google-chrome && geany && mysql-workbench) && echo "Success!" || echo "fail" &
于 2014-12-19T16:46:51.337 回答