如何在启动时运行脚本?


520

如何在Ubuntu启动时自动运行脚本,所以启动后不必手动运行它们?


3
如果有人还可以同时显示“时间”和“地点”,那就太好了。我之所以这样说,是因为我知道至少有两种方法可以启动将在其他应用程序启动之前启动的脚本(例如X11)
Buttink 2010年

1
整个答案线程都是一团糟。Stack Exchange格式似乎并非最适合此问题
Gabriel Fair

1
这实际上很有趣。有多少种不同的方式?
devios1

Answers:


206

根据您需要运行的脚本类型。对于服务等,您应该使用upstart。但是对于用户脚本,它们应该由gnome作为会话脚本启动!在系统>首选项>启动应用程序下查看。

附带说明一下,如果您需要在终端登录时运行某些脚本,可以将其添加到主目录中的.bash_login文件中。

适用于14.04及更高版本

一个简单的命令(不需要保持运行状态)可以使用Upstart作业,例如:

start on startup
task
exec /path/to/command

将此.conf文件保存为/etc/init(如果您需要在系统启动时以root身份运行)或~/.config/upstart(如果您需要在登录时以用户身份运行)文件。


58
考虑到SO和StackExchange的运行方式,您能否举一个新贵脚本的示例以及放置位置?那将使它成为一个更好的答案。您的链接说它没有得到维护,请查看新贵的菜谱,这是很麻烦的。我对从哪里开始没有太多的想法。
Ehtesh Choudhury

2
如果我需要以root用户身份运行命令怎么办?
dopatraman

1
@dopatraman答案指出所有与此相关的进程都以root身份运行。
AStopher

4
请更新此答案,以解释如何在运行systemd而不是新贵(Ubuntu 15.04+)的系统上执行操作。

3
这个答案对我来说没有意义。在system->pref->startup applications中找不到/etc/init/或中列出的应用程序~/.config/upstart。那么启动应用程序在哪里定义?
布劳伦

553

一种方法是添加@reboot cron任务:

  1. 运行crontab -e将允许您编辑cron。
  2. 在上面添加一行:

    @reboot /path/to/script
    

    计算机启动后将执行该脚本。


85
@reboot关键字是一个不错的提示,因为它尚未广为人知。
詹森(Jathanism)2010年

12
真好 确切知道何时触发?
奥利

2
所以...如果我断电并且恢复供电后PC再次打开,这将无法运行?
Mike Wills 2012年

18
@siamii:man 5 crontab表示@reboot在启动时执行(启动cron守护程序时)。
2013年

9
这太棒了。到目前为止,这似乎要好得多,rc.local因为到目前为止,系统似乎已进行了更多设置(PATH等)。奇怪的是,它是那么很难称之为东西系统启动..
KARTHIK牛逼

161

如何将命令添加到/etc/rc.local?您必须使用sudo访问权限来编辑此文件。

sudo nano /etc/rc.local

19
这最直接地回答了以下问题:如何在系统启动时简单地执行一些脚本。upstart执行的任务更加复杂:启动守护进程。
Dogweather

1
那么upstart启动守护进程,而/etc/rc.local启动bash脚本吗?
多纳托

5
应该是?这些天不再有效了,对吧?
戴文斯'17

4
Doenst与Ubuntu 17.04 systemd一起工作
qodeninja

3
请注意,如果您自己制作此文件(就像我一样),则必须使用将文件更改为可执行文件chmod 755 rc.local,然后添加#!/bin/bash到第一行。
psitae '17

77

对于15.04及更高版本:

要在启动时使用运行(短命)1命令systemd,可以使用type的systemd单位OneShot。例如,创建/etc/systemd/system/foo.service包含:

[Unit]
Description=Job that runs your user script

[Service]
ExecStart=/some/command
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

然后运行:

sudo systemctl daemon-reload
sudo systemctl enable foo.service

本质上,这只是将典型的Upstart作业转换为systemd 作业(请参阅Systemd中的Upstart用户)。

您可以使用多ExecStart行代码从同一服务文件运行多个命令:

[Service]
ExecStart=/some/command
ExecStart=/another/command some args
ExecStart=-/a/third/command ignore failure

该命令必须始终以完整路径给出。如果任何命令失败,则其余命令将不运行。-路径前的A 告诉systemd忽略非零退出状态(而不是将其视为失败)。

相关:


对于用户会话,可以~/.config/systemd改为在其中创建systemd单元。此版本应在16.04及更高版本上运行,但不适用于具有systemd的Ubuntu早期版本(因为那些仍在用户会话中使用Upstart的版本)。可以使用与系统服务相同的命令来控制用户会话单元,但是--user添加了以下选项:

systemctl --user daemon-reload
systemctl --user status foo.service

Shell语法

请注意,与Upstart不同,systemd不会Exec*通过Shell 运行命令。它;本身会执行一些有限的变量扩展和多个命令(以分隔),但就象shell语法一样就可以了。对于更复杂的事情,例如重定向或管道,请将命令包装在sh -c '...'或中bash -c '...'


1与长期存在的守护程序相对。


可以为工作设定优先级吗?还是指定它首先依赖于另一个服务?
r3wt

1
@ r3wt是的,有多种方法可以做到这一点。在WantedBy这里使用,例如,使得当它开始multi-user.target为止。您可以使用BeforeAfterRequires等见man systemd.unit
穆鲁

@PerlDuck并不是唯一缺少的东西。谢谢!
大师

别客气。—顺便说一句,这RemainAfterExit取决于您启动的服务及其所需的行为。例如,/bin/df -h<s>将</ s>应具有RemainAfterExit=no
PerlDuck

@PerlDuck并没有内在的df需求RemainAfterExit=no。除非您希望每次运行都重复执行该命令systemctl start foo
大师

71

有多种自动运行命令的方式:

  1. 新贵系统将执行从它发现在目录中配置的所有脚本/etc/init。这些脚本将在系统启动期间运行(或响应某些事件,例如关闭请求),因此可以运行不与用户交互的命令。使用此机制启动所有服务器。

    您可以在以下网址找到易读的简介:http : //upstart.ubuntu.com/getting-started.html手册页,man 5 initman 8 init提供了完整的详细信息。

  2. .gnomerc每次登录GNOME会话时,都会自动获取在主目录中命名的Shell脚本。您可以在其中放置任意命令;您在会话中运行的任何程序都将看到在此脚本中设置的环境变量。

    请注意,直到.gnomerc脚本完成,会话才开始。因此,如果要自动启动某些长时间运行的程序,则需要附加&到该程序调用上,以便将其与正在运行的shell分离。

  3. 菜单选项“ 系统”->“首选项”->“启动应用程序”使您可以定义在图形会话启动时应启动哪些应用程序(Ubuntu预定义了一些应用程序),并根据您的喜好添加或删除它们。这与.gnomerc脚本的目的和范围几乎相同,除了您不需要了解sh语法(但您也不能使用任何sh编程构造)。


11
3)“这与.gnomerc脚本具有几乎相同的目的和范围”,除了.gnomerc显然加载Unity 之前运行,并且Startup Applications显然加载Unity 之后运行。我必须运行一个位于Unity菜单栏上的程序,在这种情况下,它产生了巨大的变化!
这位巴西人

1
@ ruda.almeida感谢您指出这一点。答案是在统一之前写的。
Riccardo Murri 2013年

1
sudo update-rc.d myscript.sh defaults,其中/etc/init.d/myscript.sh是您的脚本,它也在启动时运行。
Dan Dascalescu '16

27
$HOME/.config/autostart
  • 此位置包含启动应用程序列表。
  • .desktop 可以将文件放在此处,它将在启动时执行。

.desktop文件的示例示例:

将以下.desktop文件放入$HOME/.config/autostart并给出chmod +x

[Desktop Entry]
Type=Application
Exec="</path/to/script>"
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name=Startup Script

"</path/to/script>"是用您的路径替换的script.sh
(通常建议/usr/local/bin这样做-可以通过直接命令say myscript替换为来执行"</path/to/script>")。

的示例示例script.sh

#!/bin/bash
<commands to be executed>
exit

结果: .desktop将启动文件,$HOME/.config/autostart从中执行脚本Exec=

因此,您可以在启动时运行所需的Shell脚本!



7

cron 实施的答案与最高票数不同

该答案仍然使用,cron但使用的方法与投票最高的答案不同。自Ubuntu 16.04起可以使用,但可能支持得更快。cron从16.04 开始启动计算机时,我只是开始使用它来运行作业。

什么时候cron运行?

在评论中有人问“他们什么时候跑?”。您可以在syslog / journalctl中告诉:

$ journalctl -b | grep cron
Jan 02 16:54:40 alien cron[919]: (CRON) INFO (pidfile fd = 3)
Jan 02 16:54:40 alien cron[919]: (CRON) INFO (Running @reboot jobs)
Jan 02 16:54:40 alien systemd[1]: Started Run anacron jobs.
Jan 02 16:54:40 alien anacron[949]: Anacron 2.3 started on 2018-01-02
Jan 02 16:54:40 alien anacron[949]: Normal exit (0 jobs run)
Jan 02 16:54:40 alien CRON[952]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 02 16:54:40 alien CRON[954]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 02 16:54:40 alien CRON[951]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 02 16:54:40 alien CRON[950]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 02 16:54:40 alien CRON[985]: (root) CMD (   /usr/local/bin/cron-reboot-cycle-grub-background)
Jan 02 16:54:40 alien CRON[954]: pam_unix(cron:session): session closed for user root
Jan 02 16:54:40 alien cron[919]: sendmail: Cannot open smtp.gmail.com:587
Jan 02 16:54:40 alien CRON[952]: pam_unix(cron:session): session closed for user root
Jan 02 16:54:40 alien cron[919]: sendmail: Cannot open smtp.gmail.com:587
Jan 02 16:54:40 alien CRON[950]: pam_unix(cron:session): session closed for user root

要注意的一件事是,cron可以通过电子邮件向您发送作业的运行状态和@reboot作业的运行情况,因此早期的网络管理器和电子邮件将不会运行,除非您sleep在脚本中输入命令。

放置脚本的位置

将您的脚本放在目录中/etc/cron.d

$ ll /etc/cron.d
total 44
drwxr-xr-x   2 root root  4096 Nov 26 19:53 ./
drwxr-xr-x 139 root root 12288 Dec 31 13:58 ../
-rw-r--r--   1 root root   244 Dec 28  2014 anacron
-rw-r--r--   1 root root   148 Feb 18  2017 cycle-grub-background
-rw-r--r--   1 root root   138 Mar  5  2017 display-auto-brightness
-rw-r--r--   1 root root   460 Nov 26 19:53 nvidia-hdmi-sound
-rw-r--r--   1 root root   102 Feb  9  2013 .placeholder
-rw-r--r--   1 root root   224 Nov 19  2016 touch-vmlinuz
-rw-r--r--   1 root root   700 Aug  5 11:15 turn-off-hyper-threading

脚本是什么样的?

这是我已设置为运行每次引导的几个脚本:

$ cat /etc/cron.d/cycle-grub-background SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 
@reboot   root    /usr/local/bin/cron-reboot-cycle-grub-background

$ cat /etc/cron.d/touch-vmlinuz
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
@reboot   root    touch "/boot/vmlinuz-"`uname -r`

1
添加cronjobs的方式有很多种,但是投票率很高的答案的核心仍然是@reboot
大师

添加crontab的替代方法应发布到askubuntu.com/q/2368/158442上,这显然是关于添加Cron作业的。
大师

1
我不敢苟同。有问题的答案的核心是利用crontab -e它,因为它具有类似vim的界面,因此有人认为这是一种妖术。另一方面,这个答案可能会吸引那些以某种方式连接大脑的人。我们并非都来自同一模具。再说一次,这个答案已经被否决了,所以我们让民主走她的路。
WinEunuuchs2Unix

2
哦拜托。您和我都知道可以更改编辑器。
大师

@muru是的,可能是因为您教了我,而且我学会了将编辑器更改为nano或其他几个CLI。但是我在电子战营地。除了crontab -e在星号(“ *”)的几分钟,几小时等时间内显示出星号(“ *”)的记忆,我一直在寻找Google指示。我仍然找到使用方法/etc/cron.d/etc/cron.daily然后选择了。特别是因为它是镜像/etc/udev/rules.d/etc/systemd/system-sleep方法。看起来很合适。
WinEunuuchs2Unix

5

您应该为此使用新贵。Upstart用于自动启动的Ubuntu进程。与旧的System-V init.d脚本一样,它是一个增强的解决方案。它还允许您在脚本开始处添加先决条件(即,是否需要网络运行?等)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.