Init.d script doesn't start or stop only prints help message - linux

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.

Related

shell script before splash screen in pi

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

How to kill all processes named "shairport" that do not have the pid 12345

I am using shairport at work to stream music. I am running it on a Debian machine(a raspberry). In its /etc/init.d/shairport file it has only the start|stop commands.
I want to add a restart one. Here is the code so far:
case "$1" in
restart)
service shairport stop
service shairport start
;;
start)
/usr/local/bin/shairport -d -a "$NAME" -p 5002 -k "madafaka" -w -B "mpc stop"
;;
stop)
killall shairport
;;
*)
echo "Usage: /etc/init.d/shairport {start|stop|restart}"
exit 1
;;
esac
exit 0
The issue is that when I run "service shairport restart", the service is stopped, thus running "killall shairport" and killing the bash script process itself. So "start" is never executed.
How do I make killall kill every shairport except the current script?
My idea was to get the pid and exclude it, but I cant find how to do that.
The start part should write down the PID of the started process.
Something like echo $? > /var/run/shairport.pid will do.
Stop part of your script will use the PID from the .pid file we have created, and kill the right process. This is what most of Linux services do as far as I know.
In linux you can know the process ID that the script file is running under with : $$.
You just have to check you're not killing yourself with :
stop)
for pid in $(pgrep shairport); do
if[$pid != $$]
kill $pid
fi
done
Since the answer I chose did not work straight out of the box, here is the code I ended up with:
case "$1" in
restart)
for pid in $(pgrep shairport); do
if [ "$pid" != $$ ]; then
kill $pid
fi
done
/usr/local/bin/shairport -d -a "$NAME" -p 5002 -k "madafaka" -w -B "mpc stop"
;;
start)
/usr/local/bin/shairport -d -a "$NAME" -p 5002 -k "madafaka" -w -B "mpc stop"
;;
stop)
killall shairport
;;
*)
echo "Usage: /etc/init.d/shairport {start|stop|restart}"
exit 1
;;
esac

My custom init shell script stops deployment script

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.

Escaping variables in bash file

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

Start Stop Daemon Init Debian - Unrecognized arguments

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.

Resources