83

If you create an executable file with the following contents, and run it, it will delete itself.
How does this work?

#!/bin/rm
  • 4
    Related – Digital Trauma May 3 '16 at 18:00
  • @DigitalTrauma Heh, that was my first thought when I saw this. – cat May 3 '16 at 23:16
  • it's not about rm, it is about the #!. The question could be rephrased to how does any executable script with a #! works. – njzk2 May 4 '16 at 16:12
  • 1
    How did you manage to stumble upon this? – user1717828 May 4 '16 at 19:33
  • 1
    That's definitely an epic question. I regret that I can upvote it only once. – Danila Kiver Jul 6 '18 at 13:54
111

The kernel interprets the line starting with #! and uses it to run the script, passing in the script's name; so this ends up running

/bin/rm scriptname

which deletes the script. (As Stéphane Chazelas points out, scriptname here is sufficient to find the script — if you specified a relative or absolute path, that's passed in as-is, otherwise whatever path was found in PATH is prepended, including possibly the emptry string if your PATH contains that and the script is in the current directory. You can play around with an echo script — #!/bin/echo — to see how this works.)

As hobbs pointed out, this means your script is actually an rm script, not a bash script — the latter would start with #!/bin/bash.

See How programs get run for details of how this works in Linux; the comments on that article give details for other platforms. #! is called a shebang, you'll find lots of information by searching for that term (thanks to Aaron for the suggestion). As jlp pointed out, you'll also find it referred to as "pound bang" or "hash bang" (# is commonly known as "pound" — in countries that don't use £ — or "hash", and ! as "bang"). Wikipedia has more info.

  • 9
    Other names for "#!" you might hear are "pound bang" and "hash bang". See en.wikipedia.org/wiki/Shebang_(Unix) for details. – jlp May 3 '16 at 16:31
  • @jlp Pound bang? Is that like "bang for your buck"? Heh... – cat May 3 '16 at 23:17
  • Reminds me of ol' CrunchBang – Xen2050 May 3 '16 at 23:53
  • 1
    Technically, the argument to rm will be the path to the script, that is the first argument to the execve() system call made by the process. Typically, if you ran the script as ./scriptname, that will be ./scriptname and if you invoked it as scriptname, that will be /path/to/scriptname where /path/to is the entry in $PATH where that script was found. Typically, it will only by scriptname if you have the empty string in $PATH and you've invoked the script as scriptname and scriptname is in the current directory. – Stéphane Chazelas May 4 '16 at 13:13

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.