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

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

Related

how to retrieve open file handle count for a pid via shell script

I am trying to retreive open file handle count for a particular PID in a variable via shell script and displaying the same.It is not showing the correct count. Can someone please advise?
pid=$(ps -ef | grep 'instance="AC"' | grep -v grep | awk '{print $2}') f_count=$(ls /proc/$'{pid}' | wc -l)
Expected output:
=============
When executed in command line , it shows
ps -ef | grep 'service_instance="AC"' | grep -v grep | awk '{print $2}'
25939
ls /proc/25939/fd | wc -l
98
Actual Output:
f_count= 0
Appreciate your help, thanks
Suggesting to replace:
pid=$(ps -ef | grep 'instance="AC"' | grep -v grep | awk '{print $2}')
With:
pid=$(pgrep -f 'instance="AC"')
Notice that pid takes the first matched process.
If there are more than one matched process pgrep returns multiple lines.
Suggesting to replace:
f_count=$(ls /proc/$'{pid}' | wc -l)
with
f_count=$(ls /proc/${pid}/fd | wc -l)
Or all together in one line
f_count=$(ls /proc/$(pgrep -f 'instance="AC"')/fd | wc -l)

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

AWK variable input

I've got the following bash code:
md5sum -c checksum.md5 2>&1 | grep FAILED | awk '{print $1}' | sed 's/:$// > /tmp/check.tmp
awk '{system("wget http://example.com/"$1"")}' /tmp/check.tmp
How can I use awk without a temp file?
Something like
files=`md5sum -c checksum.md5 2>&1 | grep FAILED | awk '{print $1}' | sed 's/:$//`
awk '{system("wget http://example.com/"$1"")}' $files
You can simplify the whole command to this:
md5sum -c checksum.md5 2>&1 |\
awk -F'[:/]' '/FAILED/{system("wget http://example.com/"$(NF-1))}'
wget has a switch -i that can come in handy:
md5sum -c checksum.md5 2>&1 | \
sed -n '/FAILED$/ { s/: FAILED$//; s!^!http://example.com/!; p; }' | \
wget -i
Like this:
awk '{system("wget http://example.com/"$1"")}' <<< $files

BASH - GREP - invert much not working

I'm trying to find a number of open file descriptors by user "apache". I would like to exclude ls: /proc/PID/fd: No such file or directory but the GREP exclusing is not working:
# for pid in $(lsof -u apache | awk '{ print $2 }' | uniq); do ls -1 /proc/$pid/fd | grep -v "No"; done | wc -l
ls: /proc/PID/fd: No such file or directory
1944
Try |& grep -v "No such file or directory"
Unlike |, |& will also redirect the error output of ls
Try:
for pid in $(lsof -u apache | tail -n +2 | awk '{ print $2 }' | uniq); do ls -1 /proc/$pid/fd ; done | wc -l

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