I’m downloaded tracd init.d startup script from here and I’m trying to adopt it to my own server. But when I’m running script I get folowing error message:
Usage: tracd [options] [projenv] ...
tracd: error: the --single-env option cannot be used with more than one enviroment
So I’m trying to modify the script to get it working. This is my actual version:
#!/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
And this is it’s output:
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
What is funny – when I copy the command from terminal and run it, everthing works fine. So I think that there is a problem whith runnitg this command from scrit. What am I doing wrong?
Short answer: see BashFAQ #050: I’m trying to put a command in a variable, but the complex cases always fail!
Long answer: when bash parses a command line, it looks for (& acts on) quotes and escapes before it substitutes variables. So when a variable contains something like
-s --basic-auth="bds5,/opt/trac/bds5/.htpasswd,Baza Doskonalenia Systemu", by the time that value gets included in the command line, it’s too late for the quotes in it to do anything useful.If you need to store complex command options in a variable, your best option is to use an array. Each shell word gets stored as a separate element in the array, and if you expand the array right (as
"$arrayname[@]}") that gets preserved and passed to the command intact: