如何在启动时运行Shell脚本


366

Amazon S3 Linux实例上,我有两个名为的脚本start_my_appstop_my_app它们永远启动和停止(依次运行Node.js应用程序)。我使用这些脚本手动启动和停止我的Node.js应用程序。到目前为止,一切都很好。

我的问题:我还想将其设置start_my_app为在系统启动时运行。我知道我需要在其中添加文件,init.d并且知道如何将其符号链接到其中的适当目录rc.d,但是我无法弄清楚放置在其中的文件中实际需要什么init.d。我想这应该只是一行,例如start_my_app,,但这对我没有用。


5
我不是这类专家,但是我认为init.d解决方案(here)应该比rc.local解决方案更可取,因为后者是旧工具,但仍可以使用,因为新工具向后兼容。
erikbwork

pm2启动my_app; pm2启动;pm2
Unitech

Answers:


292

在您放入的文件中,/etc/init.d/您必须使用以下命令将其设置为可执行文件:

chmod +x /etc/init.d/start_my_app

感谢@meetamit,如果此命令无法运行,则必须创建一个符号链接到 /etc/rc.d/

ln -s /etc/init.d/start_my_app /etc/rc.d/

请注意,在最新的Debian上,这将不起作用,因为您的脚本必须符合LSB(至少提供以下操作:启动,停止,重启,强制重载和状态): https://wiki.debian .org / LSBInitScripts

需要注意的是,您应该放置脚本的绝对路径而不是相对路径,这可能会解决意外的问题:

/var/myscripts/start_my_app

并且不要忘记在该文件之上添加:

#!/bin/sh

6
我做到了,它没有运行。它会仅因为它在/etc/init.d中而自动运行,还是我需要做一些事情来安排它在系统启动时运行?
两栖游戏

4
@amphibient还不够...您还需要创建一个指向此文件的符号链接(使用ln命令),指向该目录中的目录rc.d
metamit 2014年

23
我的根目录的etc文件夹中没有rc.d目录。.这让我傻眼了,这不是Linux需要启动的关键目录吗?它只是缺少一个我的操作系统似乎运行良好。我必须创建它吗?我看到一堆类似命名的文件,例如“ rc1.d”,一直到“ rc5.d”
OKGimmeMoney 2015年

3
我没有任何/etc/rc.d文件夹,但我有/etc/rcX.d文件夹(即/etc/rc0.d/etc/rc1.d/etc/rcS.d),也有一个文件的/etc/rc.local。我认为您应该在自定义文件夹中/etc/rc9.d或在现有文件夹之一中创建符号链接...(Ubuntu Server 14.04)
F8ER

2

343

为此设置一个crontab

#crontab -e
@reboot  /home/user/test.sh

每次启动后,它将运行测试脚本。


4
这是唯一对我有效的解决方案!谢谢
whoopididoo

20
这是最好的解决方案, @reboot sh $HOME/test.sh在crontab中更干净
user3667089

4
@ user3667089实际上,它不起作用。我打开终端,输入“ crontab -e”,出现一个窗口,我在其中写入“ @reboot sh /home/user/test.sh”,但启动时未运行。我在哪里做错了?
MycrofD

@ user3667089通常的默认行'#将此文件编辑为...',然后我写的行'@reboot sh /home/.../.sh'。我也尝试了“ @reboot /home/.../.sh”,但没有初始的“ sh”,但没有结果。
MycrofD

3
crontab -l应该显示@MycrofD,@reboot sh $HOME/test.sh以确认它实际上已设置。
user3667089

124

一种简单的方法是在中添加一行/etc/rc.local

/PATH/TO/MY_APP &

或者如果您想以特殊用户身份运行命令:

su - USER_FOOBAR -c /PATH/TO/MY_APP &

(结尾的“&”号使进程成为后台,并允许rc.local继续执行)

如果您想要一个完整的初始化脚本,那么debian distro有一个模板文件,因此:

cp /etc/init.d/skeleton /etc/init.d/your_app

并适应它。


2
谢谢!考虑到简单的要求,这种方法最有效。我敢肯定,我DID需要指定用户,否则,当需要手动停止应用程序(通过运行stop_my_app)时,我必须使用sudo,否?另外,我想知道后面的&符号到底是什么功能。
Meetamit 2012年

3
用户取决于您的应用程序。但是,如果不是绝对需要以root身份运行,请避免使用它。&在后台运行该过程
Gilles Quenot 2012年

2
sputnick,对不起,但是我得将Koren的答案标记为可接受的答案,主要是因为@ erikb85指出了什么,还因为我最初的问题要求init.d做事的方式(您的答案当时对我来说只是一个更简单的解决方法) 。这篇文章获得了很多意见和投票,因此保持准确性很重要。
metamit

4
似乎没有提到尾随的&符使该进程成为后台,并允许rc.local继续执行。
mchicago 2014年

谢谢你!当我尝试提供服务时,花了最后几个小时将我的头撞在墙上,但没有任何效果。试过这个,像魅力一样!
MarkoGrešak2015年

34

这就是我在Red Hat Linux系统上执行此操作的方式。

将您的脚本放入/etc/init.d,由根和可执行文件拥有。在脚本顶部,您可以给指令chkconfig。例如,以下脚本用于以oracle用户身份启动Java应用程序。

该脚本的名称是 /etc/init.d/apex

#!/bin/bash
# chkconfig: 345 99 10
# Description: auto start apex listener
#
case "$1" in
 'start')
   su - oracle -c "cd /opt/apex ; java -jar apex.war > logs/apex.log 2>logs/apex_error.log &";;
 'stop')
   echo "put something to shutdown or kill the process here";;
esac

这表示脚本必须在3、4和5级运行,启动/停止的优先级为99和10。

然后,root您可以chkconfig以用户身份在启动时启用或禁用脚本:

chkconfig --list apex
chkconfig --add apex

您可以使用service start/stop apex


同时,我尝试了一个名为supervisor(supervisor.org)的软件包,该软件包可在epel存储库中找到。它可用于启动程序和监视程序,并在出现故障时重新启动它们。
2014年

将脚本放入/etc/init.d/文件夹后,无需输入:“ chkconfig --add service_name”,您可以输入:“ chkconfig service_name on”
Dragan Radevic

21

输入cron使用sudo

sudo crontab -e

添加一个在启动时运行的命令,在这种情况下为脚本:

@reboot sh /home/user/test.sh

救:

按ESC,然后按:x保存并退出,或者按ESC再按ZZ(即shift + zz)

测试测试测试

  1. 在不使用cron的情况下运行测试脚本,以确保其确实有效。

  2. 确保将命令保存在cron中,使用 sudo crontab -e

  3. 重新启动服务器以确认一切正常 sudo @reboot


我非常喜欢这个。谢谢!附言 sudo如果要使用当前用户在启动过程中运行某个命令,请不要使用。
危险'18

该信息应存储在哪里?不在/tmp??
彼得·莫滕森

15

只需在crontab中添加一行即可。

确保文件是可执行文件:

chmod +x /path_to_you_file/your_file

要编辑crontab文件:

crontab -e

您必须添加的行:

@reboot  /path_to_you_file/your_file

这么简单!


这对我不起作用,我想念什么吗?# uname -a Linux accton-xp70a0-26-a1 3.11.10-301.fc20.x86_64 #1 SMP Thu Dec 5 14:01:17 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

这在CentOs 7上对我有用。对于有问题的人,我确实需要创建一个shell脚本,使其可执行(chmod + x file_name),然后从cron调用该shell脚本,然后依次调用节点path_to_file / index.js。
SeanOlson

11

另一种选择是在crontab中使用@reboot命令。

并非每个版本的cron都支持此功能,但是如果您的实例基于Amazon Linux AMI,它将可以正常工作。


6

你能行的 :

chmod +x PATH_TO_YOUR_SCRIPT/start_my_app 

然后使用此命令

update-rc.d start_my_app defaults 100

请参阅Cyber​​citi上的此页面。


1
我有一个基于yocto的漂亮的准系统设置,这是使我的脚本东西工作的唯一方法。谢谢。
Catalin Vasile

3

创建自己的/ init可执行文件

这不是您想要的,但很有趣!

只需选择一个任意的可执行文件,甚至是一个shell脚本,然后使用命令行参数启动内核即可:

init=/path/to/myinit

在启动快要结束时,Linux内核在给定路径上运行第一个用户空间可执行文件。

几个项目很受欢迎 init了主要发行版(例如systemd)使用的可执行文件,在大多数发行版中,init都会派生一堆用于正常系统操作的进程。

但是我们可以劫持 /init它以运行我们自己的最小脚本,以更好地了解我们的系统。

这是一个最小的可重复设置:https : //github.com/cirosantilli/linux-kernel-module-cheat/tree/f96d4d55c9caa7c0862991025e1291c48c33e3d9/README.md#custom-init


2

这个简单的解决方案在运行CentOS的Amazon Linux实例上为我工作。编辑/etc/rc.d/rc.local文件,然后将命令放在此处。在该文件中提到它将所有其他初始化脚本之后执行。因此,在这方面要小心。这是文件当前向我显示的方式。在此处输入图片说明。最后一行是我的脚本的名称。


1

如果您要运行的只是一个简单的脚本,则绝对是最简单的方法(或其他任何方法),如果您有使用系统>首选项的gui,则可以启动应用程序。

只需浏览至所需的脚本即可。(使脚本可执行)


3
这实际上不是在启动时运行的,而是在登录时运行的,这是一个很大的差异。这也取决于特定的设置,因为您不会在每个系统(特别是不是服务器)上都具有“系统>首选项”。
jazzpi

搜索字词“ Linux在启动时执行”使我想到了这个答案。即使它不能回答OP的问题,这也可能对像我这样的linux(ubuntu)菜鸟有所帮助,因此值得推荐。我也不喜欢,但这是实用主义。
thymaro


1

在卢本图,我不得不处理相反的情况。引导后Skype开始运行,我在~/.config/autostart/文件中找到了skypeforlinux.desktop。该文件的内容如下:

[Desktop Entry]
Name=Skype for Linux
Comment=Skype Internet Telephony
Exec=/usr/bin/skypeforlinux
Icon=skypeforlinux
Terminal=false
Type=Application
StartupNotify=false
X-GNOME-Autostart-enabled=true

删除该文件对我有帮助。


0
  • 将脚本添加到/etc/init.d/目录
  • 更新您的rc运行级别: $ update-rc.d myScript.sh defaults NNNN是应该执行的顺序。例如99表示它将在98之后100之前运行。

0

使用Python 3微服务或shell;使用Ubuntu Server 18.04(Bionic Beaver)或Ubuntu 19.10(Eoan Ermine)或Ubuntu 18.10(Cosmic Cuttlefish ),我总是喜欢这些步骤,并且它也总是有效

  1. 在我的案例中,创建一个名为p的微服务示例“ brain_microservice1.service”:

    $ nano /lib/systemd/system/brain_microservice1.service
  2. 在此新服务内:

    [Unit]
    Description=brain_microservice_1
    After=multi-user.target
    
    [Service]
    Type=simple
    ExecStart=/usr/bin/python3.7 /root/scriptsPython/RUN_SERVICES/microservices    /microservice_1.py -k start -DFOREGROUND
    ExecStop=/usr/bin/python3.7 /root/scriptsPython/RUN_SERVICES/microservices/microservice_1.py -k graceful-stop
    ExecReload=/usr/bin/python3.7 /root/scriptsPython/RUN_SERVICES/microservices/microservice_1.py -k graceful
    PrivateTmp=true
    LimitNOFILE=infinity
    KillMode=mixed
    Restart=on-failure
    RestartSec=5s
    
    [Install]
    WantedBy=multi-user.target
  3. 授予权限:

    $ chmod -X /lib/systemd/system/brain_microservice*
    $ chmod -R 775 /lib/systemd/system/brain_microservice*
  4. 然后授予执行权限:

    $ systemctl daemon-reload
  5. 然后启用,这将使它始终在启动时开始

    $ systemctl enable brain_microservice1.service
  6. 然后您可以对其进行测试;

    $ sudo现在重启

  7. 完成=成功!!

可以使用相同的主体脚本来运行外壳,进行反应...数据库启动脚本...任何类型的OS代码...希望对您有所帮助...

...



0

这是一个更简单的方法!

第一:编写一个shell脚本并将其保存为.sh,这是一个示例

#!/bin/bash
Icoff='/home/akbar/keyboardONOFF/icon/Dt6hQ.png'
id=13
fconfig=".keyboard"
echo "disabled" > $fconfig
xinput float $id
notify-send -i $Icoff "Internal Keyboard disabled";

此脚本将在启动时禁用内部键盘。

第二:打开应用程序“启动应用程序首选项”

在此处输入图片说明

在此处输入图片说明

第三:单击添加。第四:在“名称”部分输入名称。第五:在命令部分中浏览到.sh。第六:将命令部分编辑为:

bash <space> path/to/file/<filename>.sh <space> --start

第七:单击添加。而已!完蛋了!

现在,通过重新启动PC进行确认。

干杯!


-1

无痛,最简单,最通用的方法就是简单地使用~.bash_profileor ~.profile (如果没有bash_profile文件)执行它。

只需在该文件的底部添加执行命令,它将在系统启动时执行。

我在底部有一个示例。 ~\Desktop\sound_fixer.sh


2
那是不正确的。~/.bash_profile在用户登录时执行- 不在系统启动时执行。在最初的问题中,目的是在计算机启动时运行Node.js应用服务器。您的解决方案将要求人类用户在Node.js服务器运行之前首先登录计算机。而且,如果某种问题导致服务器在一夜之间重新启动,则该应用程序将永远无法恢复运行,直到人类重新登录为止
。– metamit

-6

对于某些人来说,这将起作用:

您可以简单地将以下命令添加到系统首选项启动应用程序中

bash /full/path/to/your/script.sh

我在系统偏好设置菜单中没有看到此信息。但是我在应用程序启动器中搜索时确实看到了它。
OKGimmeMoney 2015年

这实际上不是在启动时运行的,而是在登录时运行的,这是一个很大的差异。这也取决于特定的设置,因为您不会在每个系统(特别是不是服务器)上都具有“系统>首选项”。
jazzpi,2015年

3
对于Ubuntu / Linux桌面,此答案似乎更多,但用户实际上正在请求有关AWS EC2 Linux实例的帮助,据我所知,该实例没有GUI。
Vini.g.fer
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.