ps working on command line but not in script - bash

I have a simple script that checks the process id of some process using ps. When I run it directly on command line, it works fine but does not when I run it in a script. What am I doing wrong?
This works fine:
ps auwx | grep elasticsearch | grep -v grep | grep user | awk '{print $2}' | tail -1
In script, it does not:
#!/bin/bash
#Setting ES Heap to 50GB
ES_HEAP_SIZE="50g"
#Finding dump file to be deleted
FILE_ID=$(ps auwx | grep elasticsearch | grep -v grep | grep user | awk '{print $2}' | tail -1)
FILE_NAME="java_pid$FILE_ID.hprof"
echo "Elasticsearch pid: $FILE_ID"
echo "Dump file name if it exists: $FILE_NAME. Checking now."
if [ -s $FILE_NAME ]
then
rm $FILE_NAME
kill -9 $FILE_ID
#Starting elasticsearch daemon
/data/elasticsearch-1.4.4/bin/elasticsearch -d
else
echo "All good. Dump file $FILE_NAME does not exist."
fi

Personal pet peeve: why do you have six executions in your pipeline when two will handle everything you need?
ps auwx | awk '/elasticsearch/ && /user/ { x=$2 } END{ print x; }'
As an aside, you wanted PID? Because it looks like you're reading PPID.
Hope that helps.

Related

script to kill a process in macos bash not working: illegal process id

I created this function to kill a process by partial name, put it in bash_profile, and executed it.
when I run it one command at a time manually, everything works.
but when I call the function, it fails with the output: "illegal process id"
function killServer() {
pid=$(ps -fe | grep '[p]rocessName' | awk '{print $2}')
if [[ -n $pid ]]; then
kill $pid
else
echo "Does not exist"
fi
}
output:
kill: illegal process id: i311821
running
ps -fe | grep '[p]rocessName'
gives:
1543721191 1947 1946 0 9:12AM ?? 0:46.76 ../../jdk/bin/java -server -da -XX:PermSize=256m Xrunjdwp:transport=dt_socket,address=8000,suspend=n,server=y -DMonitorDisabled -Xms2048m -Xmx2048m -Dwrapper.port=32000 -com.XXX.YYY.server.util.Main -b 0.0.0.0 -c default
what is the reason for that?
found the problem:
a space after $2 was missing. after the fix, it works:
ps -ef | grep "[X]XX" | grep -v grep | awk '{print $2 }' | xargs kill -9

Bash process id query

I just saw a code with a check in if as
for x in `ps -ef | awk '{ print $2 }'`
do
if [ "$x" != "PID" ];then
----- do something -----
fi
done
May I know why do we need to have this check in if and what is it doing ?
That check is added to skip the header part. you can remove whole if statement by modifying awk statement to skip first line. To find out what header is run ps -eaf |head -n 1 .
for x in $(ps -ef | awk 'NR>1{ print $2 }')
do
--------Do something with $x---------
done
If you run ps -ef you will notice, that it will print a header:
UID PID PPID TTY STIME COMMAND
[...]
the check skips the header.
ps -ef | awk '{ print $2 }' outputs' as below; the first line is PID, so if statetement is used exclude PID line;
user#host:/tmp$ ps -ef | awk '{ print $2 }' | head
PID
1
2
3
5
7
8
9
10
you can also use this without if;
#!/bin/bash
for x in `ps -ef | awk '{ print $2 }' | grep -v PID`
do
#----- do something -----
echo $x
done

Tail -Fn0 and variable

This follows on from Faulty tail syntax or grep command? but I'm reading a live log entries for given conditions and when they're met continuing the execution of the rest of the script. I'm using this:
tail -Fn0 /var/log/messages | grep -q "CPU utilization" | grep -q "exceeded threshold"
FPC=$(echo $line | awk 'END { print substr($8,1,1) }')
PIC=$(echo $line | awk 'END { print substr($11,1,1) }')
echo FPC $FPC
echo PIC $PIC
echo "Running information gathering"...and rest of script.
Which works perfectly for the conditions detection and further execution, but I don't have the log entry to test for the FPC and PIC variables. I've tried wrapping the tail statement thus:
line=$(tail -Fn0 /var/log/messages | grep -q "CPU utilization" | grep -q "exceeded threshold")
but grep -q exits silently and the $line variable is blank. I've tried:
line=$(tail -Fn0 /var/log/messages | grep -m1 "CPU utilization" | grep -m1 "exceeded threshold")
which doesn't work until I attempt to CONTROL-C out of the script. Then it works fine and continues perfectly. Can someone help please?
I need the variables FPC and PIC later in the script.
Assuming that you don't need these variables later on, you could do something like this:
tail -Fn0 /var/log/messages | \
awk '/CPU utilization/ && /exceeded threshold/ {
print "FPC", substr($8,1,1); print "PIC", substr($11,1,1); exit }'
When the line matches both patterns, print the two parts of it that you are interested in and exit.
If you do need the variables, you could do something like this instead:
line=$(tail -Fn0 /var/log/messages | awk '/CPU utilization/&&/exceeded threshold/{print;exit}')
FPC=$(echo "$line" | awk '{ print substr($8,1,1) }')
PIC=$(echo "$line" | awk '{ print substr($11,1,1) }')

Move a file which is constantly in use

I need to move the whole content of a file (test.log) which is constantly in use. Moving the file could result in an error for the application which is writing to the file.
My approach is to redirect the output to test.log_bck, copy the original file (test.log) to test.log_cp, clear it and then check if there was any data added in the same time the test.log file was cleared. If any data was missing from the _cp file then merge it with the _bck file without redundant data. It is a lot of effort for such an easy task and my question is: is there another, easier / more efficient way to do it.
#/usr/bin/bash
#redirect the output to /tmp/logging/test.log_bck
bck(){
`tail -f /tmp/logging/test.log &> /tmp/logging/test.log_bck`
}
#run it in background
bck &
#copy the original file to test.log_cp
`cp /tmp/logging/test.log /tmp/logging/test.log_cp` | echo "Copped"
#clear the original file
echo "" > /tmp/logging/test.log | echo "Cleared"
#get the PID of the redirection process and check if there are other running and kill them
bck_pid=`ps -ef | grep "tail -f /tmp/logging/test.log" | grep -v grep | awk '{print$2}' | head -1`
while [ "$bck_pid" != "" ]
do
echo $bck_pid
kill $bck_pid | echo "Killed"
bck_pid=`ps -ef | grep "tail -f /tmp/logging/test.log" | grep -v grep | awk '{print$2}' | head -1`
done
date=$(date '+%Y_%m_%d_%H_%M')
cat /tmp/logging/test.log_cp /tmp/logging/test.log_bck > /tmp/logging/test.log_$date
cat -n /tmp/logging/test.log_$date | sort -uk2 | sort -nk1 | cut -f2-

Shell Script to find PID of ssh and kill the PID if present

I am trying to write a script to find a reverse SSH PID and kill it if present. I am stuck on "awk" as it gives error. below is the script:
a=('ps -aef | grep "ssh -fN" | grep -v grep | awk '{ print $2 }'')
if [ -n "$a" ]
then
echo "String \"$a\" is not null."
kill -9 "$a"
fi
I commented out if, then, kill and fi lines to debug the script. I get following error:
String "ps -aef | grep "ssh -fN" | grep -v grep | awk {" is not null.
I believe parenthesis for awk is creating the problem and I am unable to get a workaround for this. On Command line, this works perfectly and returns the correct PID.
ps -aef | grep "ssh -fN" | grep -v grep | (awk '{ print $2 }'
Once the PID is passed on to variable "a", I need to issue kill command. OS is Centos 6.4
P.S: I am not fluent on scripting but trying to achieve an objective. Help will be highly appreciated!
There are multiple problems with your script.
You need command substitution to store the output of ps pipeline into an array.
You need to check for the number of elements in the array.
Refer to the array instead of the variable.
The following might work for you:
pids=( $(ps -ef | grep '[s]sh -fN' | awk '{print $2}') )
if [ "${#pids[#]}" -gt 0 ]; then
kill -9 "${pids[#]}";
fi
First, if you have grep and then awk, you can get rid of the greps:
ps -aef | grep "ssh -fN" | grep -v grep | awk '{ print $2 }'
ps -aef |awk ' { if ( ($0 ~ /ssh -FN/) && (! $0 ~ /grep/) ) { print $2 } }'
However, instead of using ps, use pgrep.
pgrep -f "ssh -[fN][fN]" # Will match against either 'ssh -fN' or 'ssh -Nf'
There is even a pkill that will do the entire command for you:
pkill -f "ssh -[fN][fN]"
That will find all of the processes that match that particular string and kill them (if they exist).

Resources