Finding process count in Linux via command line
On systems that have pgrep
available, the -c
option returns a count of the number of processes that match the given name
pgrep -c command_name
Note that this is a grep
-style match, not an exact match, so e.g. pgrep sh
will also match bash
processes. If you want an exact match, also use the -x
option.
If pgrep
is not available, you can use ps
and wc
.
ps -C command_name --no-headers | wc -l
The -C
option to ps
takes command_name
as an argument, and the program prints a table of information about processes whose executable name matches the given command name. This is an exact match, not grep
-style. The --no-headers
option suppresses the headers of the table, which are normally printed as the first line. With --no-headers
, you get one line per process matched. Then wc -l
counts and prints the number of lines in its input.
Counting open files per process
Have a look at the /proc/
file system:
ls /proc/$pid/fd/ | wc -l
To do this for all processes, use this:
cd /proc
for pid in [0-9]*
do
echo "PID = $pid with $(ls /proc/$pid/fd/ | wc -l) file descriptors"
done
As a one-liner (filter by appending | grep -v "0 FDs"
):
for pid in /proc/[0-9]*; do printf "PID %6d has %4d FDs\n" $(basename $pid) $(ls $pid/fd | wc -l); done
As a one-liner including the command name, sorted by file descriptor count in descending order (limit the results by appending | head -10
):
for pid in /proc/[0-9]*; do p=$(basename $pid); printf "%4d FDs for PID %6d; command=%s\n" $(ls $pid/fd | wc -l) $p "$(ps -p $p -o comm=)"; done | sort -nr
Credit to @Boban for this addendum:
You can pipe the output of the script above into the following script to see the ten processes (and their names) which have the most file descriptors open:
...
done | sort -rn -k5 | head | while read -r _ _ pid _ fdcount _
do
command=$(ps -o cmd -p "$pid" -hc)
printf "pid = %5d with %4d fds: %s\n" "$pid" "$fdcount" "$command"
done
Here's another approach to list the top-ten processes with the most open fds, probably less readable, so I don't put it in front:
find /proc -maxdepth 1 -type d -name '[0-9]*' \
-exec bash -c "ls {}/fd/ | wc -l | tr '\n' ' '" \; \
-printf "fds (PID = %P), command: " \
-exec bash -c "tr '\0' ' ' < {}/cmdline" \; \
-exec echo \; | sort -rn | head
Count the number of processes and kill them
For maximum portability and reliability, use -A
(POSIX synonym of -e
) and a custom format with -o
rather than -f
.
Your filtering of the output of ps
is brittle: it may match other processes. You've had to exclude the grep process, and you may need to exclude your script as well, and there may be other completely innocent processes caught in the fray (such as your script itself) because their command line happens to contain $process
as a substring. Make your filtering as strict as possible. With ps -o pid= -o comm=
, you get just two columns (PID and command without arguments) with no header.
You don't need to use a loop to do the killing, kill
accepts multiple arguments. For the counting, let the shell do it: you have a whitespace-separated list of numbers, to let the shell do the word splitting (with $(…)
outside quotes) and count the number of resulting words ($#
).
count_and_kill_processes () {
set -- $(ps -A -o pid= -o comm= |
awk -v "name=$process" '$2 == name {print $1}')
count=$#
if [ $# -ne 0 ]; then kill "$@"; fi
}
count_and_kill_processes foo
# now the number of killed processes is in $count
If your shell is bash or ksh on all machines, you can use an array.
pids=($(ps -A -o pid= -o comm= |
awk -v "name=$process" '$2 == name {print $1}') )
if [[ $# -ne 0 ]]; then kill "$@"; fi
# the number of killed processes is ${#pids}
How does my Linux C process know how many files were opened on the command line?
There is no way to distinguish between redirections established on the command line and redirections which were already present in the execution environment.
For example, when utility util
runs in the script
exec 4<file4
# ...
util 3<file3
it will see both fd 3 and fd 4 open for reading; it can't tell that only one was opened on the command line. If you care about that, which you probably should because there can be a number of these.
That aside, you can certainly figure out which fds are currently open, for example by cycling through all of them or examining the /proc/self/fd
pseudo-directory. See this question for some example solutions to finding all the open file descriptors under Linux.
Is there a programmatic way in C to determine the number of processes ever used in a group of processes under Linux?
To enforce the RLIMIT_NPROC
limit, linux kernel reads &p->real_cred->user->processes
field in copy_process
function (on fork()
for example)
http://lxr.free-electrons.com/source/kernel/fork.c?v=4.8#L1371
1371 if (atomic_read(&p->real_cred->user->processes) >=
1372 task_rlimit(p, RLIMIT_NPROC)) {
or in sys_execve
(do_execveat_common
in fs/exec.c):
1504 if ((current->flags & PF_NPROC_EXCEEDED) &&
1505 atomic_read(¤t_user()->processes) > rlimit(RLIMIT_NPROC)) {
1506 retval = -EAGAIN;
1507 goto out_ret;
So, if the processes
is larger than RLIMIT_NPROC, function will fail. This field is defined as part of struct user_struct
(accessed with struct cred
real_cred in sched.h as
atomic_t processes; /* How many processes does this user have? */
So the process count accounting is per-user.
There is decrement of the field in copy_process in case of fail:
1655 bad_fork_cleanup_count:
1656 atomic_dec(&p->cred->user->processes);
And increment of the field is in copy_cred
: http://code.metager.de/source/xref/linux/stable/kernel/cred.c#313
313 /*
314 * Copy credentials for the new process created by fork()
315 *
316 * We share if we can, but under some circumstances we have to generate a new
317 * set.
318 *
319 * The new process gets the current process's subjective credentials as its
320 * objective and subjective credentials
321 */
322 int copy_creds(struct task_struct *p, unsigned long clone_flags)
339 atomic_inc(&p->cred->user->processes);
372 atomic_inc(&new->user->processes);
man page says that it is per-user limit: http://man7.org/linux/man-pages/man2/setrlimit.2.html
RLIMIT_NPROC
The maximum number of processes (or, more precisely on Linux,
threads) that can be created for the real user ID of the
calling process. Upon encountering this limit, fork(2) fails
with the error EAGAIN.
Related Topics
Differencebetween './Example.Sh' and 'Sh Example.Sh'
How to Look Up a Variable by Name with #!/Bin/Sh (Posix Sh)
Using Find - Deleting All Files/Directories (In Linux ) Except Any One
Using Assertion in the Linux Kernel
How to Determine If Code Is Running in Signal-Handler Context
How to Get the First Column of Comm Output
Bluetoothctl to Hcitool Equivalent Commands
Bash: Add String to the End of the File Without Line Break
How to Control Backlight by Terminal Command
Understanding Bash Short-Circuiting
Dummy Questions About Setting Up Git on Amazon Cloud Ec2
Why Does This Code Crash with Address Randomization On
Xdotool Commands Bound to Key Shortcuts Doesnot Work
In Order to Write Pci Ethernet Driver. How to Implement Mmap in the Pci Ethernet Driver
Should Linux Cron Jobs Be Specified with an "&" to Indicate to Run in Background
Execute Sudo Command on Linux from Plink.Exe on Windows
What Is a Good Way to Dump a Linux Core File from Inside a Process