'How to extract certain argruements from the system command "ps"?

I am working on a server and client program. I run ./server 8080 to specify the port from the command line. In my client program I wrote system("ps -aux | grep -w server | grep -v grep");. It does show PID:197435 0.0 0.0 4360 908 pts/1 S+ 19:34 0:00 ./server 8080. How would I go about formatting my grep to only show the port 8080?

sh


Solution 1:[1]

Instead of parsing the output of ps, you could just read the command and arguments from /proc/<pid>/cmdline. Here the arguments are null-delimited, so you will need to convert nulls to spaces.

Assuming I had nc -l localhost 8080 running as pid 3279374, that would look like this:

$ tr '\0' ' ' < /proc/3279374/cmdline
nc -l localhost 8080

You can also ask ps to display just the information you want:

$ ps -p 3279374 -o args=
nc -l localhost 8080

Solution 2:[2]

You could use either:

ps ax -o args | awk '$(NF-1) ~ /(^|\/)server$/ && $NF~/^[0-9]{4}$/ {print $NF}'

Like grep -w, except match server in the second last argument specifically*.

ps ax -o args | grep -w 'serve[r]' | awk '$NF ~ /^[0-9]{4}$/ {print $NF}'

Using grep -w as you were - but this can match server as any argument of any running process.

  • ps ax -o args is like ps aux, but prints only one column - the command and arguments.
  • *The first example matches server in the second last field, because for example if server is a script, the interpreter will be the first field, and the script server (or /path/to/server) the second (even if server is executable, and you invoked it directly).
  • eg. It may look like /usr/bin/python3 ./server 8080 if server is a python script.
  • If server has other arguments, you can change the field numbers to match.
  • grep -w 'serve[r]' avoids matching grep itself.
  • ps ax -o args | awk '/(^|[^[:alnum:]_])server($|[[:alnum:]_])/ && $NF~/^[0-9]{4}$/ {print $NF}' is equivalent to the second example, using awk only.
  • Not every unix like OS implements procfs (eg Mac, OpenBSD). But ps is POSIX (and the only question tag is sh).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 larsks
Solution 2 dan