multiple grep command in Linux - command-line

Just a basic question about grep command line. I found the way how to know that the service is running in process by using this command line:
ps -ef |grep -v grep | grep mongodb
I'm confused about the second grep:
|grep -v grep |
Why I need to use the "grep" after " -v " ???
What is the different between that command and this command ?
ps -ef |grep mongodb
Thank you!

When you grep "mongodb" through command line, your command also contains the word "mongodb" . So you will get two results. Which is flawed result. grep -v is to remove the grep command typed by user.
sh-4.1$ ps -ef |grep -v grep | grep mongodb
ps 17308 30074 0 06:05 pts/300 00:00:00 sh mongodb
vs
sh-4.1$ ps -ef |grep mongodb
ps 17308 30074 0 06:05 pts/300 00:00:00 sh mongodb
ps 17456 30074 0 06:05 pts/300 00:00:00 grep mongodb #<<<This also contains mongodb word. Hence result is flawed.

The -v option tells grep not to let through anything matching the pattern, in this case lines that contain the string "grep".
So if you omit the grep -v grep
your grep process itself would also be displayed in the output after the second command in the pipe (and also after the third, as the grep process itself contains the word "mongodb").

Related

How to write a .sh that get process id of application and then stop the application?

for example, I need to use a app called SomeApp, but it often needs to restart, so I need to type "ps -ef | grep SomeApp" and then "kill -9 7777"
which first find the process id and then stop that process:
XXXX:~ XXXX$ ps -ef | grep SomeApp
333 7777 1 0 1:40PM ?? 0:40.31 /Users/XXXX/SomeApp
333 8888 9999 0 1:58PM abcd000 0:00.00 grep SomeApp
XXXX:~ XXXX$ kill -9 7777
now I want to put the command into .sh, but I have something don't know how to write in .sh:
exclude the result that belongs to my grep action
get the correct line result
get the second argument (process id) of result string
can anyone help?
This'll do it.
ps -ef | grep 'SomeApp' | grep -v grep | awk '{print $2}' | xargs kill
Or look at pgrep and pkill depending on the OS.

Using /proc/<pid>, how can I identify a network port number's application?

I'm trying to identify what application is running on port 56474 without having root access. I know the application was started by me.
Example:
netstat -tunap
tcp 0 0 0.0.0.0:56474 0.0.0.0:* LISTEN -
I've tried using /proc/pid scripts to walk all using grep on ls -l /proc/pid/fd results. Here is my attempt. NOTE: Not sure if I was heading the right direction
for I in `find /proc/*/fd -exec ls -l {} \; 2>/dev/null | awk -F"->|:" '/socket/ {print $4}' | sort -u | sed -e 's/\[//g' -e 's/\]//g'`; do grep $I /proc/*/net/tcp; done
I had no success. Not sure if there is a way. Thanks.
NOTE: Added another answers as lsof was not satisfactory.
This should work:
#! /bin/bash
port=56474
hex_port=$(echo "obase=16; $port" | bc )
inode=$(cat /proc/net/tcp | grep ":$hex_port" | awk '{print $10}')
for i in $(ps axo pid); do
ls -l /proc/$i/fd 2> /dev/null | grep -q ":\[$inode\]" && echo $i
done
Explanation:
Once we have the port number converted to Hexadecimal, we can get the inode number from /proc/net/tcp (10th field), then we loop through /proc/pids/fd and find a symlink pointing to the inode.
If you're sure the application was started by you then you can use lsof:
/usr/sbin/lsof -nP | grep :56474 | awk '{print $2}'
Another technique to resolve pids and ports of all running apps without root:
1.) Get the pids of running apps. Either use the ActivityManager or parse a ps console output.
2.) iterate through /proc/$pid/net/status files and get the matching uid for a pid.
cat /proc/*pid*/net/status | grep Uid:
3.) Call and parse the output of tcp, tcp6,udp, udp6 files to match ports and uids:
cat /proc/net/tcp
...
4.) match the uids of both matchings, get a port-to-pid map without su access.
Cheers,
goethe

Simultaneous pipe to grep and redirect to stdout

In Linux bash, I am trying to run a command and grep for an argument:
command | grep
However, I need to redirect the result of the commad to the stdout and simultaneously pipe it to grep (I need to see both the grep result and the command result in stdout).
I googled a bit and tried some variations, such as:
command | tee /dev/tty | grep
But, no luck.
I don't want to use sth like
command
command | grep
as it is ugly :)
Thanks,
Try
command | tee >(grep whatever)
Note that there's no space between these two symbols: >(.

How to get linux process id alone using perl

When i execute the below command in command prompt it works fine. but when i include the same in perl script, it shows the whole process name.
ps -ef | grep truecontrol | awk '{print$2}'
returns
4567
3456
When I execute it throught perl, it shows the whole process details. I want to assign it to a variable array and work on it. Let me know how to do it?
my $process_chk_command = `ps -ef | grep truecontrol | awk '{print$2}'`;
print($process_chk_command);
root 9902 9890 0 05:50 ? 00:00:03 /opt/abc/jre/bin/java -DTCFTP=1 -d64 -Xms16m -Xmx64m -Djava.library.path=/opt/abc/server/ext/wrapper/lib -cla
perl's backticks and qx// interpolate variables, so when you write:
my $process_chk_command = `ps -ef | grep truecontrol | awk '{print $2}'`;
perl interpolates the special variable $2. In your case, $2 is not set, and thus expands to the empty string, so the awk command is simply {print}.
You could escape the dollar sign (`ps ... | awk '{print \$2}'`) to avoid this.
(As an aside, I'd recommend grep [t]ruecontrol to prevent grep from matching its own process table entry, or that of its parent shell which constructs the pipeline. sh aficionados with a POSIX bent might additionally suggest `ps -eo pid,comm,args | awk '/[t]ruecontrol/{print \$1}'`.)
Try using pgrep
my $process_chk_command = `pgrep truecontrol`;
my $process_chk_command = `ps -ef | grep truecontrol`;
my (undef,$pid) = split(' ', $process_chk_command, -1);
ps, there's a perl utility that converts awk scripts to perl: a2p
True to Perl's motto, another way:
my $pcc=`killall -s truecontrol`;
my (undef,undef,$pid)=split(' ',$pcc);
print $pid;

perl - one liner to loop through and kill pids

How do I execute the kill -9 in this perl one liner? I have gotten down to where I have the pids listed and can print it out to a file, like so:
ps -ef | grep -v grep |grep /back/mysql | perl -lane '{print "kill -9 $F[1]"}'
Have you considered pkill or pgrep?
pkill /back/mysql
or
pgrep /back/mysql | xargs kill -9
OK, heavily edited from my original answer.
First, the straightforward answer:
ps -ef | grep -v grep |grep /back/mysql | perl -lane 'kill 9, $F[1]'
Done.
But grep | grep | perl is kind of a silly way to do that. My initial reaction is "Why do you need Perl?" I would normally do it with awk | kill, saving Perl for more complicated problems that justify the extra typing:
ps -ef | awk '/\/back\/mysql/ {print $2}' | xargs kill -9
(Note that the awk won't find itself because the string "\/back\/mysql" doesn't match the pattern /\/back\/mysql/)
You can of course use Perl in place of awk:
ps -ef | perl -lane 'print $F[1] if /\/back\/mysql/' | xargs kill -9
(I deliberately used leaning toothpicks instead of a different delimiter so the process wouldn't find itself, as in the awk case.)
The question then switches from "Why do you need perl?" to "Why do you need grep/awk/kill?":
ps -ef | perl -lane 'kill 9, $F[1] if /\/back\/mysql/'
Let's use a more appropriate ps command, for starters.
ps -e -o pid,cmd --no-headers |
perl -lane'kill(KILL => $F[0]) if $F[1] eq "/back/mysql";'
ps -ef | grep -v grep |grep /back/mysql | perl -lane 'kill(9, $F[1])'
The kill function is available in Perl.
You could omit the two grep commands too:
ps -ef | perl -lane 'kill(9, $F[1]) if m%/back/mysql\b%'
(untested)
Why aren't you using even more Perl?
ps -ef | perl -ane 'kill 9,$F[1] if m{/back/mysql}'