2012-02-15 10 views
2

私はブート時に起動スクリプトautosshを起動するスクリプトを作成しようとしていますが、動作させることができません。私はそれが正常に動作していなかったので、それがすべての行動を記録しているのを見たいと思いますが、それはうまくいっていません。私はbashのプロではないので、私のコードは恐ろしく恥ずかしいではないことを願っています。Bash initスクリプトfor autossh

#!/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 [email protected]$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 "$1" 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: $0 {start|stop|restart|force-reload|status|log}" 
     exit 3 
    ;; 
esac 

exit 0 
+1

* bash *と/ bin/shは同じものかもしれませんが、まったく違うかもしれません。ほとんどのDebianシステムでは、 '/ bin/sh'は* dash *です。これは高速ですが、[POSIX標準シェル](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/toc.html)に加えてbash *の機能のほとんどが欠けています。多くの場合、対話型の使用のためにbash(またはzsh、さらに多くの機能を備えています)を使用しますが、POSIXシェル用のスクリプトを作成し、ダッシュなどのより高速な実装を使用して実行します。もし/ bin/shが本当に 'bash'、' dash'、OR '元の'/bin/sh'、Bourneシェル(もしあなたがAIX、Solarisなどを使っているのなら、JanHudecのコメントごとに –

+1

) HPや他の旧式のUNIX、Linuxとは対照的に、Bourneは他のキャビネットと同様に理解する必要があります)。 Bourneシェルとの互換性が必要な場合を除き、少なくとも1995年以来廃止されている '' cat $ PIDFILE''ではなく、現代的でネスト可能な '$(cat $ PIDFILE)'を使用してください。それ以外の場合は、コード神が意図した! ;-) がんばろう。 – shellter

+0

ありがとう/ bin/shはダッシュへのシンボリックリンクです:) – PvdL

答えて

2

シェルは、あなたがxオプションを設定した場合、それはそれらを実行する直前に、すべての文を印刷します。いずれか:

  • スクリプトを/bin/sh -x scriptとして実行します。
  • #!行を#!/bin/sh -xに変更してください。
  • set -xをスクリプトの冒頭に付けます。

当然のことながら、1回目は1回の実行で設定され、2回目は実行ごとに設定されます。


マニュアルページstart-stop-daemon(8)を確認すると間違っているようです。 start-stop-daemon&ではありません。start-stop-daemonには、--backgroundオプションを使用して実行されたプロセスをバックグラウンドで伝える必要があります。 --make-pidfileのドキュメントでは、--backgroundオプション以外では動作しないはずです。

また、リダイレクトする必要があるプロセスの出力のみです。開始停止ダーマンの出力をリダイレクトする必要があります。 start-stop-daemonはそれを/dev/null IIRCにリダイレクトしますが、これを無効にする方法はありません。 autosshにファイルに直接ログインするように指示しない限り、execを適切なリダイレクトで作成し、--startasオプションで使用するラッパーを作成する必要があります。

+0

この場合、スクリプトのエコーは次のようになります:+ start-stop-daemon --start --make-pidfile --pidfile /var/run/autossh/user-xxx.nl .pid --exec/usr/bin/autossh - -M 29000 -i /root/.ssh/id_rsa -X -C -R 2222:localhost:22 [email protected] このように、ログファイルに>> 、ログファイルにはリモートサーバのモートが含まれていますが、sshセッションは起動後数秒間実行されないため、エラーは発生しません。スクリプトには2>&1が含まれていますが、エラーはどこにも見つかりません。 – PvdL

+0

@ junke1990:スクリプトはstart-stop-daemonを正常に実行しているようですが、デーモン自体が失敗しています。実際には、ログファイルにはリモートサーバのmotdが含まれているため、sshが起動していることが示唆されますが、何かが間違っていることが示唆されます。うーん... manページを見て、私はあなたが 'start-stop-daemon'を間違って使っていると思っています。 –

+0

Autsosshはデーモン(param -f)として実行できますが、pidを指定することができません。そのため、私はstart-stop-daemonを使用していました。私はinitスクリプトの残りの部分を見てきましたが、ほとんどのスクリプトは私と同じ方法でデーモンを使用しています。 – PvdL

0

以下のスクリプトは、起動時に1つのautosshプロセスしか実行しません。

#!/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 [email protected]$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 "$1" 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