¿Por qué se elimina el siguiente script?

84

Si crea un archivo ejecutable con el siguiente contenido y lo ejecuta, se eliminará solo.
¿Como funciona esto?

#!/bin/rm
usuario253751
fuente
44
Relacionado
Trauma digital
@DigitalTrauma Heh, ese fue mi primer pensamiento cuando vi esto.
gato
no se trata rm, se trata de la #!. La pregunta podría reformularse a cómo funciona cualquier script ejecutable con un #!.
njzk2
1
¿Cómo lograste tropezar con esto?
user1717828
1
Esa es definitivamente una pregunta épica. Lamento haberlo votado solo una vez.
Danila Kiver

Respuestas:

112

El núcleo interpreta la línea que comienza #!y la utiliza para ejecutar el script, pasando el nombre del script; así que esto termina corriendo

/bin/rm scriptname

que elimina el guión. (Como señala Stéphane Chazelas , aquí es suficiente para encontrar el script: si especificó una ruta relativa o absoluta, se pasa tal cual, de lo contrario, cualquier ruta que se encuentre está antepuesta, incluida posiblemente la cadena de entrada si contiene eso y el script está en el directorio actual. Puede jugar con un script de eco - para ver cómo funciona.scriptnamePATHPATH#!/bin/echo

Como señaló Hobbs , esto significa que su script es en realidad un rmscript, no un bashscript, este último comenzaría con #!/bin/bash.

Consulte Cómo se ejecutan los programas para obtener detalles sobre cómo funciona esto en Linux; Los comentarios sobre ese artículo dan detalles para otras plataformas. #!se llama shebang, encontrará mucha información buscando ese término (gracias a Aaron por la sugerencia). Como jlp señaló, también lo encontrará como "libra bang" o "hash bang" ( #comúnmente conocido como "libra" - en países que no usan £- o "hash", y !como "bang" ) Wikipedia tiene más información.

Stephen Kitt
fuente
99
Otros nombres para "#!" Es posible que escuche "libra explosión" y "hash bang". Ver en.wikipedia.org/wiki/Shebang_(Unix) para más detalles.
jlp
@jlp Libra Bang? ¿Es eso como "bang for your buck"? Je ...
gato
Me recuerda a
Ol
1
Técnicamente, el argumento to rmserá la ruta al script, ese es el primer argumento para la llamada al sistema execve () realizada por el proceso. Por lo general, si ejecutó el script como ./scriptname, eso será ./scriptnamey si lo invocó como scriptname, /path/to/scriptnameallí /path/toserá la entrada en la $PATHque se encontró ese script. Por lo general, solo lo hará scriptnamesi tiene la cadena vacía $PATHy ha invocado el script como scriptnamey scriptnameestá en el directorio actual.
Stéphane Chazelas