System Administration
cancel
Showing results for 
Search instead for 
Did you mean: 

pkill not working as expected

 
ITLOUIS
Occasional Contributor

pkill not working as expected

I am trying to use pkill to kill a process that contains bea.home within the command line. I only need the default SIGTERM. The command is: "pkill -u oracle -f bea.home". The pgrep command "pgrep -u oracle -f bea.home" works and shows the process id.  When I run the pkill command the process is not killed and I get a return code of 1 (process not found). Is this a bug? I can kill the process in other ways using a ps, awk and xargs but pkill looked like a better method if it would only work. From what I can see pkill is new to HPUX and first appears in 11.31.

 

 

P.S. This thread has been moved from General to HP-UX > System Admin. - Hp forum Moderator

 

7 REPLIES
Dennis Handly
Acclaimed Contributor

Re: pkill not working as expected

>"pgrep -u oracle -f bea.home" works and shows the process id.  When I run the pkill command the process is not killed

 

Are you sure that process didn't just die?

What does "kill -0 pid-from-pgrep" show for that PID?

Bill Hassell
Honored Contributor

Re: pkill not working as expected

pgrep and pkil suffer from similar issues associated with ps | grep. I am really surprised that all the effort to create these commands did not include the exact process name (which ps does have). The -C option in ps is the only reliable way to select a program by name. Rather than use grep (which matches indiscriminately), the -C option looks at the process table name for an exact match. However -C (and also useful, -H and -o) is only valid when the environment variable UNIX95 is defined. The value is unimportant (can be null), it just must exist. But don't set the variable globally. UNIX95 affects other processes. Instead, define the variable just for the ps process.

 

Here is the typical ps|grep and the exact match ps -C results while searching for all "sh" processes:

 

# ps -ef|grep sh
root        37     0  0  Jul  8  ?        00:00:00 nfs_global_flush
root        62     0  0  Jul  8  ?        00:00:00 shutdowndaemon
root         4     0  0  Jul  8  ?        00:00:27 unhashdaemon
root        86     0  0  Jul  8  ?        00:00:00 str_mblk_flush_daemon
root      3809     1  0  Jul  8  ?        00:00:00 /opt/ssh/sbin/sshd
root     10488 10486  0 20:12:18 pts/2    00:00:00 sh
root     10418  3809  0 20:11:59 ?        00:00:00 sshd: root@pts/2
root     10494  6360  0 20:12:24 pts/0    00:00:00 grep sh
root      6357  3809  0 18:44:37 ?        00:00:00 sshd: root@pts/0
root     10121 10118  0 20:05:07 pts/1    00:00:00 -sh
root     10486 10421  0 20:12:10 pts/2    00:00:00 csh
root      6360  6357  0 18:44:39 pts/0    00:00:00 -sh
root     10421 10418  0 20:12:00 pts/2    00:00:00 -sh
blh      10320 10121  0 20:11:01 pts/1    00:00:00 -sh
root     10118  3809  0 20:05:06 ?        00:00:00 sshd: root@pts/1
blh      10382 10320  0 20:11:08 pts/1    00:00:00 ksh

# UNIX95=1 ps -f -C sh
UID        PID  PPID  C    STIME TTY          TIME CMD
root     10488 10486  0 20:12:18 pts/2    00:00:00 sh
root     10121 10118  0 20:05:07 pts/1    00:00:00 -sh
root      6360  6357  0 18:44:39 pts/0    00:00:00 -sh
root     10421 10418  0 20:12:00 pts/2    00:00:00 -sh
blh      10320 10121  0 20:11:01 pts/1    00:00:00 -sh

As you can see, grep matches lots of "sh" parts of each process line -- and that's very bad, especially when you need to kill specific processes by name.

 

Another thing I see a lot is grep used to find processes when ps already has an exact match option:

 

grep pid - not needed, use ps -p

grep uid - not needed, use ps -u

 

You can look for multiple pid or uid values - just use commas as in:  ps -u sybase,oracle

 

In your example, you can find the processes by exact name match and then grep for the command line strings.



Bill Hassell, sysadmin
Dennis Handly
Acclaimed Contributor

Re: pkill not working as expected

>pgrep and pkill suffer from similar issues associated with ps | grep.

 

Not hardly, they have the flexibility to do either.  It is the user that intentionally used -f to match anywhere in the command line.

 

>did not include the exact process name (which ps does have).

 

You just have to understand EREs, regexp(5):

pgrep "^init$" to just find init.

 

How to see what pgrep finds:

$ ps -f -p $(pgrep init | tr "^J" ",")
UID        PID  PPID  C    STIME TTY          TIME CMD
root        61     0  0  Apr  8  ?        00:00:00 mdep_initiator_thread
root        65     0  0  Apr  8  ?        00:00:00 pagetable_init_daemon
root         1     0  0  Apr  8  ?        00:00:06 init

(That ^J is formed by Control-V then Control-J or ENTER.)

Bill Hassell
Honored Contributor

Re: pkill not working as expected

The example:

 

$ ps -f -p $(pgrep init | tr "^J" ",")
UID        PID  PPID  C    STIME TTY          TIME CMD
root        61     0  0  Apr  8  ?        00:00:00 mdep_initiator_thread
root        65     0  0  Apr  8  ?        00:00:00 pagetable_init_daemon
root         1     0  0  Apr  8  ?        00:00:06 init

demonstrates the problem. The result is no different than ps -ef | grep init -- unwanted processes are found.
egrep does not disciminate the basename of a process when pathnames such as /usr/bin/sh or ./bin/sh are used:

 

# ps -f -p$(pgrep sh | tr "^J" ",")
UID PID PPID C STIME TTY TIME CMD root 62 0 0 Jul 8 ? 00:00:00 shutdowndaemon root 4 0 0 Jul 8 ? 00:00:27 unhashdaemon root 86 0 0 Jul 8 ? 00:00:00 str_mblk_flush_daemon root 3809 1 0 Jul 8 ? 00:00:00 /opt/ssh/sbin/sshd root 16388 16323 0 08:48:01 pts/1 00:00:00 sh root 16617 16391 0 08:52:48 pts/1 00:00:00 /usr/bin/sh root 16252 3809 0 08:47:45 ? 00:00:00 sshd: root@pts/0 root 16320 3809 0 08:47:55 ? 00:00:00 sshd: root@pts/1
blh      17379 17317  0 09:03:48 pts/1    00:00:00 ./bin/sh
root 16389 16388 0 08:48:01 pts/1 00:00:00 sh root 16390 16389 0 08:48:04 pts/1 00:00:00 ksh root 16391 16390 0 08:48:05 pts/1 00:00:00 sh root 16255 16252 0 08:47:46 pts/0 00:00:00 -sh root 16323 16320 0 08:47:56 pts/1 00:00:00 -sh
# UNIX95=1 ps -f -C sh UID PID PPID C STIME TTY TIME CMD root 16388 16323 0 08:48:01 pts/1 00:00:00 sh root 16617 16391 0 08:52:48 pts/1 00:00:00 /usr/bin/sh root 16389 16388 0 08:48:01 pts/1 00:00:00 sh root 16391 16390 0 08:48:05 pts/1 00:00:00 sh root 16255 16252 0 08:47:46 pts/0 00:00:00 -sh root 16323 16320 0 08:47:56 pts/1 00:00:00 -sh
blh      17379 17317  0 09:03:48 pts/1    00:00:00 ./bin/sh

So the first example finds unwanted process names that are not "sh".

This is the problem solved by ps -C <process_name>



Bill Hassell, sysadmin
Dennis Handly
Acclaimed Contributor

Re: pkill not working as expected

>The example: demonstrates the problem.

 

But that was not the example for your issue.  That was the example for the OP to see what he was getting.

 

>pgrep does not discriminate the basename of a process when pathnames such as /usr/bin/sh or ./bin/sh are used:

 

Yes it can.  If you look at my fine print and pgrep(1), your sh example would be:

ps -f -p$(pgrep '^sh$' | tr "^J" ",")

 

(Basically, if I have a command I have never used before, I like to read the whole man page. :-)

Bill Hassell
Honored Contributor

Re: pkill not working as expected

>> If you look at my fine print and pgrep(1), your sh example would be:
>> ps -f -p$(pgrep '^sh$' | tr "^J" ",")

 

Correct indeed. Both constructs give the same results:

ps -f -p$(pgrep '^sh$' | tr "^J" ",")

UNIX95=1 ps -f -C sh

 

which illustrates the Unix adage:

    "If you can't find at least 5 ways to do the same thing, you haven't looked hard enough"

 

The pgrep man page gives a slight hint with the telnet$ example, but would be much enhanced with the RE '^telnet$' or similar example. Personally, I find the -C concept simpler to use and explain, and only one process is needed rather than 3.



Bill Hassell, sysadmin
Dennis Handly
Acclaimed Contributor

Re: pkill not working as expected

>I find the -C concept simpler to use and explain, and only one process is needed rather than 3.

 

Again, that example was only to show the OP what he was getting with pgrep -f, not that I would ever use it. :-)

And yes, I normally use ps -H -C many times a day and never used pgrep(1) before.