Por que o script a seguir se exclui?


84

Se você criar um arquivo executável com o seguinte conteúdo e executá-lo, ele será excluído.
Como é que isso funciona?

#!/bin/rm


@DigitalTrauma Heh, esse foi o meu primeiro pensamento quando vi isso.
cat

não se trata rm, é sobre o #!. A questão pode ser reformulada para como funciona qualquer script executável com um #!.
Njzk2 4/16

1
Como você conseguiu tropeçar nisso?
User1717828 4/04

1
Essa é definitivamente uma pergunta épica. Lamento que eu possa votar apenas uma vez.
Danila Kiver

Respostas:


112

O kernel interpreta a linha que começa com #!e a usa para executar o script, passando o nome do script; então isso acaba correndo

/bin/rm scriptname

que exclui o script. (Como Stéphane Chazelas aponta , scriptnameaqui é suficiente para encontrar o script - se você especificou um caminho relativo ou absoluto, que é passado como está, caso contrário, qualquer caminho que foi encontrado PATHé anexado, incluindo possivelmente a sequência de empry se você PATHcontiver isso e o script está no diretório atual. Você pode brincar com um script de eco - #!/bin/echo- para ver como isso funciona.)

Como hobbs apontou, isso significa que seu script é realmente um rmscript, não um bashscript - o último começaria #!/bin/bash.

Consulte Como os programas são executados para obter detalhes de como isso funciona no Linux; os comentários nesse artigo fornecem detalhes para outras plataformas. #!é chamado shebang, você encontrará muitas informações pesquisando esse termo (obrigado a Aaron pela sugestão). Como o jlp apontou, você também o encontrará conhecido como "pound bang" ou "hash bang" ( #geralmente conhecido como "pound") - em países que não usam £- ou "hash" e !"bang" ) A Wikipedia tem mais informações.


9
Outros nomes para "#!" você pode ouvir "pound bang" e "hash bang". Veja en.wikipedia.org/wiki/Shebang_(Unix) para obter detalhes.
jlp

@jlp Pound bang? Isso é como "bang for your buck"? Heh ...
cat

Lembra-me do velho ' CrunchBang
Xen2050

1
Tecnicamente, o argumento to rmserá o caminho para o script, que é o primeiro argumento para a chamada do sistema execve () feita pelo processo. Normalmente, se você executou o script como ./scriptname, será ./scriptnamee se você o invocou como scriptname, será /path/to/scriptnameonde /path/toestá a entrada em $PATHque o script foi encontrado. Normalmente, isso ocorrerá somente scriptnamese você tiver a sequência vazia $PATHe tiver invocado o script como scriptnamee scriptnameestá no diretório atual.
Stéphane Chazelas
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.