This is my debian init script so far to start uwsgi in emperor mode:
cat <<EOF >/etc/init.d/uwsgi
#!/bin/bash
daemon="$APPVENV/bin/uwsgi"
args=( --emperor "$APPCONF/uwsgi/app.ini"
--daemonize /var/log/emperor.log
--emperor-pidfile "$APPDIR/emperor.pid" --gid \$(id -g "$APPUSER")
)
pid="$APPDIR/emperor.pid"
case "\$1" in
start)
echo "Starting uwsgi"
start-stop-daemon -m -p \$pid --start --exec \$daemon \$args
;;
stop)
echo "Stopping script uwsgi"
start-stop-daemon --signal INT -p \$pid --stop \$daemon \$args
;;
reload)
echo "Reloading conf"
kill -HUP \$(< \$pid)
;;
*)
echo "Usage: /etc/init.d/uwsgi {start|stop|reload}"
exit 1
;;
esac
exit 0
EOF
chmod u+x /etc/init.d/uwsgi
update-rc.d uwsgi defaults
service uwsgi start
When I run this command I get this response:
> service uwsgi stop
Stopping script uwsgi
start-stop-daemon: unrecognized option '--emperor'
Try 'start-stop-daemon --help' for more information.
However, I know --emperor is a perfectly valid argument of uwsgi. So what's going on, am I putting the uwsgi arguments in the wrong place?
Any help would be appreciated.
Related
I have a raspberry pi running the Jessie OS, and would like to run a bash script to execute before it does anything else, such as the splash screen.
The shell script is a simple feh command because I want the pi to operate as a slideshow of images in a picture frame and nothing else; hence needing the pi to start the shell script immediately.
It would also be great if I could have the functionality to restart it if the shell script is exited for any reason.
I have tried cron jobs, /etc/init.d, and /etc/rc0.d, however, none of these have worked for me yet.
I have my main shell script in /home/imgs/slideshow.sh and then I run the following script to set things up to hopefully run as init.d:
#!/bin/bash
sudo apt-get update
sudo apt-get install feh
sudo apt-get install xscreensaver
sudo apt-get upgrade
# Make slideshow startup file in init.d if it doesn't exit
# if it does, make a backup file and rewrite it
FILE=/etc/init.d/slideshow.sh
if [ -f "$FILE" ]
then
sudo mv $FILE $FILE-backup-$(date +"%F-%T")
else
echo "$FILE does not exist but will be created"
fi
# input this text into the file
/bin/cat <<EOM >"$FILE"
#!/bin/sh -e
DAEMON="slideshow" #Command to run
daemon_OPT="" #arguments for your program
DAEMONUSER="user" #Program user
daemon_NAME="slideshow" #Program name (need to be identical to the executable).
PATH="/sbin:/bin:/usr/sbin:/usr/bin" #don't touch
test -x $DAEMON || exit 0
. /lib/lsb/init-functions
d_start () {
log_daemon_msg "Starting system $daemon_NAME Daemon"
start-stop-daemon --background --name $daemon_NAME --start --quiet --chuid $DAEMONUSER --exec $DAEMON -- $daemon_OPT
log_end_msg $?
}
d_stop () {
log_daemon_msg "Stopping system $daemon_NAME Daemon"
start-stop-daemon --name $daemon_NAME --stop --retry 5 --quiet --name $daemon_NAME
log_end_msg $?
}
case "$1" in
start|stop)
d_${1}
;;
restart|reload|force-reload)
d_stop
d_start
;;
force-stop)
d_stop
killall -q $daemon_NAME || true #replace with an apropriate killing method
sleep 2
killall -q -9 $daemon_NAME || true #replace with an apropriate killing method
;;
status)
status_of_proc "$daemon_NAME" "$DAEMON" "system-wide $daemon_NAME" && exit 0 || exit $?
;;
*)
echo "Usage: /etc/init.d/$daemon_NAME {start|stop|force-stop|restart|reload|force-reload|status}"
exit 1
;;
esac
exit 0
EOM
sudo chmod +x /etc/init.d/slideshow.sh
sudo chmod 0755 /etc/init.d/slideshow.sh
sudo chmod +x /home/pi/imgs/slideshow.sh
sudo chmod 0755 /home/pi/imgs/slideshow.sh
sudo systemctl daemon-reload
sudo update-rc.d slideshow.sh defaults
I am currently running Liquidsoap on Ubuntu 14.4, streaming to Icecast, hosted on the same box.
My setup is running correctly, however when running sudo service liquidsoap restart, I get the following error:
fatal error exception unix.unix_error(50, "bind", "" )
In order to restart liquid soap, I need to kill the process or reboot.
It then runs correctly. Until I need to restart for whatever reason.
As a side note, liquidsoap created a user and group called liquidsoap, however I am running sudo commands via another user I created.
Does anyone have any ideas?
Fixed by enabling pid file creation.
Copy of my init.d - https://gist.github.com/anonymous/d7e232fc280d2fe1df56
#!/bin/sh
### BEGIN INIT INFO
# Provides: liquidsoap
# Required-Start: $remote_fs $network $time
# Required-Stop: $remote_fs $network $time
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts the liquidsoap daemon
# Description:
### END INIT INFO
user=liquidsoap
group=liquidsoap
prefix=/usr
exec_prefix=${prefix}
confdir=/etc/liquidsoap
liquidsoap=${exec_prefix}/bin/liquidsoap
rundir=/var/run/liquidsoap
# Test if $rundir exists
if [ ! -d $rundir ]; then
mkdir -p $rundir;
chown $user:$group $rundir
fi
case "$1" in
stop)
echo -n "Stopping liquidsoap channels: "
cd $rundir
has_channels=
for liq in *.pid ; do
if test $liq != '*.pid' ; then
has_channels=1
echo -n "$liq "
start-stop-daemon --stop --quiet --pidfile $liq --retry 4
fi
done
if test -n "$has_channels"; then
echo "OK"
else
echo "no script found in $confdir"
fi
;;
start)
echo -n "Starting liquidsoap channels: "
cd $confdir
has_channels=
for liq in *.liq ; do
if test $liq != '*.liq' ; then
has_channels=1
echo -n "$liq "
start-stop-daemon --start --quiet --pidfile $rundir/${liq%.liq}.pid \
--chuid $user:$group --exec $liquidsoap -- -d $confdir/$liq
fi
done
if test -n "$has_channels"; then
echo "OK"
else
echo "no script found in $confdir"
fi
;;
restart|force-reload)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart|force-reload}"
exit 1
;;
esac
None of mentioned solutions solved my issue. I had to fix it recently by setting proper ownership and permissions right after starting daemons. After killing the processes and restarting, further restarts work fine.
start-stop-daemon --start --quiet --pidfile $rundir/${liq%.liq}.pid \
--chuid $user:$group --exec $liquidsoap -- -d $confdir/$liq && sleep 1 && chmod 600 $rundir/${liq%.liq}.pid && chown root:root $rundir/${liq%.liq}.pid
I have a deployment script which works fine. At the end of it I added this block:
cat << EOF > /etc/init.d/uwsgi
#!/bin/bash
daemon=$APPVENV/bin/uwsgi
args="--emperor $APPCONF/uwsgi/app.ini --daemonize /var/log/emperor.log --emperor-pidfile $APPDIR/emperor.pid --gid `id -g $APPUSER`"
pid=$APPDIR/emperor.pid
case "$1" in
start)
echo "Starting uwsgi"
start-stop-daemon -p $pid --start --exec $daemon -- $args
;;
stop)
echo "Stopping script uwsgi"
start-stop-daemon --signal INT -p $pid --stop $daemon -- $args
;;
reload)
echo "Reloading conf"
kill -HUP $(cat $pid)
;;
*)
echo "Usage: /etc/init.d/uwsgi {start|stop|reload}"
exit 1
;;
esac
exit 0
EOF
Now when I run my deployment script it gets stuck here, and I just see a blinking cursor and it doesn't run any lines after it.
Have I done anything wrong with my formatting, as I know creating a file with cat was something very picky about how it was formatted, tabulated etc.
variables are still substituted in heredocs, also subshelling with $( ), which you do in your script here:
kill -HUP $(cat $pid)
your installer attempts to cat that file, with $pid probably empty, therefore it waits for input from standard input.
You want to escape those "$" to prevent expansion, like
\$(cat \$foo)
And of course with all those variables you don't want to get expanded during installation too.
I'm creating a init.d script within a bash file, which goes as follows:
# AUTOSTART
$APPDIR=somedir
$APPCONF=somedir
$APPVENV=somedir
$APPUSER=someuser
cat <<EOF >/etc/init.d/uwsgi
#!/bin/bash
daemon=$APPVENV/bin/uwsgi
args="--emperor $APPCONF/uwsgi/app.ini --daemonize /var/log/emperor.log --emperor-pidfile $APPDIR/emperor.pid --gid `id -g $APPUSER`"
pid=$APPDIR/emperor.pid
case "$1" in
start)
echo "Starting uwsgi"
start-stop-daemon -m -p $pid --start --exec $daemon $args
;;
stop)
echo "Stopping script uwsgi"
start-stop-daemon --signal INT -p $pid --stop $daemon $args
;;
reload)
echo "Reloading conf"
kill -HUP $(cat $pid)
;;
*)
echo "Usage: /etc/init.d/uwsgi {start|stop|reload}"
exit 1
;;
esac
exit 0
EOF
It is my understanding, from help, that $APPCONF, $APPVENV, $APPUSER and $APPDIR need to be escaped because I define them outside the file. So is it correct that I simply put a back slash in front of the variable like this:
daemon=\$APPVENV/bin/uwsgi
args="--emperor \$APPCONF/uwsgi/app.ini --daemonize /var/log/emperor.log --emperor-pidfile \$APPDIR/emperor.pid --gid `id -g \$APPUSER`"
pid=\$APPDIR/emperor.pid
It still doesn't seem to work though, the service doesn't start, so I think I might have done something else wrong. Can anyone confirm I am escaping properly please?
The dollar sign is only used for reading/using the value of a variable, not when setting its value. Thus, setting APPDIR to somedir would look like this:
APPDIR=somedir
Depending on how you call the script, you may also want to export the variable:
export APPDIR=somedir
I've tried to write a custom upstart script for uwsgi emperor but it doesn't seem to start uwsgi and only says Usage: /etc/init.d/uwsgi {start|stop|reload} when I try to run it using "service uwsgi start".
Can anyone please tell me where I have gone wrong. The snippet below is from my deployment shell script:
cat <<EOF >/etc/init.d/uwsgi
#!/bin/bash
daemon=\$APPVENV/bin/uwsgi
args="--emperor \$APPCONF/uwsgi/app.ini --daemonize /var/log/emperor.log --emperor-pidfile \$APPDIR/emperor.pid --gid `id -g \$APPUSER`"
pid=\$APPDIR/emperor.pid
case "$1" in
start)
echo "Starting uwsgi"
start-stop-daemon -m -p \$pid --start --exec \$daemon \$args
;;
stop)
echo "Stopping script uwsgi"
start-stop-daemon --signal INT -p \$pid --stop \$daemon \$args
;;
reload)
echo "Reloading conf"
kill -HUP \$(cat \$pid)
;;
*)
echo "Usage: /etc/init.d/uwsgi {start|stop|reload}"
exit 1
;;
esac
exit 0
EOF
chmod u+x /etc/init.d/uwsgi
update-rc.d uwsgi defaults
service uwsgi start
Use the following. Pay close attention to which $ I escape and do not escape.
cat <<EOF >/etc/init.d/uwsgi
#!/bin/bash
daemon="$APPVENV/bin/uwsgi"
args=( --emperor "$APPCONF/uwsgi/app.ini"
--daemonize /var/log/emperor.log
--emperor-pidfile "$APPDIR/emperor.pid" --gid \$(id -g "$APPUSER")
)
pid="$APPDIR/emperor.pid"
case "\$1" in
start)
echo "Starting uwsgi"
start-stop-daemon -m -p \$pid --start --exec \$daemon \$args
;;
stop)
echo "Stopping script uwsgi"
start-stop-daemon --signal INT -p \$pid --stop \$daemon \$args
;;
reload)
echo "Reloading conf"
kill -HUP \$(< \$pid)
;;
*)
echo "Usage: /etc/init.d/uwsgi {start|stop|reload}"
exit 1
;;
esac
exit 0
EOF
chmod u+x /etc/init.d/uwsgi
update-rc.d uwsgi defaults
service uwsgi start
Variables like APPDIR, based on your previous questions, are used to configure what is actually written to disk, so you leave them unescaped so that they are expanded when /etc/init.d/uwsgi is written.
Variables like daemon, $1, and the command substitutions $(id -g "$APPUSER") are intended to be expanded when the init script runs, so you want the literal string $daemon to appear in the script, not the value of $daemon (which is probably undefined) when uwsgi is written.
You forgot to escape the $1 like you did in other places in your script:
case "\$1" in
As you are using cat to create the script, you need to escape all instances of $
Check if the service start really does send an argument to your script:
*)
echo "Argument taken was \"$1\"."
echo "Usage: /etc/init.d/uwsgi {start|stop|reload}"
exit 1
It could actually be different and you may consider making changes based from it.