[英]Run script with rc.local: script works, but not at boot
我有一个 node.js 脚本,它需要在启动时启动并在 www-data 用户下运行。 在开发过程中,我总是用以下方式启动脚本:
su www-data -c 'node /var/www/php-jobs/manager.js
我确切地看到了发生了什么,manager.js 现在很好用。 搜索 SO 我发现我必须把它放在我的/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 不起作用。 怎么了?
在这个 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
在某些 linux(例如 Centos 和 RH)上, /etc/rc.local
最初只是指向/etc/rc.d/rc.local
的符号链接。 在这些系统中,如果符号链接被打破,并/etc/rc.local
是一个单独的文件,然后改到/etc/rc.local
将不会在启动时看到-在启动过程中会在运行版本/etc/rc.d
。 (如果手动运行/etc/rc.local
它们会工作,但不会在启动时运行。)
听起来像在 dimadima 的系统上,它们是单独的文件,但是/etc/rc.d/rc.local
调用/etc/rc.local
从符号链接/etc/rc.local
在“真正的”一个/etc/rc.d
可能会丢失,如果一个移动rc.local
到一个备份目录并将它放回或从头创建它,并没有意识到原来/etc
中的一个只是一个符号链接。
在 Ubuntu 中,我注意到有 2 个文件。 真正的一个是/etc/init.d/rc.local
; 似乎其他/etc/rc.local
是假的?
一旦我修改了正确的( /etc/init.d/rc.local
),它确实按预期执行。
我最终得到了upstart ,效果很好。
您可能还通过指定节点的完整路径使其工作。 此外,当您想将 shell 命令作为守护程序运行时,您应该通过在 & 之前添加 1<&- 来关闭 stdin。
我遇到了同样的问题(在 CentOS 7 上),我通过向 /etc/local 授予执行权限来修复它:
chmod +x /etc/rc.local
如果您在云上使用 linux,那么通常您没有机会用手触摸真正的硬件。 所以第一次开机是看不到配置界面的,当然也不能配置。 因此, firstboot
服务将始终阻碍rc.local
。 解决方案是通过执行以下操作禁用firstboot
:
sudo chkconfig firstboot off
如果您不确定为什么您的rc.local
不运行,您可以随时从/etc/rc.d/rc
文件中检查,因为该文件将始终运行并调用其他子系统(例如 rc.local)。
我通过编辑/etc/rc.local
然后发出以下 3 个命令来使我的脚本工作。
sudo mv /filename /etc/init.d/
sudo chmod +x /etc/init.d/filename
sudo update-rc.d filename defaults
现在脚本在启动时工作。
我正在使用 CentOS 7。
$ cd /etc/profile.d
$ vim yourstuffs.sh
在 yourstuffs.sh 脚本中输入以下内容。
在此处输入您想要执行的任何内容
export LD_LIBRARY_PATH=/usr/local/cuda-7.0/lib64:$LD_LIBRARY_PATH
保存并重新启动操作系统。
我过去使用过 rc.local。 但是我从我的经验中了解到,在系统启动时运行脚本的最可靠方法是在 crontab 中使用@reboot命令。 例如:
@reboot path_to_the_start_up_script.sh
这很可能是由缺少或不完整的 PATH 环境变量引起的。
如果您提供可执行文件(su 和 node)的完整绝对路径,它将起作用。
我的理解是,如果您将脚本放在某个 RUN 级别,则应该使用 ln -s 将脚本链接到您希望它在其中工作的级别。
首先使用sudo chmod 755 /path/of/the/file.sh
使脚本可执行,现在将脚本添加到 rc.local sh /path/of/the/file.sh
然后在 rc.local 中退出 0,接下来进行rc.local 可执行sudo chmod 755 /etc/rc.local
接下来初始化 rc.local 使用sudo /etc/init.d/rc.local start
这将启动 rc.local 现在重新启动系统。 完毕..
我发现因为我在rc.local
使用了面向网络的命令,所以有时它会失败。 我通过将sleep 3
放在脚本顶部来解决此问题。 我不知道为什么,但似乎当脚本运行时网络接口没有正确配置或其他什么,这只是为 DHCP 服务器或其他东西留出一些时间。 我不完全明白,但我想你可以试一试。
我遇到了完全相同的问题,脚本在本地运行良好,但是当我重新启动/开机时却没有。
我通过更改文件路径解决了这个问题。 基本上需要在脚本中给出完整的路径。 在本地运行时,可以访问文件,但在重新启动时运行时,将无法理解本地路径。
好吧,您可以这样做,但可能会捕获更多异常。
因此,如果您的脚本应以其他用户身份运行,例如 www U 应确保 PATH 和其他环境正常。
sudo -u www -i /the/path/of/your/script
请首选sudo手册~ -i [命令] -i(模拟初始登录)选项运行目标用户的密码数据库条目指定的shell作为登录shell...
rc.local
仅在启动时运行。 如果您重新启动并希望脚本执行,它需要进入以 K99 前缀开头的rc.0
文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.