SHOUTcast daemon script not functioning properly - shell

I've got a SHOUTcast server running on Ubuntu. The server process is running great, but I can't seem to get the daemon script to function properly. Following a couple tutorials I found I came up with this:
#!/bin/sh
CONFIG="/home/apps/shout32/sc_plex.conf"
DAEMON="/home/apps/shout32/sc_serv"
case "$1" in
start)
echo "Starting SC..."
$DAEMON $CONFIG > /dev/null 2>&1 &
;;
stop)
echo "Stopping SC..."
kill -9 `ps -C sc_serv -o pid --no-headers`
;;
restart)
echo "Rebooting SC..."
kill -9 `ps -C sc_serv -o pid --no-headers`
$DAEMON $CONFIG > /dev/null 2>&1 &
;;
*)
echo "usage: service sc32d {start | stop | restart}"
exit 1
;;
esac
This however does not work. I didn't know what a lot of this meant, so I started to break it down line by line. If I remove the /dev/null stuff - which as I now understand keeps the program running 'silent' in the background - I get this message, and the program closes:
root#streams3:/etc/init.d# service sc32d start
Starting SC...
root#streams3:/etc/init.d# 2013-05-21 14:41:50 E msg:<***> logger could not open file logs/sc_serv.log
2013-05-21 14:41:50 I msg:<***> Logger shutdown
root#streams3:/etc/init.d#
root#streams3:/etc/init.d# ps -C sc_serv
PID TTY TIME CMD
root#streams3:/etc/init.d#
I was still in the process of researching what exactly /dev/null did and why, so I wanted to run those commands with all the /dev/null stuff by hand, which I did, and that's where I got some sort of error code:
root#streams3:/etc/init.d# /home/apps/shout32/sc_serv /home/apps/shout32/sc_plex.conf > /dev/null 2>&1 &
[2] 2261
root#streams3:/etc/init.d#
[2]- Exit 255 /home/apps/shout32/sc_serv /home/apps/shout32/sc_plex.conf > /dev/null 2>&1
root#streams3:/etc/init.d# ps -C sc_serv
PID TTY TIME CMD
Unfortunately from the brief amount of research I did it sounds like 'Exit 225' is like a catch-all error code for codes that are outside of the acceptable range of codes.
The interesting part of the whole issue is this: When I navigate to the /home/apps/shout32/ folder, and run the commands there, without the full path... damn thing works:
root#streams3:/home/apps/shout32# ./sc_serv sc_plex.conf > /dev/null 2>&1 &
[2] 2245
root#streams3:/home/apps/shout32#
root#streams3:/home/apps/shout32# ps -C sc_serv
PID TTY TIME CMD
2245 pts/0 00:00:00 sc_serv
So, something is messing up because the script file is in /etc/init.d/ and not in the folder the application is in? As far as I know I followed every step in the published tutorials for setting up SHOUTcast in Ubuntu and then making a daemon... I don't think I missed anything. I have a feeling the solution is either staring me right in the face or its some sort of obscure permissions thing that's a bit over my head.
But any help would be greatly appreciated!
So, based on an answer below I added cd /home/apps/shout32/ to the START command in my script, also added pwd and ls... to see if we could eliminate the fact that the script couldn't find the /log/ directory.
So now my script is:
CONFIG="/home/apps/shout32/sc_plex.conf"
DAEMON="/home/apps/shout32/sc_serv"
cd /home/apps/shout32/
case "$1" in
start)
echo "Starting SC..."
cd /home/apps/shout32/
pwd
ls
$DAEMON $CONFIG &
;;
stop)
echo "Stopping SC..."
kill -9 `ps -C sc_serv -o pid --no-headers`
;;
restart)
echo "Rebooting SC..."
kill -9 `ps -C sc_serv -o pid --no-headers`
$DAEMON $CONFIG &
;;
*)
echo "usage: service sc32d {start | stop | restart}"
exit 1
;;
esac
I got this:
admin#streams3:/etc/init.d$ service sc32d start
Starting SC...
/home/apps/shout32
changes.txt readme.txt sc_serv_debug.conf
config_builder sc_plex.conf sc_serv_public.conf
control sc_serv sc_serv_relay.conf
docs sc_serv2_linux_07_31_2011.tar sc_serv_simple.conf
logs sc_serv_basic.conf tos.txt
admin#streams3:/etc/init.d$ 2013-06-05 17:52:08 E msg:<***> logger could not open file logs/sc_serv.log
2013-06-05 17:52:08 I msg:<***> Logger shutdown

your second snippet contains logger could not open file logs/sc_serv.log. So it tries to write to a file sc_serv.log which it either expects or wants to create in the directory logs which it expects in the current directory. This also explains that it works when you cd to /home/apps/shout32/ first. I guess there's a file /home/apps/shout32/logs/sc_serv.log.
can you configure the location of that file?
can't you just add some cd ... at the start of the script?

Related

Mac Terminal Open Command - Save PID of Opened Application?

I'd like to open an xcode workspace in terminal, wait some time, then close that workspace (xcode has some hidden magic it does on projects that makes this necessary in an automated build process).
So something like-
pid=`open proj.xcworkspace`
sleep 30
kill $pid
Because multiple xcode projects may be running in the same time. I can't simply kill xcode, just the process I started.
How can I get the PID of an application I open in terminal?
You can catch the current Process ID with $$.
Or you can search for Process IDs with ps -C PROGRAMM_NAME -o pid=.
suleiman#antec:~$ ps -C icedove -o pid=
887
suleiman#antec:~$ ps -C vlc -o pid=
29405
Addition...
Here is a working example of what I mean ...
#!/bin/bash
i=0
while [ "$i" -le 10 ]
do
example.sh &
Pid[$i]=$(ps -C "example.sh" -o "pid=")
Pid[$i]=$(echo "${Pid[$i]}" | tail -n 1)
#echo "${Pid[$i]}"
i=$(($i +1))
done
for PID in "${Pid[#]}"
do
kill "$PID"
done
exit 0

How to show background jobs in shell hidden by &

I run a webserver by one Makefile by command make install
The content of Makefile is
project : webserver.c
webserver.c : server/webserver.c
gcc -g -D_FORTIFY_SOURCE=0 -frecord-gcc-switches -fno-stack-protector -g -o server/webserver -lpthread -lnsl -lresolv -D_TS_ERRNO server/webserver.c
install :
sudo /etc/init.d/fhttpd.init stop
sudo cp server/webserver /usr/local/fhttpd/fhttpd
sudo chmod 4755 /usr/local/fhttpd/fhttpd
sudo /etc/init.d/fhttpd.init start
clean :
rm server/webserver
the content of fhttpd.init is
httpd="/usr/local/fhttpd/fhttpd"
prog=fhttpd
port=8080
RETVAL=0
# disable ASLR so that lab exercise will work reliably
echo 0 > /proc/sys/kernel/randomize_va_space
start() {
echo "Stopping $prog..."
killall $prog
echo -n $"Starting $prog: "
$httpd $port &
}
stop() {
echo -n $"Stopping $prog: "
killall $prog
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
start
;;
reload)
start
;;
*)
echo $"Usage: $prog {start|stop|restart}"
exit 1
esac
exit $RETVAL
I guess init use & to make server run in background. But after I use that command. I used jobs command to show all my jobs, I can't see anything. But if I run it directly, like this
lhu343ai#server:~$ /usr/local/fhttpd/fhttpd 8080 &
[1] 7154
lhu343ai#server:~$ jobs
[1]+ Running /usr/local/fhttpd/fhttpd 8080 &
Everything is OK to me.
If I just use make install or sudo /etc/init.d/fhttpd.init start, jobs shows nothing. In fact, the server is running correctly. I just don't know how does it work because I use & in /etc/init.d/fhttpd.init.
I don't know why is the reason I can't use 'jobs' with makefile. And how can I get background program back in this case.
I'd expect this command to elevate execution to the superuser's userspace:
sudo /etc/init.d/fhttpd.init start
As a result you wouldn't see that process in your regular user, lhu343ai. You'd want to check the jobs for the superuser, instead. For example, sudo jobs would be the command you're looking for...
Please note that this isn't a programming question, and it certainly isn't about C. We have enough low-level noise spammed over that tag from people confusing x86 assembly concepts with C, as it is.

Gracefully shutting down sidekiq processes

Does anyone know how to find sidekiq's pidfile to gracefully shut it down?
Running ps ax | grep sidekiq and then running sidekiqctl stop <pid from grep> consistently gives a no such pidfile error?
Cntl-C and Cntl-D also seem to have no effect.
Closing the process window and reopening a new window doesn't kill the process as it appears to be running as a daemon.
The only consistent fix I've found is rebooting.
Use this to kill sidekiq forcefully.
ps -ef | grep sidekiq | grep -v grep | awk '{print $2}' | xargs kill -9
Sidekiq provides the ability to specify a pidfile at start time or, as shown below, to create the pidfile after the process has been started. In either case you can then use the pidfile at stop time.
Use ps -ef | grep sidekiq to find the pid
Create a file (e.g., sidekiq.pid) with the only contents being the pid you just found
sidekiqctl stop <pidfile_name>
Use -P <pidfile_name> or --pidfile <pidfile_name> when starting sidekiq in the future
Just been looking into this one myself...
Seems like newer versions of Sidekiq have this built in:
https://github.com/mperham/sidekiq/wiki/Signals
kill -USR1 [PROCESS_ID]
Worked great for me. The workers stopped picking up new jobs, but finished the ones they were on, then I finally killed the process when it was done.
kill -TERM [PROCESS_ID]
I've written a little handler that can start or stop sidekiq.
start_stop_sidekiq.sh
#!/bin/bash
cmd=$1
PROJECT_DIR=$2
PIDFILE=$PROJECT_DIR/tmp/pids/sidekiq.pid
cd $PROJECT_DIR
start_function(){
LOGFILE=$PROJECT_DIR/log/sidekiq.log
echo "Starting sidekiq..."
bundle exec sidekiq -d -L $LOGFILE -P $PIDFILE -q mailer,5 -q default -e production
}
stop_function(){
if [ ! -f $PIDFILE ]; then
ps -ef | grep sidekiq | grep busy | grep -v grep | awk '{print $2}' > $PIDFILE
fi
bundle exec sidekiqctl stop $PIDFILE
}
case "$cmd" in
start)
start_function
;;
stop)
stop_function
;;
restart)
stop_function && start_function;
;;
*)
echo $"Usage: $0 {start|stop|restart} /path/to/rails/app"
esac
Save it, type chmod +x start_stop_sidekiq.sh.
Then just run it with:
bash start_stop_sidekiq.sh start /path/to/your/rails/app
or
bash start_stop_sidekiq.sh stop /path/to/your/rails/app
If you only have one Rails app, you can also set the $PROJECT_DIR variable statically so that you don't need to specify the path each time. Hope this helps!
Try using god to monitor sidekiq.
Then all you need to do is bundle exec god stop
Alternatively, you can use:
sidekiqctl stop 60
If you like bashes...
scripts/stop_sidekiq.sh
#!/bin/bash
DIR="$( cd "$( dirname "$0" )" && pwd )"
PROJECT_DIR=$DIR/../ # EDIT HERE: rel path to your project form this file location (my scripts are in ./scripts/)
SIDEKIQ_PID_FILE=$PROJECT_DIR/tmp/pids/sidekiq.pid # EDIT HERE: pid file location
if [ ! -f $SIDEKIQ_PID_FILE ]; then
# if no pid file, retrieve pid and create file
ps -ef | grep sidekiq | grep busy | grep -v grep | awk '{print $2}' > $SIDEKIQ_PID_FILE
fi
(cd $PROJECT_DIR && bundle exec sidekiqctl stop $SIDEKIQ_PID_FILE)
Notes:
will work even if sidekiq started without pid file argument
assumes this script is in a folder inside the project and pid files are stored in ./tmp/pids/
Sharing a bash script that checks if sidekiq is running, sends it TSTP to ask it to not pick up any new jobs, waits until any running jobs are finished and then stops the process by sending a TERM signal to it.
https://gist.github.com/kamilbednarz/5ea6398af2a7537aa8feb5a63f3acf2f

rc.d start does not terminate?

So I wrote the Arch Linux rc.d script for mongod daemon (following an example), but when I do:
sudo rc.d start mongod
it just gets stuck on:
:: Starting /usr/bin/mongod [BUSY]
and never transitions to "DONE" phase. Any tips?
Here is my script:
#!/bin/bash
# import predefined functions
. /etc/rc.conf
. /etc/rc.d/functions
# Point to the binary
DAEMON=/usr/bin/mongod
# Get the ARGS from the conf
. /etc/conf.d/crond
# Function to get the process id
PID=$(get_pid $DAEMON)
case "$1" in
start)
stat_busy "Starting $DAEMON"
# Check the PID exists - and if it does (returns 0) - do no run
[ -z "$PID" ] && $DAEMON $ARGS &> /dev/null
if [ $? = 0 ]; then
add_daemon $DAEMON
stat_done
else
stat_fail
exit 1
fi
;;
stop)
stat_busy "Stopping $DAEMON"
kill -HUP $PID &>/dev/null
rm_daemon $DAEMON
stat_done
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "usage: $0 {start|stop|restart}"
esac
I've looked at how apache does it, but I can't figure out what they are doing that's different. Here's a piece of their httpd script:
case "$1" in
start)
stat_busy "Starting Apache Web Server"
[ ! -d /var/run/httpd ] && install -d /var/run/httpd
if $APACHECTL start >/dev/null ; then
add_daemon $daemon_name
stat_done
else
stat_fail
exit 1
fi
;;
For one thing, you are passing an $ARGS variable that is never actually defined. You will probably want to either pass some configuration options, or the location of a mongodb.conf file using the -f or --config option, to inform the daemon of the location of your database, log file, IP bindings, etc.
The mongod defaults assume that you database location is /data/db/. If this does not exist, or the daemon does not have permissions to that location, then the init script will fail.
You should probably also run the daemon with a user account other than yourself or root (the default pacman package creates a user named mongodb), and give this user read/write access to the data path and log file.
[ -z "$PID" ] && /bin/su mongodb -c "/usr/bin/mongod --config /etc/mongodb.conf --fork" > /dev/null
I would suggest referring to the mongodb init script provided in the Arch Community package, and comparing that to what you have here. Or, install MongoDB using pacman, which sets all of this up for you.
If all else fails, add some 'echo' commands inside of your if and else blocks to track down exactly where the init script is hanging, check mongodb's logs, and report back to us.

Bash script send enter key or prevent cat hang

I am currently running a Minecraft server in a screen session with this command:
(tail -f /path/to/fifo & cat) | java -Xmx2048M -jar minecraft_server.jar nogui
You can shutdown a minecraft server by sending 'stop' in the server console. I am using the fifo to send commands from other bash scripts, and cat to allow input from the actual Minecraft server console in the screen session.
What happens though, is that if you put the command 'stop' in the actual minecraft console, the server ends up hanging right before it should exit because of the 'cat' command. The only way to get past this, is to press enter again after sending the stop command.
How can I get 'cat' to not cause this to hang?
Edit: The full script.
#!/bin/bash
serverDirectory=/opt/games/minecraft
pidFile=$serverDirectory/server.pid
fifoFile=$serverDirectory/server.fifo
cleanup() {
rm -f $pidFile
rm -f $fifoFile
}
if [ ! -p $fifoFile ]; then
mkfifo $fifoFile && chmod 0777 $fifoFile
fi
echo $$ > $pidFile
# restart server if it stops
while true
do
# how minecraft server should handle an interruption
trap "{ echo 'stop' > $fifoFile ; }" SIGINT
(tail -f $fifoFile & cat) | java -Xmx2048M -jar minecraft_server.jar nogui
echo "Restarting server...."
# if interruption occurs before we restart, stop trying to restart and clean up
trap "{ cleanup ; exit 0 ; }" SIGINT SIGTERM
sleep 5
done
I haven't used a minecraft server, so I don't know if I'm on the right track here, but would this work?
#!/bin/sh
fifo="/path/to/fifo"
mkfifo $fifo
trap "rm -f $fifo" 0 1 2 3 6 15
/path/to/java -Xmx2048M -jar minecraft_server.jar nogui < $fifo &
echo $? > /path/to/minecraft.pid
cat > $fifo
This still doesn't kill off the cat once the server quits, but at least it doesn't block the server. You might want to launch the minecraft server in a function that kills the cat when it exits. I suggest keeping the .pid file for possible future use. :-)

Resources