3

As an exercise, I wanted to kill a process by command line using basic bash principles but i'm having some errors that i don't understand:

ps -A | grep nautilus | egrep -o '[0-9]{4,5}' | kill

1) It doesn't work

If i try

ps -A | grep nautilus | egrep -o '[0-9]{4,5}' > kill

2) Doesn't work either

3) If i do (..) egrep '\d' (...) shouldn't this be the same as [0-9] ?

4) Is there any way that i do something like this:

kill < (greps (...) )
3
  • Why is this getting migrated? Isn't it programming related?
    – aioobe
    Jun 7, 2011 at 20:04
  • It is absurd that this was migrated. Shell scripting is absolutely programming related.
    – riwalk
    Jun 7, 2011 at 20:07
  • 1
    First of all: nautilus -q (!!); otherwise killall name, pgrep -fl name, pkill -f name
    – sehe
    Jun 7, 2011 at 20:51

7 Answers 7

5

Try

kill `ps -A | grep nautilus | egrep -o '[0-9]{4,5}'`

The commands within the backticks will be executed and fed as a part of the command.

2
  • 3
    ... or using $() instead of the backticks, easier to read :)
    – slhck
    Jun 7, 2011 at 20:48
  • 4
    The assumption of 4-5 digits is strange; most ps implementations don't zero-pad the left of pids, and pid usage can wrap around. Some OSes even actually use more than 16-bits of pid space.
    – Phil P
    Jun 7, 2011 at 21:50
3
  1. The | operator feeds the "standard output" (stdout) from the left to the "standard input" of the right; standard input, or stdin, is equivalent to "what I read as though from the user if they type into me". The kill(1) command kills the process ids provided on its command-line, not on its stdin. So inserting xargs before kill would help:

    ... | xargs kill
    

    because xargs(1) takes its stdin and batches it up into chunks, to repeatedly invoke the supplied command (here, "kill") with command-lines made up of those chunks.

  2. The > operator is used to redirect stdout to a file, so you've created a new file in the current directory, which has the filename "kill" and contents of the pids.

  3. The pattern \d is not a part of either the "standard" or "extended" regular expression languages; instead, it was introduced by Perl (I believe) and is in many later variants of the regular expression language. PCRE, for Perl Compatible Regular Expressions, provides a library which was instrumental in spreading the extended syntax to many other tools and languages, but is certainly not the only implementation today. There are websites which will provide matrix comparisons of the different regexp languages for you.

    PCRE ships with pcregrep(1) which will understand \d for you; also, modern GNU grep has the -P option, which will use PCRE for regexps.

  4. You're here after the concept called "command substitution", where the stdout of the command is used directly in the command-line; the modern syntax for this is $(...), although you'll also see backticks used, `...` but that's historical and doesn't nest well. So:

    kill $(ps ... | pcregrep ... | munge)
    
2

If you know the name of the executable, it is better to use pidofto find the pid of the running program.

2

You can also try killall:

killall nautilus

(from the package psmisc, at least in debian/ubuntu).

1
  • 1
    OP didn't state their OS. Better hope it's not SysV, such as Solaris, in which killall doesn't do what you think it does. ;)
    – Phil P
    Jun 8, 2011 at 5:17
1

Most Linuxes have pkill (and pgrep) which do what you want.

pkill nautilus
0

I would go for xargs:

ps -A | grep nautilus | egrep -o '[0-9]{4,5}' | xargs -L 1 kill

Actually, kill accepts multiple arguments, so -L 1 is not strictly needed.

-1
   ps -A | grep nautilus | awk '{print "kill " $1}' | bash

I would do it this way, but there are many ways to execute the same thing =) I had this answer written out in detail on stackoverflow, to find it migrated here.

1
  • why? curious. in particular about the last part 'awk '{print "kill " $1}' | bash'
    – matchew
    Jun 15, 2011 at 15:50

You must log in to answer this question.