如何在启动时运行脚本?

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

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

  1. 跑步 crontab -e 将允许您编辑您的cron。
  2. 在上面添加一条这样的行:

    @reboot /path/to/script

    一旦您的计算机启动,将执行该脚本。

取决于你需要运行什么样的脚本。. 对于你应该使用的服务和类似的东西 新贵. 但是对于用户脚本,这些应该作为gnome的会话脚本启动! 看看系统>首选项>启动应用程序.

另外,如果您需要在终端登录上运行一些脚本,您可以将它们添加到 .巴什*洛金 文件在您的主目录。

适用于14.04及以上

一个简单的命令(一个不需要保持运行的命令)可以使用像:

start on startuptaskexec /path/to/command

保存在一个 .conf 档案在 /etc/init (如果您需要它在系统启动时以root身份运行),或在 ~/.config/upstart (如果您需要在登录时以您的用户身份运行)。

您可以将命令添加到 /etc/rc.local:

sudo nano /etc/rc.local

这将以root身份执行命令。

要以特定用户身份执行命令,请使用 sudo -i -u (-i 以还运行登录shell)。 例如,要建立持久SSH隧道,其中 myhost 定义在 johndoes ~/.ssh/config 档案:

sudo -i -u johndoe autossh -nNT -L 1234:localhost:1234 myhost

请注意,如果 /etc/rc.local 不存在(就像16.04以来在Ubuntu上的情况一样),您需要添加一个 舍邦线 在顶部(例如 #!/bin/bash),并确保文件是可执行的:

sudo chmod a+x /etc/rc.local

对于15.04及更高版本:

运行一个(短暂的)1 使用启动时的命令 systemd,您可以使用类型的systemd单元 OneShot. 例如,创建 /etc/systemd/system/foo.service 包含:

[Unit]Description=Job that runs your user script[Service]ExecStart=/some/commandType=oneshotRemainAfterExit=yes[Install]WantedBy=multi-user.target

然后运行:

sudo systemctl daemon-reloadsudo systemctl enable foo.service

从本质上讲,这只是转换 一个典型的暴发户工作 到一个systemd一个(见 新贵用户的Systemd).

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

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

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

有关:


对于用户会话,您可以在 ~/.config/systemd 相反。 这应该适用于16.04以后,但不适用于systemd的Ubuntu早期版本(因为那些仍然使用Upstart进行用户会话)。 用户会话单元可以用与系统服务相同的命令来控制,但可以用 --user 选项添加:

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

Shell语法

请注意,与Upstart不同,systemd不会运行 Exec* 通过shell命令。 它执行一些有限的变量扩展和多个命令(由 ;)本身,但就类似shell的语法而言,这就是它。 对于任何更复杂的事情,比如重定向或管道,将您的命令包装在 sh -c '...'bash -c '...'.


1而不是长寿的守护进程。

有不同的方法可以自动运行命令:

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

    你可以找到一个可读的介绍: http://upstart.ubuntu.com/getting-started.html 人页 man 5 initman 8 init 给你完整的细节。

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

    请注意,会话直到 .gnomerc 脚本完成;因此,如果你想自动启动一些长时间运行的程序,你需要追加 & 到程序调用,以便将其与正在运行的shell分离。

  3. 菜单选项 系统->首选项->启动应用程序 允许您定义在图形会话启动时应该启动哪些应用程序(Ubuntu预定义了相当多),并根据您的口味添加或删除它们。 这具有几乎相同的目的和范围的 .gnomerc 脚本,除非你不需要知道 sh 语法(但你也不能使用任何 sh 编程构造)。

$HOME/.config/autostart 包含启动应用程序列表。 .desktop 此文件夹中的文件将在启动时执行。 它可能需要可执行权限(chmod +x startup.desktop).

示例示例 .desktop 档案:

[Desktop Entry]Type=ApplicationExec="</path/to/script>"Hidden=falseNoDisplay=falseX-GNOME-Autostart-enabled=trueName=Startup Script

这里 "</path/to/script>" 被替换为您的路径 script.sh如果你把你的脚本 myscript/usr/local/bin 这样就可以直接通过命令执行了,可以写 myscript 而不是 "</path/to/script>".

示例示例 myscript.sh:

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

结果:.desktop 文件将从 $HOME/.config/autostart 哪个执行脚本 Exec=

对于简单的事情,你可以在 >>系统-首选项-会话 指向脚本的位置。

或者,您可以将其添加到/etc/init。d/rc。本地或制作 新贵 工作,如果它是一个更 低水平 东西。

看看 https://help.ubuntu.com/community/UbuntuBootupHowto 有关更多资料

cron 答案与顶级投票不同

这个答案仍然使用 cron 但使用的方法与投票最多的答案不同。 这自Ubuntu16.04以来一直有效,但可能支持得更快。 只是我开始用 cron 从16.04开始,计算机启动时运行作业.

什么时候? cron 跑?

在评论中有人问"他们什么时候跑?". 你可以在syslog/journalctl告诉:

$ journalctl -b | grep cronJan 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-02Jan 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 rootJan 02 16:54:40 alien cron[919]: sendmail: Cannot open smtp.gmail.com:587Jan 02 16:54:40 alien CRON[952]: pam_unix(cron:session): session closed for user rootJan 02 16:54:40 alien cron[919]: sendmail: Cannot open smtp.gmail.com:587Jan 02 16:54:40 alien CRON[950]: pam_unix(cron:session): session closed for user root

有一点需要注意的是 cron 可以通过电子邮件向您发送作业运行状态和 @reboot 作业运行这么早网络管理器和电子邮件不会运行,除非你把一个 sleep 命令到你的脚本(s)。

把你的脚本放在哪里

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

$ ll /etc/cron.dtotal 44drwxr-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/shPATH=/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-vmlinuzSHELL=/bin/shPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin@reboot   root    touch "/boot/vmlinuz-"`uname -r`

你应该使用 新贵 为了这个。 Upstart用于自动启动的Ubuntu进程。 它是一个增强的解决方案,就像旧的System-V init一样。d脚本。 它还允许您在脚本开始时输入先决条件(即您需要网络运行吗? 等。)

如果您希望您的脚本在内核启动后在systemd之前运行,那么AFAIK的方式是添加 init=/path/to/script 到内核命令行 /boot/grub/grub.cfg 或更多的未来证明使自己的菜单项在 /etc/grub.d/40_custom 通过从复制菜单项 /boot/grub/grub.cfg 并进行所需的更改(和运行 update-grub 之后为 grub 将自定义文件添加到 /boot/grub/grub.cfg).

linux   /boot/vmlinuz-5.4.0-26-generic ... ro  quiet splash 

更改为

linux   /boot/vmlinuz-5.4.0-26-generic ... ro  quiet splash init=/path/to/script

注意正确地放置例如 #!/bin/bash 在第一行和 exec /sbin/init (如果 /sbin/init 存在于你的系统上-在我的系统上它指向systemd),以避免内核恐慌。

如果有人也可以同时显示何时何地,那将是真棒。 我这样说是因为我知道至少有2种方法可以启动一个脚本,该脚本将在其他应用程序启动之前触发(如X11)

+1到@GabrielFair。 问题的很大一部分是原来的问题和答案是十岁。 我还要补充一点,解决这个问题的方法太多了。 Unix哲学的简单性发生了什么?! 请求某人知识渊博并有足够的分数重写这篇文章,或者为现代操作系统版本添加一个新的,最新的,明确的答案。

这整个答案线程是一团糟。 堆栈交换格式似乎不适合这个问题