0

我从这里下载了 tracd init.d 启动脚本,我正在尝试将它应用到我自己的服务器上。但是当我运行脚本时,我收到以下错误消息:

Usage: tracd [options] [projenv] ...

tracd: error: the --single-env option cannot be used with more than one enviroment

所以我正在尝试修改脚本以使其正常工作。这是我的实际版本:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          tracd
# Required-Start:    networking
# Required-Stop:     networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start the tracd standalone Trac web server.
### END INIT INFO
# (C) 2008 Guy Rutenberg <http://www.guyrutenberg.com>

## Options you should probably change ##
HOSTNAME=193.17.184.23 # to which hostname should we listen
# If you only want to serve one project keep this variable
# empty and set the PROJECT_ENV variable 
ENV_PARENT_DIR=
PROJECT_ENV=/opt/trac/bds5/
PORT=8000
# add any additional options (such as authentication) here. If you only have one
# project you should probably add -s here
ADDITIONAL_OPTS='-s --basic-auth="bds5,/opt/trac/bds5/.htpasswd,Baza Doskonalenia Systemu"'

## Options you should probably not change ##
DAEMON=/usr/local/bin/tracd
NAME=tracd-bds5
DESC="web server"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
SSD="/sbin/start-stop-daemon"

test -x $DAEMON || exit 1

set -e

. /lib/lsb/init-functions

DAEMON_OPTS="--daemonize --pidfile=$PIDFILE --port=$PORT --hostname=$HOSTNAME $ADDITIONAL_OPTS"
if [ -n "$ENV_PARENT_DIR" ]; then
    DAEMON_OPTS="$DAEMON_OPTS --env-parent-dir=$ENV_PARENT_DIR"
else
    DAEMON_OPTS="$DAEMON_OPTS $PROJECT_ENV"
fi

case "$1" in
  start)
    log_daemon_msg "Starting $DESC" $NAME
    echo "$SSD --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS" 
    $SSD --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS
    if [[ -n $! ]]; then
            log_end_msg 0
    else
            log_end_msg 1
    fi
    ;;
  stop)
    log_daemon_msg "Stopping $DESC" $NAME
    if $SSD --stop --retry 30\
    --pidfile $PIDFILE ; then
        rm -f $PIDFILE
        log_end_msg 0
    else
        log_end_msg 1
    fi
    ;;
  restart|force-reload)
    $0 stop
    [ -r  $PIDFILE ] && while pidof -x $NAME |\
         grep -q `cat $PIDFILE 2>/dev/null` 2>/dev/null ; do sleep 1; done
    $0 start
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
    exit 1
    ;;
esac

exit 0

这是它的输出:

Starting web server: tracd-bds5
/sbin/start-stop-daemon --start --quiet --pidfile /var/run/tracd-bds5.pid --exec /usr/local/bin/tracd -- --daemonize --pidfile=/var/run/tracd-bds5.pid --port=8000 --hostname=127.0.0.1 -s --basic-auth="bds5,/opt/trac/bds5/.htpasswd,Baza Doskonalenia Systemu" /opt/trac/bds5/
Usage: tracd [options] [projenv] ...

tracd: error: the --single-env option cannot be used with more than one enviroment

有趣的是 - 当我从终端复制命令并运行它时,一切正常。所以我认为从脚本运行这个命令存在问题。我究竟做错了什么?

4

1 回答 1

4

简短回答:请参阅BashFAQ #050:我正在尝试将命令放入变量中,但复杂的情况总是失败!

长答案:当 bash 解析命令行时,它会在替换变量之前查找(& 作用于)引号和转义。因此,当变量包含类似-s --basic-auth="bds5,/opt/trac/bds5/.htpasswd,Baza Doskonalenia Systemu"的内容时,当该值包含在命令行中时,其中的引号无法执行任何有用的操作为时已晚。

如果您需要将复杂的命令选项存储在变量中,最好的选择是使用数组。每个 shell 字都作为一个单独的元素存储在数组中,如果您将数组向右展开(as "$arrayname[@]}"),它将被保留并完整地传递给命令:

ADDITIONAL_OPTS=(-s --basic-auth="bds5,/opt/trac/bds5/.htpasswd,Baza Doskonalenia Systemu")
...
DAEMON_OPTS=(--daemonize --pidfile=$PIDFILE --port=$PORT --hostname=$HOSTNAME "${ADDITIONAL_OPTS[@]}")
if [ -n "$ENV_PARENT_DIR" ]; then
    DAEMON_OPTS+=(--env-parent-dir=$ENV_PARENT_DIR)
else
    DAEMON_OPTS+=($PROJECT_ENV)
fi
...
$SSD --start --quiet --pidfile $PIDFILE --exec $DAEMON -- "${DAEMON_OPTS[@]}"
于 2013-01-12T18:03:44.100 回答