How to test if a process is running with grep in bash? - linux

I have the command:
ps ax | grep my_application
Which outputs a large string including the port of the proccesses involved in my_application.
If my_application is not running it outputs:
3873 pts/0 S+ 0:00 grep my_application
I need a condition to test the output of ps ax | grep my_application and do exit 2in case my_application is still running.
Any ideas?

You can add brackets to exclude the grep process:
ps ax | grep -q '[m]y_application' && exit 2
If my_application is running, ps ax will print my_application along with the grep command and pattern. Grep understands [m] as a character class, but it will not match the litteral string '[m]' printed by ps ax, so the grep process is excluded.

The simplest solution is to use pgrep, if it is available on your system.
Otherwise, you can customize the way ps reports processes. You don't have to use the default format, which includes (some) command-line arguments.
For example:
ps ax -ocomm
will only output the executable name. If you want pids as well,
ps ax -opid,comm
For convenient grepping, you might want to remove the headers
ps ax -opid=,comm=
Any of those should work just fine as input to grep application_name, although you still need to watch out for application_name being a substring of another application name.
man ps should give you the list of possible output fields. There are lots of them.

You can exclude stuff from the results returned by grep by using something like this:
ps ax | grep my_application | grep -v grep
This excludes the process that is returning when your application is not running that shows the grep running. When this is run and your application is not running, it will return nothing. Check for the empty string, and exit that way.

Related

Linux ps aux with grep check for specific PHP process ID

I'm trying to figure out whether a PHP process is running or not using the ps aux command and passing grep to it, for instance:
I need it to return and tell me whether a process ID on php is running or not but whenever I try the following I always seem to get a result where the result is appending 1234 at the end, what am I missing?
ps aux | grep 'php|1234'
Suggesting pgrep command instead of ps aux
pgrep -af "php"
The reason your get always one line:
php process is not matched with grep 'php|123123123'
ps aux list the grep command you submitted and the grep command match itself
maybe you meant grep -E 'php|123123123' to match php or 123123123
The solution I've come across thanks to a user above is to do:
ps aux | grep '123456' | grep 'grep' -v
Where 123456 would be the process ID

Getting User from processid when multiple user processes exist

I'm trying to tweak a bash script to pull back PID's of the individual application accounts when there are multiple applications running as a masterId. This used to run under individual user accounts, but recent changes have forced the applications to all run under a combined "masterId", but still maintain a unique application Id that I can grep against.
Normally
pgrep -u "appId"
would give me a single PID. Now I have to run:
pgrep -u "masterId"
it returns all of the PID's (each one is it's own application).
1234
2345
3456
I'm trying to come up with a command to bring me back just the PID of the appAccount(n) so I can pipe it into other useful commands. I can do a double grep (which is closer to what I want):
ps aux | grep -i "masterId" | grep -i "appAccount(n)"
and that will get me the entire single process information, but I just want the PID to do something like:
ps aux | grep -i "masterId" | grep -i "appAccount(n)" | xargs sudo -u appAccount(n) kill -9
How do I modify the initial above command to get just the PID? Is there a better way to do this?
pgrep --euid "masterId" --list-full | awk '/appAccount(n)/ {print $1}'
Output the full process command line, then select the one with the desired account and print the first field (pid).

Get pid of last started instance of a certain process

I have several instances of a certain process running and I want to determine the process id of the one that has been started last.
So far I came to this code:
ps -aef | grep myProcess | grep -v grep | awk -F" " '{print $2}' |
while read line; do
echo $line
done
This gets me all process ids of myProcess. Somehow I need to compare now the running times of this pids and find out the one with the smallest running time. But I don't know how to do that...
An easier way would be to use pgrep with its -n, --newest switch.
Select only the newest (most recently started) of the matching
processes.
Alternatively, if you don't want to use pgrep, you can use ps and sort by start time:
ps -ef kbsdstart
Use pgrep. It has a -n (newest) option for that. So just try
pgrep -n myProcess

Linux / Bash, using ps -o to get process by specific name?

I am trying to use the ps -o command to get just specific info about processes matching a certain name. However, I am having some issues on this, when I try to use this even to just get all processes, like so, it just returns a subset of what a normal ps -ef would return (it doesn't return nearly the same number of results so its not returning all running processes)
ps -ef -o pid,time,comm
I want to try something like this (below) but incorporate the ps -o to just get specific info from it (just the PID)
ps -ef |grep `whoami`| grep firefox-bin
Any advice is appreciated as to how to do this properly, thanks
This will get you the PID of a process by name:
pidof name
Which you can then plug back in to ps for more detail:
ps -p $(pidof name)
This is a bit old, but I guess what you want is: ps -o pid -C PROCESS_NAME, for example:
ps -o pid -C bash
EDIT: Dependening on the sort of output you expect, pgrep would be more elegant. This, in my knowledge, is Linux specific and result in similar output as above. For example:
pgrep bash
ps -fC PROCESSNAME
ps and grep is a dangerous combination -- grep tries to match everything on each line (thus the all too common: grep -v grep hack). ps -C doesn't use grep, it uses the process table for an exact match. Thus, you'll get an accurate list with: ps -fC sh rather finding every process with sh somewhere on the line.
Sometimes you need to grep the process by name - in that case:
ps aux | grep simple-scan
Example output:
simple-scan 1090 0.0 0.1 4248 1432 ? S Jun11 0:00
Sorry, much late to the party, but I'll add here that if you wanted to capture processes with names identical to your search string, you could do
pgrep -x PROCESS_NAME
-x Require an exact match of the process name, or argument list if -f is given.
The default is to match any substring.
This is extremely useful if your original process created child processes (possibly zombie when you query) which prefix the original process' name in their own name and you are trying to exclude them from your results. There are many UNIX daemons which do this. My go-to example is ninja-dev-sync.

linux shell scripting kiddie's question

an Unix shell script with only purpose - count the number of running processes of qmail (could be anything else). Easy thing, but there must be some bug in code:
#!/bin/bash
rows=`ps aux | grep qmail | wc -l`
echo $rows
Because
echo $rows
always shows greater number of rows (11) than if I just count rows in
ps aux | grep qmail
There are just 8 rows. Does it work this way on your system too?
Nowadays with linux, there is pgrep. If you have it on your system, you can skip grep -v grep
$ var=$(pgrep bash) # or `pgrep bash | wc -l`
$ echo $var
2110 2127 2144 2161 2178 2195 2212 2229
$ set -- $var; echo ${#}
8
also, if your ps command has -C option, another way
$ ps -C bash -o pid= | wc -l
if not, you can set a character class in your grep pattern
$ ps aux|grep [q]mail | wc -l
It appears that you're counting the grep process itself and the header line that ps normally prints before its output.
I'd suggest something more like:
qprocs=$(ps auxwww | grep -c "[q]mail")
... note that GNU grep has a "-c" switch to have it print a "count" of matches rather than the lines themselves. The trick with the regular expression here is to match qmail without matching the literal string that's on the grep command line. So we take any single character in the string and wrap it in square brackets such that it is a single character "class." The regexp: [q]mail matches the string qmail without matching the string [q]mail.
Note that even with this regex you may still find some false positive matches. If you really want to be more precise then you should supply a custom output format string to your ps command (see the man pages) or you should feed it through a pipemill or you should parse the output of the ps command based on fields (using awk or cut or a while read loop). (The -o option to ps is by far the easiest among these).
No, since I'm not running qmail. However, you will want to, at a bare minimum, exclude the process running your grep:
ps aux | grep qmail | grep -v grep
For debugging, you may want to do:
rows=`ps aux | grep qmail`
echo $rows >debug.input
od -xcb debug.input
(to see your input to the script in great detail) and then rewrite your script temporarily as:
#!/bin/bash
rows=`cat debug.input | wc -l`
echo $rows
That way, you can see the input and figure out what effect it's having on your code, even as you debug it.
A good debugger will eventually learn to only change one variable at a time. If your changing your code to get it working, that's the variable - don't let the input to your code change as well.
Use
$ /sbin/pidof qmail
A few ways...
ps -e | grep ' [q]mail' | wc -l
ps -C qmail -opid= | wc -l
pidof qmail | tr ' ' '\n' | wc -l
pgrep is on many Linux distributions, and I imagine available for other Unices.
[dan#khorium ~]$ whatis pgrep
pgrep (1) - look up or signal processes based on name and other attributes
[dan#khorium ~]$ pgrep mingetty
1920
1921
1922
1923
1924
In your case, pgrep qmail | wc -l should do the trick.

Resources