Bash Script not executing command - bash

I have a bash script that is supposed to check for a running instance of a program and if its not running execute a command (echo for testing purposes). The problem is, that bash isn't executing the command even though it works when I copy/paste the command directly to the command line. I imagine my issue is simple and caused by my naivety with the script language.
The line in question:
ps -ef | grep -v grep | grep $SCRIPT > /dev/null || echo "`date` - $0 : $SCRIPT stopped. Restarting..."
If I paste it to the command line it works perfect, but when I run my script nothing happens. Suggestions?
EDIT: I believe I've resolved the issue. The script that is run to check the queue_reader.sh script I foolishly named check_queue_reader.sh" so the ps -ef command was finding itself preventing the || from executing.

See edit on original post.
The script I was running was called "check_queue_reader.sh" and was using grep to search ps -ef for "queue_reader.sh". This caused the script to locate itself thus failing the check when it got to ||

Related

Shell script returning non zero value after killing process

I am trying to kill a process using a shell script.Looks shell itself is getting killed in this process. Also I am seeing non zero return value of the script in terminal.
I am running it on Amazon Linux 2 with sudo.
#!/bin/bash
kill -9 $(ps -ef | grep myapp | grep -v grep | awk '{print $2}')
I am executing like:
sudo ./myscript.sh
"echo $?" after executing is returning 137 instead of zero. Can someone please help to understand what is going wrong.
Another observation:
if i directly run kill command in my terminal, i.e below command,
kill -9 $(ps -ef | grep myapp | grep -v grep | awk '{print $2}')
I see echo $? is returning zero.
Update:
Problem is solved. Name of process I am trying to kill is overlapping with name of my script. Hence grep is returning both the pid's. Both the process are getting killed. Also learnt that better way of doing this by using pkill or using pidof() to get pid.
If you want the exit code of your last-run command to be the exit code for the script, your script must end with exit $? as the last line. Any function before that must also end with the $? so the chain flows to that final line. Otherwise some other exit is taking place.
If the script is being killed along side the application or script you are trying to kill, then your ps and grep work is likely including both in the results. Look at the output of the ps and grep while the script is running. You could add a line prior to your kill line which just shows the output of the ps and greps so you can see what is actually getting killed.
Finally (and I don't think this is the case) if you are trying to end the script after the kill, manually run an exit (again likely using exit $? for the reason stated above) where appropriate within the script.
Hope that helps you get where you are going.

Cron job won't start again after I stopped it?

I wrote a script to run constantly on startup. If for whatever reason the script were to fail, I wrote a second script to check if it has failed, and if so, run the first script again. I then set this second script as a cronjob to run every minute so that it is constantly checking if the first script is alive.
So to test this, I reboot my system. I can see in htop that the first script is running from start up as expected. Good. I kill the process to test the second script. Sure enough, the second script starts the first script again. Still good. I then kill this process, but the second script won't run again now. It still updates a txt file when I manually start the first script, but the second script just doesn't start the first script like it's supposed to. Is it because I killed the cronjob? Restarting the cron service doesn't fix anything though, so I don't know why my second script isn't running again at all.
First script:
#!/bin/bash
stamp=$(date +%Y%m%d-%H%M)
timeout 10d tcpdump -i eth0 -s 96 -z gzip -C 10 -w /home/user/Documents/${stamp}
Second script:
#!/bin/bash
echo "not running" > /home/working.txt
if (( $(ps -ef | grep -v grep | grep tcpdump.sh | wc -l) > 0 ))
then
echo "tcpdump is running!!!" > /home/working.txt
else
/usr/local/bin/tcpdump.sh start
fi
Any help?
You would probably be better off running a simple for loop as the main script, and that kicks off the tcpdump script in the background, so something like:
#!/bin/bash
while true; do
if ps -ef | grep -v grep | grep -q tcpdump; then
: tcpdump running OK
else
# tcpdump not running - start it off
nohup /usr/local/bin/firstscript.sh start &
fi
sleep 30
done
This checks that "tcpdump.sh" is in the output of the "ps -ef" command - if it is, then do nothing (note that you must have an actual command between the "then" and "else" - the ":" command, which just takes it s arguments and ignores them, is sufficient). If it isn't running, start the first script in the background. Then sleep 30 seconds and check again. (Yes, I could have inverted the test so that I didn't need an empty "then" arm, but it would have made the code less obvious)
You put this script as the one which starts at boot time.
Edit: Do you really want to check for "tcpdump.sh"? Is that what the first script is actually called? Assuming that you actually want to check for the tcpdump program, you could use:
if pgrep tcpdump; then

Run two shell commands

What would be the correct format for the following, where I want to execute two scripts? The following is only executing the first one for me:
if ps aux | grep -E "[a]ffiliate_download.py|[g]oogle_download.py" > /dev/null
then
echo "Script is already running. Skipping"
else
exec "$DIR/affiliate_download.py"
exec "$DIR/google_download.py"
fi
The exec command replaces the current shell process with the program it runs. Since the shell is no longer running, it can't run commands after that.
Just execute the commands normally:
else
"$DIR/affiliate_download.py"
"$DIR/google_download.py"
fi

Using variables and multiple pips in bash?

I'm trying to finish up a maintenance script, and I'm getting caught up with the following line:
PUID=$(ps aux | grep $PID | grep -v $USER| cut -d' ' -f1)
I'm trying to pull a specific process ID ($PID) out of the ps aux command, (while ignoring the process the user just created with the same PID), then eliminate all but the user name of the process owner.
Currently, the command runs fine when run in the command line, however I've been having issues assigning it to the variable $PUID, or even just executing it as a command. Any advice?
EDIT:
I'm trying to get this figured out and I believe there is still a problem in passing the variable $PID, right now it's pulling from a file (which it does properly) using this line
PID=$(cat /nfs/pdx/home/komcconx/PID/current/pid)
and if I add an echo $PID it returns the proper pid.
when I run the command PUID=$(ps -p $PID -o uname=), I get an error saying "ERROR: Process ID list syntax error." and if I runn the command with a "1" in the place of $PID it properly returns "root"
any ideas?'
Final edit:
Found out the issue was the PID was being pulled from a DOS file, and I was trying to run the command with a DOS newline, this issue is closed!
If you only want the user name of a process you can use -o option:
PUID=$(ps -p $PID -o uname=);
echo $PUID

Bash: How can I make a sync call until finding a match pattern in log file

I have a start server script
startserver.sh
It will run as background task startserver.sh &
the script need to run for sometime until it can really run in running state.
The running state could write into log file server.log when it is ready.
So I need to know when the server is really run by executing a bash cmd. If not, I need to wait until the Running state is shown in the server.log.
Can i achieve this in bash?
try something like this
mkfifo my_fifo
tail -f server.log >my_fifo &
tail_pid=$!
perl -ne '/pattern/&&exit' <my_fifo
kill $tail_pid
rm my_fifo
EDIT : perl command can be replaced with
grep -l 'pattern' <my_fifo >/dev/null
or if grep support this option
grep -q 'pattern' <my_fifo

Resources