使用rc.local运行脚本:脚本可以工作,但不能在启动时运行

时间:2011-10-16 09:10:07

标签: linux bash ubuntu boot autorun

我有一个node.js脚本需要在www-data用户下的boot 下运行。在开发过程中,我始终使用以下命令启动脚本:

su www-data -c 'node /var/www/php-jobs/manager.js

我看到发生了什么,manager.js现在很棒。搜索我发现我必须将其放在我的/etc/rc.local中。另外,我学会了将输出指向一个日志文件,并将2>&1附加到“将stderr重定向到stdout”,它应该是一个守护进程,所以最后一个字符是&

最后,我的/etc/rc.local看起来像这样:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

su www-data -c 'node /var/www/php-jobs/manager.js >> /var/log/php-jobs.log 2>&1 &'

exit 0

如果我自己运行(sudo /etc/rc.local):是的,它有效!但是,如果我执行重新启动没有node进程正在运行,则/var/log/php-jobs.log不存在,因此,manager.js不起作用。发生了什么事?

17 个答案:

答案 0 :(得分:69)

在这个rc.local脚本示例中,我在第一行执行时使用io重定向到我自己的日志文件中:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

exec 2> /tmp/rc.local.log  # send stderr from rc.local to a log file
exec 1>&2                      # send stdout to the same log file
set -x                         # tell sh to display commands before execution

/opt/stuff/somefancy.error.script.sh

exit 0

答案 1 :(得分:10)

在某些Linux(例如Centos& RH)上,/etc/rc.local最初只是/etc/rc.d/rc.local的符号链接。在这些系统上,如果符号链接断开,并且/etc/rc.local是一个单独的文件,则在启动时将无法看到对/etc/rc.local的更改 - 启动过程将在{{1 }}。 (如果手动运行/etc/rc.d,它们将起作用,但不会在启动时运行。)

听起来像dimadima的系统,它们是单独的文件,但/etc/rc.local调用/etc/rc.d/rc.local

如果将/etc/rc.local移动到备份目录并将其复制回来或从头开始创建,/etc/rc.local/etc/rc.d到'{1}}中的符号链接可能会丢失在rc.local中实现原始的只是一个符号链接。

答案 2 :(得分:5)

我最终得到upstart,效果很好。

答案 3 :(得分:5)

在Ubuntu中,我注意到有2个文件。真实的是/etc/init.d/rc.local;看来另一个/etc/rc.local是假的?

一旦我修改了正确的(/etc/init.d/rc.local),它就会按预期执行。

答案 4 :(得分:4)

您可能还通过指定节点的完整路径使其工作。此外,当您想要作为守护程序运行shell命令时,您应该通过在&前添加1<& - 来关闭stdin。

答案 5 :(得分:2)

如果您在云上使用Linux,那么通常您没有机会用手触摸真实硬件。所以你第一次启动时看不到配置界面,当然也无法配置它。因此,firstboot服务始终会在rc.local之内。解决方案是通过执行以下操作来禁用firstboot

sudo chkconfig firstboot off

如果您不确定为什么rc.local没有运行,您可以随时从/etc/rc.d/rc文件进行检查,因为此文件将始终运行并调用其他子系统(例如rc.local)。

答案 6 :(得分:2)

我有同样的问题(在CentOS 7上),我通过给/ etc / local赋予执行权限来修复它:

chmod +x /etc/rc.local

答案 7 :(得分:1)

我通过编辑/etc/rc.local然后发出以下3个命令让我的脚本工作。

sudo mv /filename /etc/init.d/
sudo chmod +x /etc/init.d/filename 
sudo update-rc.d filename defaults

现在脚本在启动时工作。

答案 8 :(得分:1)

我正在使用CentOS 7.

$ cd  /etc/profile.d

$ vim yourstuffs.sh

在yourstuffs.sh脚本中键入以下内容。

输入您要执行的任何内容

export LD_LIBRARY_PATH=/usr/local/cuda-7.0/lib64:$LD_LIBRARY_PATH

保存并重新启动操作系统。

答案 9 :(得分:0)

这很可能是由于PATH环境变量丢失或不完整引起的。

如果您提供可执行文件(su和节点)的完整绝对路径,它将起作用。

答案 10 :(得分:0)

我的理解是,如果您将脚本放在某个RUN级别,则应使用ln -s将脚本链接到您希望它工作的级别。

答案 11 :(得分:0)

我过去使用过rc.local。但是我从我的经验中了解到,在系统启动时运行脚本的最可靠方法是在crontab中使用 @reboot 命令。例如:

@reboot path_to_the_start_up_script.sh

答案 12 :(得分:0)

首先使用以下命令使脚本可执行 sudo chmod 755 /path/of/the/file.sh 现在将脚本添加到rc.local中 sh /path/of/the/file.sh 在0号出口之前 在rc.local中, 接下来使rc.local可执行 sudo chmod 755 /etc/rc.local 接下来初始化rc.local使用 sudo /etc/init.d/rc.local start 这将启动rc.local 现在重新启动系统。 完成..

答案 13 :(得分:0)

我发现,由于我在rc.local中使用了面向网络的命令,因此有时会失败。我通过在脚本的顶部放置sleep 3来解决此问题。我不知道为什么,但是似乎在运行脚本时,网络接口未正确配置或某些东西,这只为DHCP服务器提供了一些时间。我不太了解,但我想您可以尝试一下。

答案 14 :(得分:0)

我遇到了完全相同的问题,脚本在本地运行良好,但当我重新启动/开机时却没有。

我通过更改文件路径解决了这个问题。基本上需要在脚本中给出完整的路径。在本地运行时,可以访问文件,但在重启时运行时,将无法理解本地路径。

答案 15 :(得分:-1)

1不建议使用root来运行节点应用程序等应用程序。

嗯,你可以做到,但可能会遇到更多例外。

2 rc.local通常以root用户身份运行。

因此,如果您的脚本应该像另一个用户(例如www U)那样运行,请确保PATH和其他环境正常。

3我找到了一种以用户身份运行服务的简便方法:

sudo -u www -i / / path / of / your / script

请选择sudo手册〜        -i [命令]                    -i(模拟初始登录)选项将目标用户的密码数据库条目指定的shell作为loginshell运行...

答案 16 :(得分:-3)

rc.local仅在启动时运行。如果您重新启动并希望脚本执行,则需要进入以K99前缀开头的rc.0文件。