How to kill process by awk? - bash

In my makefile I have a command
kill `ps aux | awk '/process_name/' | awk '$11 ~ /special_mask/ {print $2}'`
It works through the terminal but when I try to call it through the command make my-command it returns
kill `ps aux | awk '/process_name/' | awk '1 ~ /special_mask/ {print }'`
and it can't execute kill without process id.
How could I fix it?

Makefile needs double $$ for shell commands.
You can use:
ps aux | awk '/[p]rocess_name/ && $$11 ~ /special_mask/{print $$2}' | xargs -r kill

Related

One-liner to retrieve path from netstat port

I'm looking to create a one liner that, given a port number (2550) uses the returned value from netstat would allow me to then run the resulting output against ps -ef to return the path of the process in question. I have:
ps -ef | grep $(netstat -tonp | grep 2550 | awk '{split($7,a,"/"); print a[1]}')
and whilst I know
netstat -tonp | grep 2550 | awk '{split($7,a,"/"); print a[1]}'
returns the expected resulted, the subsequent grep tells me that there is no such file or directory (but, if I do the ps -ef | grep **) it works just fine... I'm obviously missing something... well, obvious, but I can't see what?
try something like (it takes the first PID/port corresponding, not all):
Port=2550;ps -f --pid $( netstat -tonp | awk -F '[ \t/]+' -v Port=$Port '$0 ~ "([0-9]+[.:]){4}" Port { PID= $7;exit}; END { print PID+0 }' ) | sed 's/^\([^ \t]*[ \t]*\)\{7\}//'
the last sed is assuming a ps reply like this (space are important):
usertest 4408 4397 0 09:43 pts/6 00:00:00 ssh -p 22 -X -l usertest 198.198.131.136
for every PID and with no ending sed:
Port=2550; ps -ef | awk -v PIDs="$( netstat -tonp | awk -F '[ \t/]+' -v Port=${Port} '$0 ~ (":" Port) { print $7}' )" 'BEGIN{ split( PIDs, aTemp, /\n/); for( PID in aTemp) aPID[ aTemp[PID] ] }; $2 in aPID { sub( /^([^ \t]*[ \t]*){7}/, ""); print}'
This will give you the pids:
<sudo> netstat -tulpen | awk '$4 ~ /:2550$/{sub("/.*","",$NF);print $NF}'
You can use xargs to pass the pid to ps:
netstat -tulpen | awk '$4 ~ /:2550$/{sub("/.*","",$NF);print $NF}' | xargs -P 1 ps -o pid,cmd -p

How to feed the output of one pipe to another pipe?

I have a command here:
ps aux | grep -i java | grep -i test | awk '{ print $2 }'
which gives only one process id like 1201. Now I want to kill them by piping the 1201 to kill command.
How do I do that?
I tried tee like this:
ps aux | grep -i java | grep -i test | awk '{ print $2 }' | tee >(kill -9)
but that gives:
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
where I'm making mistake?
Use xargs to convert standard input to command-line parameters
ps aux | grep -i java | grep -i test | awk '{ print $2 }' | xargs kill

How to escape grep and awk within pipe in an alias?

I want to create an alias for an long command. But I'm not able to escape it correct, I guess it's a problem with the pipes.
My original command
ps aux | grep gimp | awk '{ print $2 '\011' $11 }' | grep -v 'grep'
My attempt for an alias
alias psa="ps aux | grep $1 | awk '{ print \$2 \"\011\" \$11 }' | grep -v 'grep'"
But I get an error that grep can not open file foo (when I do psa foo)
When I remove the last part | grep -v 'grep' then awkthrows the same error.
I prefer an alias before an shell script.
You need to use a function if you want to to insert arguments:
psa() {
ps aux | grep "$1" | awk '{print $2 "\t" $11 }' | grep -v grep
}
You can avoid all the escaping by using a function for this:
myps() {
ps aux | grep gimp | awk '{ print $2 "\011" $11 }' | grep -v 'grep'
}

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).

shell command to find a process id and attach to it?

I want to attach to a running process using 'ddd', what I manually do is:
# ps -ax | grep PROCESS_NAME
Then I get a list and the pid, then I type:
# ddd PROCESS_NAME THE_PID
Is there is a way to type just one command directly?
Remark: When I type ps -ax | grep PROCESS_NAME, grep will match both the process and grep command line itself.
There is an easy way to get rid of the grep process:
ps -ax | grep PROCESS_NAME | grep -v ' grep '
(as long as the process you're trying to find doesn't include the string " grep ").
So something like this should work in a script (again, assuming there's only one copy running):
pid=$(ps -ax | grep $1 | grep -v ' grep ' | awk '{print $1}')
ddd $1 ${pid}
If you call your script dddproc, you can call it with:
dddproc myprogramname
Although I'd add some sanity checks such as detecting if there's zero or more than one process returned from ps and ensuring the user supplies an argument.
As separate commands:
% PID=`ps -ax | grep ${PROCESS_NAME} | grep -v grep | cut -d ' ' -f 1-2`
% ddd ${PROCESS_NAME} ${PID}
In one line:
% PID=`ps -ax | grep ${PROCESS_NAME} | grep -v grep | cut -d ' ' -f 1-2` && ddd ${PROCESS_NAME} ${PID}
ddd <process_name> `pgrep <process_name>`
you can use pggrep to find the process
You can use awk to both filter and get the column you want. The "exit" limits the ps results to the first hit.
function ddd_grep() {
ddd $(ps -ax | awk -v p="$1" '$4 == p { print $1; exit 0; }');
}
ddd_grep PROCESS_NAME
You may have to adjust the columns for your ps output. Also you can change the == to ~ for regex matching.
Do this way -
ddd PROCESS_NAME \`ps -ax | grep PROCESS_NAME | grep -v grep | awk '{print $1}'\`

Resources