For quite some time—as my research will show, March 2016—, I have
been annoyed by a directory named --help
showing up in my home
directory (and sometimes in others).
It’s just an empty, innocent directory with a weird name.
Removed by a simple run of rmdir ./--help
.
Yet, it would turn up again.
Sometimes soon, sometimes it took a few weeks.
I had no idea where it came from.
Obviously, a simple mkdir --help
just print’s the mkdir
help:
Usage: mkdir [OPTION]... DIRECTORY...
Create the DIRECTORY(ies), if they do not already exist.
...
I thought, maybe some program was called once with --help
but
didn’t understand it, yet stored it somewhere and would create it when
run again. I suspected many things, especially applications I don’t use that
often, like Gimp or Transmission. I grepped all dotfiles in $HOME
for --help
. To no avail.
I decided I had to track this down.
My first thought was to use
fatrace
,
which logs all file accesses. But fatrace
doesn’t register
directory creation (the fanotify
API does, I think).
I didn’t know what to do, and left the problem alone for some time.
The --help
directory kept reappearing.
Some time later, I read a book on eBPF, and decided I can log all mkdir(2) calls with it, globally. (I also think I tried this with SystemTap before, but I’m not sure anymore.)
I wrote a bpftrace
script called mkdirsnoop
, a variant of opensnoop
.
It would print all mkdir(2) calls and what program ran it, system wide.
I ran it a lot, but not consistently.
Yesterday, it finally triggered! I tweeted:
I’m really flipping the table.
For months, I’ve been trying to figure out what occasionally creates “–help” folders in my $HOME. I have no idea why it happens.
I wrote a bpftrace script to find the culprit.
Today it triggered.
It says, it’s mkdir(1).
(╯°□°)╯︵ ┻━┻
If it was mkdir(1), it must have been created by a script. Gimp and Transmission were acquitted of charge.
Julien Kirch proposed to put a different mkdir
into my $PATH
,
which I think was a smart idea. I wrote this:
#!/bin/sh
printf '%s\n' "mkdir called from $$ at $(date)" >> /tmp/mkdirlog
pstree -sap $$ >> /tmp/mkdirlog
exec /usr/bin/mkdir "$@"
Very quickly, the script triggered, and I saw:
runit,1
`-sh,30996 -c urxvt
`-urxvt,30997
`-zsh,30998
`-zsh,31055
`-mkdir,31058 /home/leah/bin/mkdir --help
`-pstree,31060 -sap 31058
So it was actually zsh
calling mkdir --help
.
(Or a zsh
script.)
But there was no directory --help
.
Because calling mkdir --help
does not create a directory,
instead printing the help.
Jannis Harder told me that the zsh completion for mkdir
would run
mkdir --help
(to see if it’s the GNU variant), which I could verify.
But it didn’t explain the --help
directory.
However, I had something to track down now.
Using my extrace, I would
log all runs of mkdir
with a --help
argument, and at some point
I found:
mkdir -p -- --help
Mysterious. I grepped my dotfiles again and found the unsuspicious
function mkcd
:
# mkcd -- mkdir and cd at once
mkcd() { mkdir -p -- "$1" && cd -- "$1" }
This is a helper function I use a lot. But I don’t call it with
--help
of course, and then wonder for 4 years why I do that.
Well I don’t. But zsh
does, because I also had:
compdef mkcd=mkdir
This was a quick shortcut to complete mkdir
’s arguments (only
directories) also for mkcd
. I added it in 2013. Even before I added
the -p
flag in 2016.
Quickly, I verified that mkcd <TAB>
would create a --help
directory. But only if the completion wasn’t loaded already,
e.g. when I didn’t run mkdir <TAB>
before. This explains why
the directory only appeared sporadically.
I quickly rewrote the completion:
_mkcd() { _path_files -/ }
compdef _mkcd mkcd
And another mystery of my setup has been solved. Case closed.
NP: Pearl Jam—Take The Long Way