Eu vi conselhos em vários lugares para usar a seguinte linha shebang
#!/usr/bin/env bash
em vez de
#!/usr/bin/bash
Minha reação instintiva é: "e se alguém substituir este executável pelo seu próprio em say ~/.local/bin
?" Esse diretório geralmente é configurado no caminho do usuário antes dos caminhos de todo o sistema. Vejo isso levantado como uma questão de segurança, muitas vezes como uma observação lateral, e não como algo a ser levado a sério, mas queria testar a teoria.
Para testar isso eu fiz algo assim:
echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/bash
chmod 755 $HOME/.local/bin/bash
PATH=$HOME/.local/bin env bash
Isso rende
/usr/bin/env: ‘bash’: No such file or directory
Para verificar se estava captando alguma coisa, eu também fiz
echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/perl
chmod 755 $HOME/.local/bin/perl
PATH=$HOME/.local/bin env perl
que imprime, como eu esperava,
Hacked!
Alguém pode me explicar por que o substituto bash
não foi encontrado, mas o substituto perl
sim? Isso é algum tipo de medida de "segurança" que (do meu ponto de vista) não entende o objetivo?
EDIT: Porque fui solicitado: não estou perguntando como /usr/bin/env bash
é diferente de usar /bin/bash
. Estou fazendo a pergunta conforme indicado acima.
EDIT2: Deve ter sido algo que eu estava fazendo errado. Tentei novamente hoje (usando o caminho explícito em env
vez do implícito) e nenhum comportamento "não encontrado".
Responder1
"e se alguém substituir este executável pelo seu próprio, digamos ~/.local/bin ?
Então o script não funciona para eles.
Mas isso não importa, já que eles poderiam quebrar o script de outras maneiras ou executar outro programa diretamente, sem mexer com PATH
ou env
.
A menos que seus usuários tenhamoutrodiretórios de usuários em seus diretórios PATH
, ou pode editar os PATH
de outros usuários, não há realmente nenhuma possibilidade de um usuário bagunçar outro.
No entanto, se não fosse um script de shell, mas algo que conceda privilégios adicionais, como um wrapper setuid para algum programa, então as coisas seriam diferentes. Nesse caso, serianecessáriopara usar um caminho absoluto para executar o programa, coloque-o em um diretório que usuários sem privilégios não possam modificar e limpe o ambiente ao iniciar o programa.
Responder2
Quanto à diferença de comportamento entre o shell e o perl
, perl
ao contrário do shell inspeciona a primeira linha para determinar o que executar:
$ cat tcl
#!/usr/bin/env tclsh
puts "TCL running as [pid]"
$ perl tcl
TCL running as 39689
$ cat sbcl
#!/opt/local/bin/sbcl --script
(format t "~a running as ~a~%" 'lisp (sb-unix:unix-getpid))
$ perl sbcl
LISP running as 39766
$
Os usos desse recurso incluemescrevendo testes em alguma outra linguagem além do perlentão é possível ter scripts compatíveis com TAP em outros idiomas e prove
algo assim irá executá-los corretamente.
Responder3
Não há risco de segurança aqui. /usr/bin/env
deve selecionar o binário apropriado de acordo com o ambiente do usuário. Portanto, se o usuário instalou o seu próprio bash
no ~/.local/bin
, então /usr/bin/env
deveria tentar usá-lo (ele pode, por exemplo, ter compilado uma versão com recursos extras que não estão disponíveis na versão para todo o sistema e preferiria usá-lo no lugar da versão para todo o sistema). O mesmo vale para qualquer outro binário/interpretador. Não há risco de segurança, porque o usuário não poderá executar nada que não seria capaz de executar de qualquer maneira.
Quanto ao motivo pelo qual o substituto está falhando no seu caso, duvido que tenha algo a ver com /usr/bin/env
. Tente executar PATH=~/.local/bin bash
, PATH=~/.local/bin bash <path-to-script>
(como seria chamado quando você executa o script) e PATH=~/.local/bin /usr/bin/env bash
veja qual deles falha. Isso deve dar uma pista sobre a que se refere o erro "arquivo não encontrado".