用于 autossh 的 Bash 初始化脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9296686/
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
Bash init script for autossh
提问by PvdL
I'm trying to create a script that will launch autosshon boot through an init script, but I can't get it to work. I would like to see that it logs all of its actions, since it was not working properly, but that isn't going that well ether. Since I'm not a pro in bashI hope my code isn't horribly embarrassing.
我正在尝试创建一个脚本,该脚本将autossh通过 init 脚本在启动时启动,但我无法让它工作。我想看到它记录了它的所有操作,因为它没有正常工作,但以太坊的情况并不是那么好。由于我不是专业人士,bash我希望我的代码不会太尴尬。
#!/bin/sh
#
# by Patrick van der Leer <[email protected]>
# released under GPL, version 2 or later
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON="/usr/bin/autossh"
DESC="Autossh job"
PIDFOLDER="/var/run/autossh"
PIDFOLDERSSH="$PIDFOLDER/ssh"
REMOTE_USER=""
REMOTE_ADDR=""
LOGFILE="/var/log/autossh.log"
if [ ! -d $PIDFOLDER ] ; then
mkdir -p $PIDFOLDER
fi
if [ ! -d $PIDFOLDERSSH ] ; then
mkdir -p $PIDFOLDERSSH
fi
test -f $DAEMON || exit 0
. /lib/lsb/init-functions
PIDFILE="$PIDFOLDER/$REMOTE_USER-$REMOTE_ADDR.pid"
PIDFILESSH="$PIDFOLDERSSH/$REMOTE_USER-$REMOTE_ADDR.pid"
is_running() {
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if [ -n "$PID" ]; then
return 0
else
return 1
fi
else
return 1
fi
}
start_autossh() {
if ! is_running; then
echo "Starting $DESC"
export AUTOSSH_FIRST_POLL=10
export AUTOSSH_POLL=60
export AUTOSSH_PIDFILE=$PIDFILESSH
start-stop-daemon --start --make-pidfile --pidfile $PIDFILE --exec $DAEMON -- -M 29000 -i /root/.ssh/id_rsa -X -C -R 2222:localhost:22 $REMOTE_USER@$REMOTE_ADDR >> $LOGFILE 2>&1 &
sleep 1;
if ! is_running; then
echo "$DESC: running @ pid $PID"
else
echo 'Something went wrong';
fi
else
echo "$DESC: already running (pid $PID)"
fi
}
stop_autossh() {
if is_running; then
echo "Stopping $DESC"
start-stop-daemon --stop --pidfile $PIDFILE --signal 15
if [ -f $PIDSSHFILE ]; then
PIDSSH=`cat $PIDFILESSH`
kill $PIDSSH
rm -f $PIDFILESSH
fi
else
echo "$DESC: not running"
fi
[ -f $PIDFILE ] && rm -f $PIDFILE
}
case "" in
start)
start_autossh
;;
stop)
stop_autossh
;;
force-reload|restart)
stop_autossh
start_autossh
;;
status)
if is_running; then
echo "$DESC: running (pid $PID)"
exit 0
else
echo "$DESC: not running"
[ -f $PIDFILE ] && exit 1 || exit 3
fi
;;
log)
if [ -f $LOGIFLE ]; then
tail $LOGFILE
else
echo "log file '$LOGFILE' does't exist"
fi
;;
*)
echo "Usage: #!/bin/sh
### BEGIN INIT INFO
# Provides: skeleton
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $network $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: autosshtun
# Description: Used to launch SSH tunnel with autossh
### END INIT INFO
# Author: Laurent HUBERT <[email protected]>
#
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="AUTOSSH Tunnel"
NAME=autosshtun
DAEMON=/usr/lib/autossh/autossh
DAEMON_ARGS=""
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
CONN_PORT=22
SSH_TUNNEL_KEY_PATH=/root/.ssh/id-rsa
SSH_USERNAME=user
SSH_SERVER=server.domain.tld
ENTRY_PORT=1122
EXIT_PORT=22
ENV_COMMAND=/usr/bin/env
ENV_OPTIONS="AUTOSSH_PIDFILE=$PIDFILE"
SSH_COMMAND_OPTIONS="-p $CONN_PORT -i $SSH_TUNNEL_KEY_PATH $SSH_USERNAME@$SSH_SERVER"
OPEN_TUNNEL_OPTIONS="-T -N -R $ENTRY_PORT:localhost:$EXIT_PORT"
AUTOSSH_OPTION="-M 0"
DAEMON_ARGS="$AUTOSSH_OPTION $SSH_COMMAND_OPTIONS $OPEN_TUNNEL_OPTIONS"
is_running() {
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if [ -n "$PID" ]; then
return 0
else
return 1
fi
else
return 1
fi
}
#
# Function that starts the daemon/service
#
do_start()
{
QUIET="--quiet"
if ! is_running; then
start-stop-daemon --background --start $QUIET --name $NAME \
--exec $ENV_COMMAND -- $ENV_OPTIONS $DAEMON $DAEMON_ARGS
retval=$?
sleep 1
if [ $retval -gt 0 ]; then
return $retval
else
sleep 1
start-stop-daemon --stop $QUIET --pidfile $PIDFILE \
--test --exec $DAEMON > /dev/null || return 2
fi
else
return 1
fi
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/10/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=TERM/10/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}
case "" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
restart)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
exit 3
;;
esac
{start|stop|restart|force-reload|status|log}"
exit 3
;;
esac
exit 0
回答by Jan Hudec
Shell will print all statements just before it executes them if you set the xoption. Either:
如果您设置了该x选项,Shell 将在执行它们之前打印所有语句。任何一个:
- Run the script as
/bin/sh -x script. - Change the
#!line to#!/bin/sh -x. - Do
set -xat the beginning of the script.
- 将脚本作为
/bin/sh -x script. - 将该
#!行更改为#!/bin/sh -x。 - 不要
set -x在脚本的开始。
Obviously the first will set it for that one run, the other two will set it for each run.
显然,第一个将为该一次运行设置它,其他两个将为每次运行设置它。
Checking man page of start-stop-daemon(8)it seems you are using it wrong. You should notbackground start-stop-daemonwith &, you should instead tell start-stop-daemonto background the executed process using --backgroundoption. The documentation for --make-pidfileeven says it should not be expected to work except together with --backgroundoption.
检查start-stop-daemon(8) 的手册页,您似乎使用错误。你应该没有背景start-stop-daemon与&,则应该告诉start-stop-daemon背景使用执行过程--background选项。--make-pidfileeven的文档说它不应该被期望工作,除非与--background选项一起使用。
You also should be redirecting the start-stop-dameon's output, it's only output of the process you need redirected. start-stop-daemonwill redirect it to /dev/nullIIRC, but I don't see a way to override this. You might have to create a wrapper that will execit with appropriate redirections and use that in --startasoption, unless you manage to tell autosshto log into a file directly.
您还应该重定向 start-stop-dameon 的输出,它只是您需要重定向的进程的输出。start-stop-daemon将它重定向到/dev/nullIIRC,但我看不到覆盖它的方法。您可能必须创建一个包装器,exec它将使用适当的重定向并在--startas选项中使用它,除非您设法告诉autossh直接登录到文件。
回答by lauhub
The script below runs one and only one autossh process when invoked.
下面的脚本在调用时只运行一个 autossh 进程。
##代码##
