2022-04-11 pgrep, or what I do when Vagrant hangs

I use Virtualbox (via Vagrant) pretty extensively. Unfortunately, sometimes it just hangs. (Two cases when it tends to happen is when I put my laptop to sleep with the VM on or when I try to run too many things on the VM. Not every time, but often enough to be a nuisance – say, maybe once a month. And given that I regularly have uptime on the order of weeks – Emacs uptime, not computer uptime, mind you;-), though in my case it is usually almost the same), I don’t want to reboot the system. Unfortunately, in such situations even vagrant halt --force doesn’t help.

What helps is just killing all Vagrant processes and saying vagrant halt (for some reason, just killing them is not enough – go figure). The naive way to find all Vagrant processes is to say ps aux | grep vagrant and manually copy all the pids to a kill -9 command. That ps​/​grep invocation has an annoying side effect of listing itself – after all, it also matches the vagrant regex. There is a neat workaround where you say ps aux | grep [v]agrant – and I learned it from the grep Info manual of all places!

Once I showed this trick to a friend, and he pointed me to the pgrep command. You can just say pgrep vagrant and see the PIDs of all vagrant processes. This is not helping, though, because the list can be actually empty – the executable name for these processes is usually ruby. However, the string vagrant obviously appears in the command-line arguments, so here’s how you can get the PIDs of the Vagrant-related processes on your machine: pgrep --full vagrant. And to kill all of them, just say kill -9 $(pgrep --full vagrant) (in Bash).

But we can do even better! I checked the manpage for pgrep, and it turns out that it has a variant called pkill which both finds and kills the processes it found. (Interestingly, it seems that the binaries for pgrep and pkill are identical, which implies the common trick where the behavior of some program depends on the filename of its executable, but they are neither hard- nor symlinks on my system.) So, an even shorter way of killing all Vagrant-related processes is pkill -9 --full vagrant. (For the sake of completeness, there’s also pwait which waits until all “selected” processes finish their job.)

So, I wrote an extremely simple script, just this and then vagrant halt in the correct directory, to deal with my unresponsive Vagrant processes.

That’s it for today!

CategoryEnglish, CategoryBlog