10

I have added an alias command to kill my guake terminal to my .bashrc

alias killguake="kill -9 $(ps aux | grep guake | head -n -1 | awk '{print $2}')"

But the problem is, the sub-command i.e. ps aux | grep guake | head -n -1 | awk '{print $2}' is executed at the time of terminal startup and killguake is set to kill -9 result_of_subcommand.

Is there any way to set it like so, that the sub command is run/calculated every time I run killguake? So that it can have the latest PID for the guake.

I have also tried piping to the kill using xargs but that also result in same, that is calculating everything at startup. Here is what I tried with piping

ps aux | grep guake | head -n -1 | awk '{print $2}' | xargs -I{} kill -9 {}
8
  • 2
    ... Or use quotes ' instead of double-quotes ". Commented Jan 17, 2017 at 7:55
  • 1
    To avoid using head, use grep like this grep [g]uake. Commented Jan 17, 2017 at 11:08
  • @richard nice tip, thanks. But what does [g] means? Commented Jan 17, 2017 at 12:11
  • 2
    Can't pidof replace that long command sequence? As in kill -9 $(pidof guake), or even better, pkill? Commented Jan 17, 2017 at 12:56
  • 3
    @MuhammadTahir [g] just means g in this context. [abc] would match a, b, or c ... but when there's just one character, it's basically redundant... except that now the grep won't find itself in ps, and therefore you can skip needing to do the head part to filter it out.
    – Foon
    Commented Jan 17, 2017 at 13:03

2 Answers 2

24

Use pkill instead:

alias killguake='pkill guake'

This is a whole lot safer than trying to parse the process table outputted by ps.

Having said that, I will now explain why your alias doesn't do what you want, but really, use pkill.

Your alias

alias killguake="kill -9 $(ps aux | grep guake | head -n -1 | awk '{print $2}')"

is double quoted. This means that when the shell parses that line in your shell initialization script, it will perform command substitutions ($( ... )). So each time the file runs, instead of giving you an alias to kill guake at a later time, it will give you an alias to kill the guake process running right now.

If you list your aliases (with alias), you'll see that this alias is something like

killguake='kill -9 91273'

or possibly even just

killquake='kill -9'

if guake wasn't running at the time of shell startup.

To fix this (but really, just use pkill) you need to use single quotes and escape the $ in the Awk script (which is now in double quotes):

alias killguake='kill -9 $(ps aux | grep guake | head -n -1 | awk "{print \$2}")'

One of the issues with this approach in general is that you will match the processes belonging to other users. Another is that you will possibly just find the grep guake command instead of the intended process. Another is that it will throw an error if no process was found. Another is that you're invoking five external utilities to do the job of one.

5
  • Using the ` with internal single quotes, I get invalid syntax near )` when I use this. Any idea? PS. I would use pkill with guake but some other things I need this approach. Commented Jan 17, 2017 at 10:56
  • 2
    @MuhammadTahir Really do not use this approach. I only mentioned what was wrong so that you would learn something. Do not ever try to parse the output of ps to find a process!! I'm serious. There is no instance where you need to do that, ever!
    – Kusalananda
    Commented Jan 17, 2017 at 11:02
  • Ah, ok, I thought my use case cannot be done with pkill, but I got my use case working with pkill. Thanks. But just out of curiosity, any idea about the syntax error? Commented Jan 17, 2017 at 11:12
  • 1
    @MuhammadTahir The answer is updated, have a look.
    – Kusalananda
    Commented Jan 17, 2017 at 11:13
  • Muhammad Tahir could also turn it into a function, but again, pkill is probably simpler.
    – Pysis
    Commented Jan 17, 2017 at 15:27
6

Use pkill, don't reinvent the wheel!

alias killguake="pkill -9 guake"

Not the answer you're looking for? Browse other questions tagged .