bash 如何让这个 init.d 脚本在服务器重启时启动?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18680720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get this init.d script to start at server restart?
提问by st0rk
I'm following the directions on installing Redis on a production machine (CentOS using chkconfig).
我正在按照有关在生产机器(使用 chkconfig 的 CentOS)上安装 Redis 的说明进行操作。
The example script I was given requires the argument start
to actually start it, which it seems init.d does not do (pass arguments).
我给出的示例脚本需要参数start
来实际启动它,似乎 init.d 没有这样做(传递参数)。
The real command that must be run is /etc/init.d/redis_6379 start
, but what its actually calling is /etc/inti.d/redis_6379
, which simply says use start or stop as an argument
必须运行的真正的命令/etc/init.d/redis_6379 start
,但它是什么实际上调用的是/etc/inti.d/redis_6379
,这只是说use start or stop as an argument
Therefor, when my server reboots it doesnt actually start redis. What should I do here?
因此,当我的服务器重新启动时,它实际上并没有启动 redis。我应该在这里做什么?
Here is the initial config
这是初始配置
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
#
# chkconfig: - 85 15
# description: Redis is a persistent key-value database
# processname: redis_6379
REDISPORT=6379
EXEC=/usr/local/bin/redis-server
CLIEXEC=/usr/local/bin/redis-cli
PIDFILE=/var/run/redis_${REDISPORT}.pid
CONF="/etc/redis/${REDISPORT}.conf"
case "" in
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed"
else
echo "Starting Redis server..."
$EXEC $CONF
fi
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE does not exist, process is not running"
else
PID=$(cat $PIDFILE)
echo "Stopping ..."
$CLIEXEC -p $REDISPORT shutdown
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown ..."
sleep 1
done
echo "Redis stopped"
fi
;;
*)
echo "Please use start or stop as first argument"
;;
esac
回答by konsolebox
Make sure your script is added for service management by chkconfig
. Use chkconfig --list
to see the list and use chkconfig --add scriptname
if it's not there. After that configure the runlevels you want it to be called into. I would guess it's 3, 4 and 5 so: chkconfig --level 345 scriptname on
.
确保您的脚本已添加用于服务管理chkconfig
。使用chkconfig --list
查看列表和使用chkconfig --add scriptname
,如果它不存在。之后配置您希望它被调用的运行级别。我想这是3,4和5这样:chkconfig --level 345 scriptname on
。
回答by linux_fanatic
If you want to start a service through command line you can just add in /etc/rc.d/rc.local
too for the same instead of creating a service file in init.d.
如果您想通过命令行启动服务,您也可以添加/etc/rc.d/rc.local
相同的内容,而不是在 init.d 中创建服务文件。
回答by Aleks-Daniel Jakimenko-A.
You should tell us how exactly you are running the script from init.d
你应该告诉我们你是如何从 init.d 运行脚本的
But here is a dirty workaround:
但这是一个肮脏的解决方法:
Change the line
换线
start)
to
到
start|'')
This will make it start if there are no parameters passed.
如果没有传递参数,这将使其启动。
回答by bbaassssiiee
Centos redis has an init script with a chkconfig header line stating that it will start in all runlevels, which is very bad. chkconfig is used to manage the symlinks in /etc/rc.d
Centos redis 有一个 init 脚本,里面有一个 chkconfig 头行,说明它将在所有运行级别中启动,这是非常糟糕的。chkconfig 用于管理 /etc/rc.d 中的符号链接
# chkconfig: - 85 15
I suggest that redis is a service to run in level 3 after critical services have launched (sshd for instance). In your test scenario's reboot your server before going to production. If redis cannot launch (just happened here) you cannot boot it in another runlevel to fix it.
我建议 redis 是在关键服务启动后运行在级别 3 的服务(例如 sshd)。在您的测试场景中,在进入生产环境之前重启您的服务器。如果 redis 无法启动(刚刚发生在这里),您无法在另一个运行级别启动它来修复它。
If you implement the proper headers you can use init and also systemd (Fedora)
如果你实现了正确的头文件,你可以使用 init 和 systemd (Fedora)
回答by Dmitry Stolbov
Your should add code below to the script /etc/inti.d/redis_6379
. The status
argument is used by command service --status-all
.
您应该将下面的代码添加到脚本中/etc/inti.d/redis_6379
。该status
参数由 command 使用 service --status-all
。
# processname: redis_6379
# Source function library.
. /etc/init.d/functions
...
...
case "" in
status)
status -p $PIDFILE redis
script_result=$?
;;
回答by Bent Cardan
Init.d's days are numbered, wtf are you still reading this for? There's no more sudo service
, all the new kids are slapping down syscrtl
Init.d 的日子屈指可数了,你还在看这个吗?没有了sudo service
,所有的新孩子都在打耳光syscrtl
Nowadays like of course on my ubuntu 17.04 server at work, /etc/rc.local
didn't even exist
现在当然就像在我工作的 ubuntu 17.04 服务器上一样,/etc/rc.local
甚至不存在
Just write a new one!
只写一个新的!
rc.local
is awesome, especially combined with the unix style daemonize program... those two alone, I can pretty much call it a day.
rc.local
太棒了,尤其是与 unix 风格的daemonize 程序相结合......仅这两个,我几乎可以称之为一天。
However, if you want to take rc.local
to the next level, I'll cover basic ideas behind my own personal redis init.d script--same one we use on production servers across my company:
但是,如果您想rc.local
更上一层楼,我将介绍我自己的个人 redis init.d 脚本背后的基本思想——我们在我公司的生产服务器上使用的相同:
pre-empt redis complaint about system socket/file limits
slap in some linux perf and mess around with sysconf in persistent fashion
autopilot redis while i go take a nap
关于系统套接字/文件限制的抢先 redis 投诉
在某些 linux perf 中打耳光,并以持久的方式与 sysconf 混为一谈
我去打盹时自动驾驶 redis
#!/bin/sh
### BEGIN INIT INFO
# Provides: redis
# Required-Start: $syslog
# Required-Stop: $syslog
# Should-Start: $all
# Should-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: true
# Short-Description: start and stop redis
# Description: persistent key-value db
### END INIT INFO
NAME=redis
PATH=/opt/bin:/opt/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
EXEC=/opt/sbin/redis-server
CLIEXEC=/opt/sbin/redis-cli
CONF=/etc/$NAME/$NAME.conf
PIDFILE=/var/run/$NAME.pid
SOCKET=/var/run/$NAME.sock
PERF=/tmp/redis.sysctl
KERNELPG=/sys/kernel/mm/transparent_hugepage/enabled
[ -x /opt/sbin/redis-server ] || exit 0
set -e
# tune system for better redis performance
if [ ! -f $PERF ]; then
echo "tunning redis..." &>> $PERF
echo never > $KERNELPG && cat $KERNELPG &>> $PERF
sysctl -w net.core.somaxconn=65535 &>> $PERF
sysctl -w vm.overcommit_memory=1 &>> $PERF
echo "tuned." &>> $PERF && cat $PERF
fi
next, if we're doin' it right:
接下来,如果我们做得对:
let's have nice idiomatic case $money numbers, focused on starting and stopping without sorting through excessive PID tracking shenanigans
take advantage of the start-stop-daemon (i.e. can't get cut short by parent process death if there is no parent process)
让我们有很好的惯用案例 $money 数字,专注于启动和停止,而不需要通过过多的 PID 跟踪恶作剧进行分类
利用 start-stop-daemon(即,如果没有父进程,则不会因父进程死亡而缩短)
case in
start)
if [ ! -f $PIDFILE ]; then
echo -n "Starting $NAME: "
start-stop-daemon --start --pidfile $PIDFILE --exec $EXEC -- $CONF
echo "waiting for redis db to start..."
while [ ! -f $PIDFILE ]; do
sleep 0.1;
done
fi
PID=$(cat $PIDFILE)
echo "running with pid: $PID"
;;
stop)
if [ ! -f $PIDFILE ]; then
echo "redis is already stopped"
else
PID=$(cat $PIDFILE)
echo -n "Stopping $NAME: "
$CLIEXEC -s $SOCKET shutdown
echo "waiting for shutdown..."
while [ -x /proc/${PID} ]; do
sleep 0.1
done
echo "db stopped."
fi
;;
status)
if [ -f $PIDFILE ]; then
PID=$(cat $PIDFILE)
echo "running with pid: $PID"
else
echo "stopped."
fi
;;
restart|force-reload)
mkdir /etc/redis
echo 'daemonize yes' >> /etc/redis/redis.conf
echo 'pidfile /var/run/redis.pid' >> /etc/redis/redis.conf
stop && mkdir /etc/redis
vim /etc/redis/redis # keep it traditional, no .sh extensions here
# saving buffers from root all damn day...
chmod a+x /etc/init.d/redis
update-rc.d redis defaults
start
;;
*)
echo "Argument \"\" not implemented."
exit 2
;;
esac
exit 0
- edit
redis.conf
to designatedaemonize yes
. Make redis the primary responsible party for administrative PID file state (in case you were wondering why we didn't have to do anything with it in the script, except read from it if it's around)
- 编辑
redis.conf
指定daemonize yes
。使 redis 成为管理 PID 文件状态的主要责任方(以防你想知道为什么我们不必在脚本中对它做任何事情,除非在它周围时读取它)
- update your rc entry by name after copying and setting execution bits:
- 在复制和设置执行位后按名称更新您的 rc 条目:
- Here's the full example linkw/ service installer. Again, be sure to edit
conf
andinstall
to suit you. Most people would probably want to remove the listening file path in favor of TCP stack w/ redis port number open for client(s),
- 这是带有服务安装程序的完整示例链接。同样,一定要编辑
conf
并install
适合您。大多数人可能希望删除侦听文件路径,以支持为客户端打开的带有 redis 端口号的 TCP 堆栈,