Today I was trying to grep through a directory structure full of PHP code, looking for a function which, inexplicably, returned -6.

Grepping for anything with a dash as not as easy as one would think, since grep assumes the - indicates a command argument, and just pauses, waiting for further input, like this:

[davidy:~/tmp] 130 % grep -6 stupid-php-files/*
^C
[davidy:~/tmp] 130 % grep "-6" stupid-php-files/*
^C

No problem, I figured, Iโ€™ll just escape the dash. But nope, no, and na-da:

[davidy:~/tmp] 130 % grep \-6 stupid-php-files/*
^C

Bare double dash does do the deed!

Finally, Google leads me on a journey of discovery of โ€œbare double dashesโ€.

It turns out, a double-dash (--) indicates to the built-in bash commands that weโ€™re done with command options, allowing the -6 to be searched for as a plain string:

[davidy:~/tmp] 130 % grep -- -6 stupid-php-files/*
     return(-6); # because stupid
[davidy:~/tmp] %

What about brackets?

What about grepping for open/closing brackets? (hi, @tjh)

Turns out that is just as simple as escaping the bracket, as illustrated below:

[davidy:~/tmp] % grep (because stupid-php-files/*
zsh: unknown file attribute: b
[davidy:~/tmp] 1 % grep \(because stupid-php-files/*
(because I can)
[davidy:~/tmp] %

Practical test ?

When I shared my new, groundbreaking discovery, one of my colleagues pointed out that the following is therefore completely safe (while at the same time quite terrifying):

rf -- -rf /

To prove it (yes, I tested on stupid-php-files first!):

[davidy:~/tmp] 1 % rm -- -rf /
rm: -rf: No such file or directory
rm: /: is a directory
[davidy:~/tmp] 1 %

Youโ€™ve successfully subscribed to ๐Ÿ‘จโ€๐Ÿ’ป Funky Penguin
Welcome back! Youโ€™ve successfully signed in.
Great! Youโ€™ve successfully signed up.
Your link has expired
Success! Check your email for magic link to sign-in.