How to use multiple exec command in a upstart script? - linux

Here is what I tried to run multiple exec command , but I am getting output of email but not for the sms . Is there a way to run the both exec command ?
description "starts a kafka consumer for email and sms "
respawn
start on runlevel [2345]
stop on runlevel [!2345]
env FOUNDATION_HOME=/opt/home/configs
env VIRTUAL_ENV=/opt/home/virtualenvs/analytics
# run as non privileged user
setuid xxx
setgid xxx
console log
chdir /opt/xxx
exec stdbuf -oL /opt/xxx/virtualenvs/analytics/bin/python -m yukon.pipelinerunnerexternal /opt/xxx/configs/datastream.pheme_sms > /tmp/sms.out 2>&1
exec stdbuf -oL /opt/xxx/virtualenvs/analytics/bin/python -m yukon.pipelinerunnerexternal /opt/xxx/configs/datastream.pheme_email > /tmp/email.out 2>&1
post-start script
PID=`status kafka_upstart | egrep -oi '([0-9]+)$' | head -n1`
echo $PID > /var/tmp/kafka_upstart.pid
end script
post-stop script
rm -f /var/tmp/kafka_upstart.pid
end script

You can try concatenating them with && (assuming they're not blocking indefinitely):
exec stdbuf -oL /opt/xxx/virtualenvs/analytics/bin/python -m yukon.pipelinerunnerexternal /opt/xxx/configs/datastream.pheme_sms > /tmp/sms.out 2>&1 && stdbuf -oL /opt/xxx/virtualenvs/analytics/bin/python -m yukon.pipelinerunnerexternal /opt/xxx/configs/datastream.pheme_email > /tmp/email.out 2>&1
Or put the commands in a separate script, kafkalaunch.sh, then run the script:
exec kafkalaunch.sh
Which is more elegant in my opinion.

Related

How to stop supervisor process with piped command

I want to send server logs to the telegram bot. Here's my supervisor config:
[program:telegram-log-nginx]
process_name=%(program_name)s_%(process_num)02d
command=bash -c 'tail -f /var/log/nginx/error.log | /usr/share/telegram_log.sh nginx'
autostart=true
autorestart=true
numprocs=1
When I stop supervisor
supervisorctl stop telegram-log-nginx:*
the process is still running:
ps aux | grep telegram
www-data 32151 0.0 0.0 21608 3804 ? S 20:53 0:00 /bin/bash /usr/share/telegram_log.sh nginx
Is there a proper way to stop all processes?
telegram_log.sh
#!/bin/bash
CHATID="chat"
KEY="key"
SERVICE=$1
TIME="10"
URL="https://api.telegram.org/bot$KEY/sendMessage"
while IFS= read -r line; do
read -r -d '' TEXT <<- EOM
Service: $SERVICE
$line
EOM
curl -s --max-time $TIME -d "chat_id=$CHATID&disable_web_page_preview=1&text=$TEXT" $URL >/dev/null
done
├─supervisord,1101 /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
│ ├─php,643187 /var/www/web/artisan queue:work
│ ├─php,643188 /var/www/web/artisan queue:work
│ ├─php,643189 /var/www/web/artisan queue:work
├─systemd,640839 --user
│ └─(sd-pam),640841
├─systemd-journal,406
├─systemd-logind,1102
├─systemd-resolve,807
├─systemd-timesyn,684
│ └─{systemd-timesyn},689
├─systemd-udevd,440
├─tail,643203 -f /var/log/nginx/error.log
├─telegram_log.sh,643204 /usr/share/telegram_log.sh nginx
Assuming that you have a new enough version of bash that process substitutions update $!, you can have your parent script store the PIDs of both its direct children and signal them explicitly during shutdown:
#!/usr/bin/env bash
# make our stdin come directly from tail -f; record its PID
exec < <(exec tail -f /var/log/nginx/error.log); tail_pid=$!
# start telegram_log.sh in the background inheriting our stdin; record its PID
/usr/share/telegram_log.sh nginx & telegram_script_pid=$!
# close our stdin to ensure that we don't keep the tail alive -- only
# telegram_log.sh should have a handle on it
exec </dev/null
# define a cleanup function that shuts down both subprocesses
cleanup() { kill "$tail_pid" "$telegram_script_pid"; }
# tell the shell to call the cleanup function when receiving a SIGTERM, or exiting
trap cleanup TERM EXIT
# wait until telegram_log.sh exits and exit with the same status
wait "$telegram_script_pid"
This means your config file might become something more like:
command=bash -c 'exec < <(exec tail -f /var/log/nginx/error.log); tail_pid=$!; /usr/share/telegram_log.sh nginx & telegram_script_pid=$!; exec </dev/null; cleanup() { kill "$tail_pid" "$telegram_script_pid"; }; trap cleanup TERM EXIT; wait "$telegram_script_pid"'
#CharlesDuffy has provided the answer
bash -c 'tail -f /var/log/nginx/error.log | /usr/share/telegram_log.sh nginx'
should be
bash -c 'exec < <(exec tail -f /var/log/nginx/error.log); exec /usr/share/telegram_log.sh nginx'

Get PID of a remote process started with sshpass

I have a bash script which need to start some process on remote machine.
I have done that using sshpass command.
I need to store the PID of that remote process.
I tried the following with a script:
sshpass -p password ssh user#ipaddr /bin/bash << EOF
nohup process > /dev/null 2>&1 & echo $! > pid_file
cat pid_file
EOF
when I check with remote machine, the process is started and pid_file also has a number written in it. But the process id and number of pid_file do not match.
Executing the above set of commands directly on terminal without script, doesn't write anything in pid_file.
Can somebody help in storing the right pid of remote process.
sshpass -p password ssh user#ipaddr /bin/bash << EOF
nohup process > /dev/null 2>&1 & echo $! > pid_file
cat pid_file
EOF
The thing is that $! get's expanded not on the remote computer, but on your computer. When using the Here document, variable names are replaced by their values. So it gets expanded to whatever process you have had run in the background on you computer. You need to execute echo $! on the remote computer. That's why it's good to use -c and to always properly enclose the arguments.
sshpass -p password ssh user#ipaddr /bin/bash -c 'nohup process >/dev/null 2>&1 & echo $! > pid_file'
or you can just escape the $!:
sshpass -p password ssh user#ipaddr /bin/bash <<EOF
nohup process > /dev/null 2>&1 & echo \$! > pid_file
cat pid_file
EOF
or the best is to use quoted here string delimiter:
sshpass -p password ssh user#ipaddr /bin/bash <<'EOF'
nohup process > /dev/null 2>&1 & echo $! > pid_file
cat pid_file
EOF

Launch mvn exec:java as linux daemon

I am trying to execute the mvn plugin exec:java as a deamon on linux. When I do it "manually" from the console it seems to work:
$ nohup mvn -f $PATH_TO_POM exec:java -Pxyz &
launches the daemon and redirects the usual console output to the file nohup.out. I could not figure out what the -P parameter does, but I can use it to find the pid of the launches process and to kill the process
$ pgrep -f xyz # returns some pid, e. g. 12345
$ kill 12345
When I try to launch the daemon from within a simple bash script
# this is part of bash script in separate file
$ nohup mvn -f $PATH_TO_POM exec:java -Pxyz /tmp 2>> /dev/null >> /dev/null &
$ pgrep -f xyz # returns some pid, e. g. 12345
$ jps -l # shows that 12345 belongs to org.codehaus.plexus.classworlds.laucher.Laucher
$ jps -m # shows "12345 Launcher -f $PATH_TO_POM exec:java -Pxyz /tmp"
it fails, because after executing the file above and then
$ ps -p 12345
there is no such process with PID 12345, although the script above delivers the PID.
$ nohup mvn -f $PATH_TO_POM exec:java -Pxyz 2>> /dev/null >> /dev/null &
without /tmp works

Run jar file as Daemon on Linux Ubuntu

I want to install a bot to my Teamspeak3 and run this bot as a daemon on startup. I wrote my own script and copied it to init.d and then added it with update-rc.d to defaults.
#!/bin/sh
#
# JTS3ServerBot Script
#
USER="ts"
NAME="jts3"
DIR="/home/ts/jts3/"
case $1 in
start)
echo "Starting ${NAME} ..."
if [ ! -f $DIR/pid ]; then
sudo -u $USER -c nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>> /dev/null >> /dev/null &
echo $! > $DIR/pid
echo "${NAME} started ..."
else
echo "${NAME} is already running ..."
fi
;;
stop)
if [ -f $DIR/pid ]; then
PID=$(cat $DIR/pid);
echo "Stopping ${NAME} ..."
kill $PID;
echo "${NAME} stopped ..."
rm $DIR/pid
else
echo "${NAME} is not running ..."
fi
;;
restart)
if [ -f $DIR/pid ]; then
PID=$(cat $DIR/pid);
echo "Stopping ${NAME} ...";
kill $PID;
echo "${NAME} stopped ...";
rm $DIR/pid
echo "Starting ${NAME} ..."
sudo -u $USER -c nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>> /dev/null >> /dev/null &
echo $! > $DIR/pid
echo "${NAME} started ..."
else
echo "${NAME} is not running ..."
fi
;;
esac
A pid file in generated, but if i try to kill the process with this pid i get an error that the process does not exist. If i use top there is no process with the pid listed.
root#vps-1023645-8462:~# service jts3 start
Starting jts3 ...
jts3 started ...
root#vps-1023645-8462:~# cat /home/ts/jts3/pid
10206
root#vps-1023645-8462:~# kill 10206
bash: kill: (10206) - No such process
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1762 ts 20 0 1881m 14m 3408 S 0 1.4 215:47.28 ts3server_linux
32356 ts 20 0 164m 1576 1336 S 0 0.2 0:09.85 tsdnsserver_lin
I have found another solution for my problem. I use upstart (works only with Ubuntu) to run my jar-File as a daemon. Upstart manages the PIDs. Just add myservice.conf to /etc/init (not /etc/inid.d) and the daemon will be started on boot and you can mangage it as a service. You do not have to make the file runnable or anything else
You can manage the service as normal for example
service myservice restart
service myservice status
...
My Config-File:
description "myservice"
author "your name"
start on runlevel [3]
stop on shutdown
expect fork
script
cd /home/username/
sudo -u username java -jar /home/username/myservice/myservice.jar >/home/username/myservice.log 2>&1
emit myservice_running
end script
This solution is really easy and works well on my Ubuntu 12.04 Server.
You have an error in this line:
sudo -u $USER -c nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>>/dev/null >>/dev/null&
You appear to be mixing the syntaxes of sudo and su. Before version 1.8, sudo had no -c option - you just give it the command to run after any other options. In 1.8 there is a -c option but it's not for specifying the command (it's for limiting resource usage to that of a given login class). sudo is printing an error message about this invalid syntax, but you're not seeing it because you're redirecting all the output to /dev/null.
Simply remove the -c to form a valid command:
sudo -u $USER nohup java -jar $DIR/JTS3ServerMod.jar $DIR 2>> /dev/null >> /dev/null &
Also, you can simplify the command a little by using the 2>&1 syntax to send stderr to the same handle as stdout, and there is no need for append mode when writing to /dev/null:
sudo -u $USER nohup java -jar $DIR/JTS3ServerMod.jar $DIR >/dev/null 2>&1 &

Getting sudo and nohup to work together

Linux newbie here.
I have a perl script which takes two command line inputs. I tried to run it in the background but this is what I got:
[~user]$ nohup sudo ./ascii_loader_script.pl 20070502 ctm_20070502.csv &
[2] 19603
[~user]$ nohup: appending output to `nohup.out'
after the system returns "nohup: appending output to `nohup.out'", no new prompt will appear. Then as long as I type in some other command, the shell will tell me that the process is stopped:
[~user]$ nohup sudo ./ascii_loader_script.pl 20070502 ctm_20070502.csv &
[2] 19603
[~user]$ nohup: appending output to `nohup.out'
ls
ascii_loader_script.pl format_wrds_trd.txt nohup.out norm_wrds_trd.cfg
[2]+ Stopped nohup sudo ./ascii_loader_script.pl 20070502 ctm_20070502.csv
I've looked at this post and tried to do "sudo date" before executing the command. Still got the same thing.
http://www.sudo.ws/pipermail/sudo-users/2003-July/001648.html
The solution is to use the -b flag for sudo to run the command in the background:
$ sudo -b ./ascii_loader_script.pl 20070502 ctm_20070502.csv
You should only use nohup if you want the program to continue even after you close your current terminal session
The problem here, imho, is not nohup, but background processing sudo.
You are putting the process in background (& at end of command) but probably sudo needs password authentication, and that is why the process stops.
Try one of these:
1) remove the ampersand from end of command, reply to passord prompt and afterwords put it in background (by typing CTRL-Z - which stops the process and issuing the bg command to send it to background)
2) Change the /etc/sudoers to not ask for users password by including the line:
myusername ALL=(ALL) NOPASSWD: ALL
If besides the password reply your application waits for other input, then you can pipe the input to the command like this:
$ cat responses.txt|sudo mycommand.php
hth
You can Try
sudo su
and then
nohup ./ascii_loader_script.pl 20070502 ctm_20070502.csv &
instead of
nohup sudo ./ascii_loader_script.pl 20070502 ctm_20070502.csv &
You must use sudo first, nohup second.
sudo nohup ./ascii_loader_script.pl 20070502 ctm_20070502.csv &
My working solution for evaluating disk fragmentation in the background:
Exec sudo with nohup without ampersand (&) at the end:
$ sudo nohup nice -20 find / -type f -exec filefrag "{}" \; | sed 's/^\(.*\): \([0-9]\+\) extent.*/\2\t\1/'| awk -F ' ' '$1 > 0' | sort -n -r | head -50 > filefrag.txt
Enter password for sudo;
Press Ctrl+Z;
Put the running process in the background.
$ bg 1
[1]+ sudo nohup nice -20 find / -type f -exec filefrag "{}" \; | sed 's/^\(.*\): \([0-9]\+\) extent.*/\2\t\1/' | awk -F ' ' '$1 > 0' | sort -n -r | head -50 > filefrag.txt &
Now you can exit the terminal and log in later. The process will remain running in the background. Because nohup is used.
First of all, you should switch sudo and nohup.
And then:
if sudo echo Starting ...
then
sudo nohup <yourProcess> &
fi
The echo Starting ... can be replaced by any command that does not do much.
I only use it as dummy command for the sudo.
By this the sudo in the if-condition triggers the password-check.
If it is ok then the sudo session is logged in and the second call will succeed, otherwise the if will fail and not execute the actual command.
I open an editor and typed these lines:
#!/bin/bash
sudo echo Starting ...
sudo -b MyProcess
(Where MyProcess is anything I want to run as superuser.)
Then I save the file where I want it as MyShellScript.sh .
Then change the file permissions to allow execution.
Then run it in a terminal. the "-b" option tells sudo to run the process separately in the background, so the process keeps running after the terminal session dies.
Worked for me in linux-mint.
You can set it as your alias:
sudo sh -c 'nohup openvpn /etc/openvpn/client.ovpn 2>&1 > /dev/null &'
This should work
sudo -b -u userName ./myScript > logFile
I am just curious to understand that can I send this logFile as a email after the ./myScript is successful running in background.
Try:
xterm -e "sudo -b nohup php -S localhost:80 -t /media/malcolm/Workspace/sites &>/dev/null"
When you close xterm, the PHP web server still alive.
Don't put nohup before sudo or else the PHP web server will be killed after closing xterm.

Resources