How do I count specific processes on Mac OS X? - macos

Using a Mac, what would be the best way to count the number of instances of a particular process I am running? This is for a script I am writing to find the number of ffmpeg processes running on my machine.
Should I be using top here? ps aux|grep ffmpeg? What would be the best way to get the number?

grep -c will count occurrences:
count=`ps aux | grep -v "grep" | grep -c ffmpeg`
echo $count

ps aux | grep ffmpeg | wc -l will get you the number of processes that mention the phrase 'ffmpeg' you'll need to minus 1 on this value as ps aux | grep ffmpg is a process also.

You're looking for the program called "wc" -- "wc -l" will count lines for you.
"man wc" for details.

You can try the killall command on the Mac:
$ killall -s ffmpg
kill -TERM 20148
kill -TERM 20146
kill -TERM 20140
The -s means just list what you'd do, but don't actually kill any processes. Pipe it to wc, and you should get your result:
$ killall -s ffmpg | wc -l
3
In a shell script, you can do something like this:
num_of_processes=$(killall -s ffmpg | wc -l)

pgrep:
$ pgrep -c ffmpeg
If you don't use pgrep then mere grep might produce false positives.
To avoid it you could try -C option:
$ ps -C ffmpeg -o pid= | wc -l
Check that your ps version interprets it correctly.

Related

pgrep process count show extra count

I've a scirpt name server.sh
#!/bin/bash
process_count=$(ps aux | grep server.sh | grep -v grep | wc -l )
echo "total process running:"
echo $process_count
... other script code
when I run script I get output as
./server.sh
total process running:
2
Why do I get process count as 2 instead of 1? I only have one script running and have also excluded grep process.
Even using pgrep -f server.sh and excluding pgrep gives 2 as process count.
My approach is to redirect the output of ps into a temp file, then grep that file. That will eliminate extra processes.
ps aux > /tmp/ps.txt
process_count=$(grep server.sh /tmp/ps.txt | wc -l)
rm /tmp/ps.txt

Killing a running sh script using pid

I have made an Auto Clicker and was wondering how i would kill it using
kill [pid]
My auto Clicker works like this:
while true [1]; do
xdotool click --repeat 10000 --delay 150 1
done
code I have used to try and terminate running proccess:
ps -ef | grep AutoClicker | grep -v grep | xargs kill -9
I found this code on another post, however i have had no luck with it.
pkill -f AutoClicker or kill $(pgrep -f AutoClicker)
If you run your code:
ps -ef | grep AutoClicker | grep -v grep | xargs kill -9
you should get an error message from kill.
kill expects a list of process ids not usernames, times, and random strings.
You need to filter out everything except the pids with something like:
ps -ef | grep AutoClicker | grep -v grep | awk '{print $2}' | xargs kill
Instead of searching for the process ID, use your own "PID file". I'll demonstrate with sleep in place of xdotool.
echo $$ > /tmp/my.pid
while true [1]; do
echo "clicking"
sleep 5
done
# rm -f /tmp/my.pid
I can run this script in another terminal window or the background. The important thing is that /tmp/my.pid contains the process ID of this running script. You can stop it with:
kill $(</tmp/my.pid)
This interrupts the while-loop. Need to figure out how to remove the PID file...

How to kill a process with 'kill' combined with 'grep'

I'd like to kill a process/script with a simple command using. At the moment I do the following
ps -ef | grep myscriptname
kill 123456
But is there a way to maybe combine the 2 command together so I don't need to look and manually write the pid, something like this kill grep myscriptname?
You want pkill:
pkill myscriptname
On some systems there is a similar tool called killall, but be careful because on Solaris it really does kill everything!
Note that there is also pgrep which you can use to replace your ps | grep pipeline:
pgrep myscriptname
It prints the PID for you, and nothing else.
Another alternative is using the pidof command:
kill $(pidof processname)
you can try this simple trick
pkill -f "my_sript_filename"
I use kill $(pgrep <program name>), it works.
Another alternative, pgrep with xargs
ps aux | pgrep gitlab | xargs kill
An alternative is piping to the xargs command:
ps -ef | grep myscriptname | xargs kill
http://man7.org/linux/man-pages/man1/xargs.1.html

How to access the PID from an lsof.

Given the following command lsof -i:1025 I get:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ruby 12345 john 11u IPv4 0xb2f4161230e18fd57 0t0 TCP localhost:foobar (LISTEN)
I am trying to write a script to get that PID (12345) and kill it. At the moment I have to run lsof -i:1025, get that PID and then run kill -9 12345.
The lsof(8) man page says:
-t specifies that lsof should produce terse output with process
identifiers only and no header - e.g., so that the output
may be piped to kill(1). -t selects the -w option.
You can use lsof -t -i:1025 | xargs kill -9.
Something like:
#!/bin/bash --
x=`lsof -Fp -i:1025`
kill -9 ${x##p}
Should do it. The 3rd line runs lsof using the -F option to get just the pid, with a leading p. The next line drops the leading p from the output of lsof and uses the result as the pid in a kill command.
Edit: At some point lsof was modified so the file descriptor preceded by an f is always output, whether you ask for it or not (which makes no sense to me, but what do I know). While you could put a | grep '^p' in the back quotes, an easier way is to use the -t option, as noted in fabianopinto's answer below.
man lsof says that you can use -F to specify fields to to be output for processing by other programs. So you can do something like
lsof -i:1025 -Fp | sed 's/^p//' | xargs kill -9
Further to #blm's answer, it didn't work for me exactly because the output of the lsof command was:
p4679
f33
So with the ${x##p} was
4679
f33
The solution
Grab only the first line with | head -n 1:
x=`lsof -Fp -i:"$1" | head -n 1`
kill -9 ${x##p}
And furthermore from #blm's and #Mosh Feu's answers:
lsof -i:1337 -Fp | head -n 1 | sed 's/^p//' | xargs kill
is what ended up doing the trick for me.
I recommend adding this as a bash function and aliasing it
alias kbp='killByPort'
killByPort() {
lsof -i:$1 -Fp | head -n 1 | sed 's/^p//' | xargs kill
}
This shortcut will kill the process quickly for you
kill -9 $(lsof -t -i :3000)
for fish shell users, simply remove the $ sign, so
kill -9 (lsof -t -i :3000)

Finding number of child processes

How do find the number of child processes of a bash script, from within the script itself?
To obtain the PID of the bash script you can use variable $$.
Then, to obtain its children, you can run:
bash_pid=$$
children=`ps -eo ppid | grep -w $bash_pid`
ps will return the list of parent PIDs. Then grep filters all the processes not related to the bash script's children. In order to get the number of children you can do:
num_children=`echo $children | wc -w`
Actually the number you will get will be off by 1, since ps will be a child of the bash script too. If you do not want to count the execution of ps as a child, then you can just fix that with:
let num_children=num_children-1
UPDATE: In order to avoid calling grep, the following syntax might be used (if supported by the installed version of ps):
num_children=`ps --no-headers -o pid --ppid=$$ | wc -w`
I prefer:
num_children=$(pgrep -c -P$$)
It spawns just one process, you do not have to count words or adjust the numbers of PIDs by the programs in the pipe.
Example:
~ $ echo $(pgrep -c -P$$)
0
~ $ sleep 20 &
[1] 26114
~ $ echo $(pgrep -c -P$$)
1
You can also use pgrep:
child_count=$(($(pgrep --parent $$ | wc -l) - 1))
Use pgrep --parent $$ to get a list of the children of the bash process.
Then use wc -l on the output to get the number of lines: $(pgrep --parent $$ | wc -l)
Then subtract 1 (wc -l reports 1 even when pgrep --parent $$ is empty)
If job count (instead of pid count) is enough I just came with a bash-only version:
job_list=($(jobs -p))
job_count=${#job_list[#]}
Use ps with the --ppid option to select children of the current bash process.
bash_pid=$$
child_count=$(ps -o pid= --ppid $bash_id | wc -l)
let child_count-=1 # If you don't want to count the subshell that computed the answer
(Note: this requires the Linux version of ps for --ppid. I don't know if there is an equivalent for BSD ps or not.)
You may evaluate the shell builtin command jobs like:
counter = `jobs | wc -l`

Resources