why nohup does not launch my script? - linux

Here is my script.sh
for ((i=1; i<=400000; i++))
do
echo "loop $i"
echo
numberps=`ps -ef | grep php | wc -l`;
echo $numberps
if [ $numberps -lt 110 ]
then
php5 script.php &
sleep 0.25
else
echo too much process
sleep 0.5
fi
done
When I launch it with:
./script.sh > /dev/null 2>/dev/null &
that works except when I logout from SSH and login again, I cannot stop the script with kill%1 and jobs -l is empty
When I try to launch it with
nohup ./script.sh &
It just ouputs
nohup: ignoring input and appending output to `nohup.out'
but no php5 are running: nohup has no effect at all
I have 2 aleternatives to solve my problem:
1) ./script.sh > /dev/null 2>/dev/null &
If I logout from SSH and login again, How can I delete this job ?
or
2) How to make nohup run correctly ?
Any idea ?

nohup is not supposed to allow you to use jobs -l or kill %1 to kill jobs after logging out and in again.
Instead, you can
Run the script in the foreground in a GNU Screen or tmux session, which lets you log out, log in, reattach and continue the same session.
killall script.sh to kill all running instances of script.sh running on the server.

Related

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

Shell Script is not generating the logs file

I am trying to capture the netstat command logs for every minute.I have written a script which runs in loop.But my script executes till capturing logs statement into test.sh code.
test.sh
#!/bin/sh
export TODAY=`date`
export i=0
while [ true ]
do
echo "capturing logs" $i
sh test1.sh > test$i.log
echo "sleeping for 1m"
sleep 60
i=$((i+1))
done
test1.sh
#!/bin/sh
netstat -l 5575 | while IFS= read -r line; do printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$line"; done
The output from above script is :
capturing logs
(If i press crtl-c then it move further and it display "sleeping for 1m" statement and i need to press again crtl-c when it comes to "capturing logs statement").
sh test1.sh > test$i.log
Is waiting for test1.sh to finish, which probably takes way too long to complete.
Try to execute test1.sh in another tty like
setsid sh -c 'exec [launch the script] <> /dev/tty[number_of_tty] >&0 2>&1'
and let me know.
Be careful not to run a lot of processes on the same tty. You can play with [number_of_tty] to avoid this.
Could solve the problem, could not, but it's worth trying.

Check whether a process is running or not Linux

Here is my code:
#!/bin/bash
ps cax | grep testing > /dev/null
while [ 1 ]
do
if [ $? -eq 0 ]; then
echo "Process is running."
sleep 10
else
nohup ./testing.sh &
sleep 10
fi
done
I run it as nohup ./script.sh &
and it said nohup: failed to run command './script.sh': No such file or directory
What is wrong?
The file script.sh simply does not exist in the directory that you are issuing the command from.
If it did exist and was not executable you would get:
`nohup: failed to run command ‘./script.sh’: Permission denied
For each newly created scripts on Linux, you should first change the permission as you can see the permission details by using
ls -lah
The following content may help you:
#!/bin/bash
while [ 1 ];
do
date=`date`
pid=`ps -ef | grep "your process" | grep -v grep | awk -F' ' '{print $2}'`
if [[ -n $pid ]]; then
echo "$date - processID $pid is running."
else
echo "$date - the process is not running"
# script to restart your process
say: start the process
fi
sleep 5m
done
Make sure your script is saved as script.sh
and your executing nohup ./script.sh & from the same directory in which script.sh.
Also you can give executable permission for script.sh by
chmod 776 script.sh
or
nohup ./script.sh &
Run as
nohup sh ./script.sh &

How to run nohup and write its pid file in a single bash statement

I want to run my script in background and then write its pid file. I am using nohup to do this.
This is what i came up with,
nohup ./myprogram.sh > /dev/null 2>&1 & && echo $! > run.pid
But this gives a syntax error.
The following doesn't give syntax error but the problem is echo $! doesn't write the correct pid since nohup is run in a sub shell
(nohup ./myprogram.sh > /dev/null 2>&1 &) && echo $! > run.pid
Any solutions for this, given i want a single line statement for achieving this?
You already have one ampersand after the redirect which puts your script in background. Therefore you only need to type the desired command after that ampersand, not prefixed by anything else:
nohup ./myprogram.sh > /dev/null 2>&1 & echo $! > run.pid
This should work:
nohup ./myprogram.sh > /dev/null 2>&1 &
echo $! > run.pid
Grigor's answer is correct, but not complete.
Getting the pid directly from the nohup command is not the same as getting the pid of your own process.
running ps -ef:
root 31885 27974 0 12:36 pts/2 00:00:00 sudo nohup ./myprogram.sh
root 31886 31885 25 12:36 pts/2 00:01:39 /path/to/myprogram.sh
To get the pid of your own process, you can use:
nohup ./myprogram.sh > /dev/null 2>&1 & echo $! > run.pid
# allow for a moment to pass
cat run.pid | pgrep -P $!
Note that if you try to run the second command immediately after nohup, the child process will not exist yet.

terminate infinite loop initiated in remote server when exiting bash script

Script which executes commands in infinite loop in background
<SOMETHING ELSE AT START OF SCRIPT>
cmd='while true;
do
ps aux | head;
sleep 1;
done > $FILE'
ssh root#$SERVER $cmd &
...
...
<SOME OTHER TASKS>
...
...
( at the end of this script, how to kill the above snippet executing in remote server)
[ kindly note i dont want to wait as the while loop is infinite ]
Read and tried some posts from stackoverflow, but could not find exact solution for this problem.
Rather than an infinite loop, use a sentinel file:
cmd='while [ -r /tmp/somefile];
do
# stuff
done > $FILE'
ssh root#$SERVER touch /tmp/somefile
ssh root#$SERVER $cmd &
# do other stuff
ssh root#$SERVER rm -f /tmp/somefile
This follows your current practice of putting the remote command in a variable, but the arguments against that cited elsewhere should be considered.
If you want to kill the ssh process running in background at the end of your script, just do:
kill $!
I assume this is the only (or the last) process you started in background.
Try following sequence
CTRL+Z
fg
CTRL+C
or
jobs
kill %jobspec
To kill everything belonging to user logged in you could try:
whois=`w|grep $user|awk '{print $2}'`;user=root; ssh $user#server -C "ps auwx|grep $whois|awk '{print \$2}'"
This will list all the processes owned by the user you just logged in as - just add |xargs kill -9
whois=`w|grep $user|awk '{print $2}'`;user=root; ssh $user#server -C "ps auwx|grep $whois|awk '{print \$2}'|xargs kill -9 "
whois=`w|grep $user|awk '{print $2}'`;user=root; ssh $user#server -C "ps auwx|grep $whois|awk '{print \$2}'|awk '{print "kill -9 " $1}'|/bin/sh "

Resources