Why does the following script delete itself?
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.
Related videos on Youtube
user253751
Updated on September 18, 2022Comments
-
user253751 over 1 year
If you create an executable file with the following contents, and run it, it will delete itself.
How does this work?#!/bin/rm
-
Admin about 8 years
-
Admin almost 8 years@DigitalTrauma Heh, that was my first thought when I saw this.
-
Admin almost 8 yearsit's not about
rm
, it is about the#!
. The question could be rephrased to how does any executable script with a#!
works. -
Admin almost 8 yearsHow did you manage to stumble upon this?
-
Admin almost 8 years@user1717828 Probably PPCG.
-
Admin almost 6 yearsThat's definitely an epic question. I regret that I can upvote it only once.
-
-
jlp about 8 yearsOther names for "#!" you might hear are "pound bang" and "hash bang". See en.wikipedia.org/wiki/Shebang_(Unix) for details.
-
cat almost 8 years@jlp Pound bang? Is that like "bang for your buck"? Heh...
-
Swiss Frank about 4 years"passing in the script's name" -- not quite. That's how it worked in the 70s, but it invites a race condition hack. You can start a script with one heading, or set of file permissions, then change it before the interpreter is started. Instead, I believe such files are opened and read by the OS, then LEFT opened and passed to the interpreter as file handle 2 (or 0?). I'm not 1000% sure of this so I won't edit the actual answer
-
Stephen Kitt about 4 years@SwissFrank yes, there is a race, and yes, there are loaders (in the Linux kernel) which support passing an open file descriptor, but not for scripts. In fact, if the race were fixed for scripts, arbitrary commands would no longer work as shebangs, and
rm
couldn’t be used in this way.