1

I have some processes that I am running both locally and within docker containers on the same host. Since I run multiple processes with the same name, I would like to make an alias/function that would allow me to kill all of them that are running on the host, but ignore the ones that are running in docker.

The command that I am using now has this form:

kill $(ps aux | grep 'process_name' | awk '{print $2}')

I noticed that this command kills the processes with the same name in all of the running containers which makes them crash. How can I prevent this?

This is how the process on the host machine looks like (as a result of ps aux):

hamzam   9109  0.9  0.0 510912 24732 ?        Ssl  14:21   0:00 python /opt/scripts/ex_script __name:=process_name __log:=/home/hamzam/.logs/0286c734-71fd-11e7-9dc4-901b0ed728a7/process_name-3.log

And this is the process which is run in one of the containers:

hamzam  12168  2.3  0.0 472708 64312 ?        Ssl  14:22   0:00 python /opt/scripts/ex_script __name:=process_name __log:=/home/logs/0/126e36dc-71fd-11e7-bd98-0242ac110003/process_name-3.log
  • Please edit your question and include an example of the relevant lines from the output of ps aux. Show at least one you would want to kill and one you would want to keep. Also, as a general rule, you don't use ps | grep for this sort of thing. That's what pkill is for. – terdon Jul 26 '17 at 12:14
  • @terdon Thanks! I have added the examples now. – hamzam Jul 26 '17 at 12:31
  • As you can see, they look identical so this won't be possible with ps aux. You will need to use the parent PID, probably. Could you show us the output of pstree $pid where $pid is the PID of each of the two (host and container) python processes? – terdon Jul 26 '17 at 12:33
  • They are the same \python───5*[{python}]. Also, I don't get the same results when I do ps aux and pkill. When I do pkill 'process_name' nothing happens actually, only when I do pkill python, but I don't want to kill all the python processes. EDIT: pkill -f works. Sorry for so many edits! – hamzam Jul 26 '17 at 12:41
  • pkill has --ns pid and --nslist name... options which you can use to limit the slaughter to a specific namespace. e.g. using pkill with --ns $$ from sh/bash/etc should kill only matching processes in the same namespace as your shell (all your docker containers will be in different namespaces). – cas Jul 27 '17 at 5:54
1

pkill has --ns pid and --nslist name... options which can be used to restrict which namespaces the kill will affect.

The --ns pid combines well with the bash built-in variable $$, which is equal to the current shell's PID.

For example, on one of my systems, I run an instance of gitlab in docker, and one of the services it runs in that container is redis:

# ps u -C redis-server
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
997      30006  0.1  0.0  35504  2896 ?        Ssl  16:05   0:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0

Note the PID, 30006.

If I use pkill's -ns $$ option, then it won't be kill because it's in a different namespace to my shell. Note how the PID has not changed - this indicates that it has not been killed and restarted.

# pkill --ns $$ redis-server
# ps u -C redis-server
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
997      30006  0.1  0.0  35504  2896 ?        Ssl  16:05   0:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0

If i don't use that option, then (unsurprisingly) it will be killed.

# pkill redis-server
# ps u -C redis-server
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
997        459  0.5  0.0  35504  2896 ?        Ssl  16:11   0:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0

The PID of redis-server is now 459. It has been killed and restarted.

BTW, pgrep supports the same options, so it's easy to get a list of other processes in the same namespaces. e.g. pgrep -a --ns 459 shows me all processes running in the same namespace as the redis-server above.


ps also has various output format options for displaying namespace details. For example:

# ps -o pidns,pid,cmd -C redis-server
     PIDNS   PID CMD
4026532661   459 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0

From man ps:

pidns PIDNS

Unique inode number describing the namespace the process belongs to. See namespaces(7).

  • Thank you. This gave me more than enough information to make it work. For some reason, most likely since I am running the command from a script using popen, pkill does not do anything. So instead, I simply used kill -9 $(pgrep ...) with pgrep args that filters the namespace of $$. – hamzam Jul 28 '17 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.