I want to toggle rofi an application launcher with one keybinding. I made a shell script,


rofi -dpi 1 -modi drun -show drun -show-icons

And bound it to some key. This works but to toggle toggle it back to not running, I tried:

pkill -0 rofi || rofi -dpi 1 -modi drun -show drun -show-icons

That won't let rofi start to begin with. I tested pkill emacs || emacs and that does toggle emacs. Could someone tell me how can I fix it for rofi? And, what does the argument "-0" do? I could not find it in the manual.

I did find this,

I spent a decent chunk of time beating my head against this, and then I realized that rofi stores its pid. We can access the pid file via the config, which in turn gives us access to all the information we need. Before I get to the exciting stuff, though, it's important to mention safety. It's a really good idea to limit your process count (somehow) in case you create a runaway script. Speaking from experience, it could be half an hour before you can free up enough memory to switch to another tty and kill everything.

if [[ 10 -lt $(pgrep -c -f "$0") ]]; then
    pkill -f rofi
    pkill -f "$0"
    exit 1

I am not sure if this is exactly what I want or what does that code even do.

1 Answer 1


tl;dr: As it is, your code says "if pkill doesn't find a rofi process that we can kill, then run rofi". It doesn't actually say to kill it if it's already running, just to crudely check if it's running and if not, start it. If you really want it to kill it every time, remove -0.

-0 kills with signal 0, which just checks whether the calling process has the authority to kill the process, and the process exists. It doesn't actually kill anything.

From man 3 kill:

If sig is zero (the null signal), error checking is performed but no signal is actually sent. The null signal can be used to check the validity of pid.

Passing the signal this way is documented here in man pkill (somewhat unclearly as -signal, which really means -[signal]):

-signal --signal signal: Defines the signal to send to each matched process. Either the numeric or the symbolic signal name can be used.

If you want to kill the process, use pkill without -0 to use the default signal (SIGTERM), or pass another signal name or number to use that instead.

As a side note, this method of handling application lifecycle is pretty basic, and can fail for a number of reasons (eg. kill isn't synchronous, so there's no guarantee that the previous rofi will be gone before the next one appears if you replace -0 with a fatal signal). For that reason it would ideally be better to have the application itself, or a service manager, handle this more reliably.

  • Care to suggest an application or service manager based approach? I am sorry, I am very new to rofi and shell scripting.
    – scribe
    Mar 22, 2021 at 1:59
  • @scribe - An application level approach means adding the code to rofi itself. A service manager approach is using (for example) systemd user services with Type=exec or similar.
    – Chris Down
    Mar 22, 2021 at 2:56
  • Actually, pressing Esc gets rid of the rofi after having opened it. I am not sure exactly how, I think it disappears when it loses focus. Do you think there could be a way of making it lose focus with the same keybinding?
    – scribe
    Mar 22, 2021 at 23:45
  • @scribe It's probably the escape itself which does that, but I wouldn't try to emulate it -- being confident about the right window and its current state is likely to be quite cumbersome.
    – Chris Down
    Mar 23, 2021 at 0:23

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.