A limitação shebang do argumento 2 do Linux (interpeter + argumento único) é observada na maioria das respostas, mas dizer que isso não pode ser feito está incorreto - você só precisa mudar para um interpretador que possa fazer algo útil com um único argumento:
#!/usr/bin/perl -we%ENV=();exec "/bin/sh " . join " ", map "'$_'", @ARGV;
# your sh script here
O que isto faz é invocar perl
com um script de uma linha ( -e
) que limpa %ENV
(mais barato que env -i
) e invoca exec /bin/sh
, citando corretamente os argumentos. Outras perl
logic podem ser adicionadas, se necessário (embora não muito no Linux, já que você está limitado a BINPRM_BUF_SIZE
caracteres, o que é provável 128)
Infelizmente, isso é específico do Linux, não funcionará em um sistema que permita múltiplos argumentos: - /
perl
processa esta string como um único argumento, então ela não é citada acima como você normalmente faria com perl -e ...
da linha de comando (se você fosse adicionar aspas, elas são preservadas, perl vê apenas uma string literal, com avisos sobre ela que se queixam de uma constante inútil).
Observe também que há uma pequena alteração no comportamento quando usada dessa forma, @ARGV
normalmente contém apenas os argumentos e $0
contém o script, mas com este shebang $ARGV[0]
é o nome do script (e $0
é -e
) o que torna isso um pouco mais fácil.
Você também pode resolver isso com um intérprete que "reprocessa" sua linha de comando (sem um argumento -c
extra) o antigo AT & T ksh93
:
#!/bin/ksh /usr/bin/env -i /bin/sh
embora talvez ksh
não seja tão comum hoje em dia; -)
( bash
tem um recurso semelhante com --wordexp
, mas é "não documentado" nas versões em que funciona, e não habilitado em tempo de compilação nas versões em que está documentado: - / Também não pode ser usado para isso, pois precisa de dois argumentos ...)
Além disso, efetivamente, uma variação nas respostas do @Patrick e @ maxschlepzig:
#!/bin/bash
[ "$_" != bash ] && exec -c -a "bash" /bin/bash "$0" "$@"
# your script here
Em vez de usar uma nova variável, ela usa a variável especial " _
", se não estiver definida como "bash", substitua o script por exec
usando -a
para gerar ARGV[0]
(e, portanto, $_
) apenas "bash" e usando -c
para limpar o ambiente.
Como alternativa, se for aceitável limpar o ambiente no início do script (apenas bash):
#!/bin/sh
unset $(compgen -e)
# your script here
Utiliza compgen
(ajudante de conclusão) para listar os nomes de todas as variáveis de ambiente exportadas e unset
s de uma só vez.
Veja também Múltiplos argumentos em shebang para mais detalhes sobre o problema geral da shebang comportamento.