Eu tentei o seguinte, mas parece não funcionar:
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
bash
shell-script
env
balki
fonte
fonte
Respostas:
A razão pela qual isso não funciona é porque ele vê
-i /bin/sh
como um único argumento paraenv
. Geralmente isso seria 2 argumentos,-i
e/bin/sh
. Esta é apenas uma limitação do shebang. De jeito nenhum.No entanto, você ainda pode executar esta tarefa, apenas de uma maneira diferente.
Se você deseja que essa tarefa seja executada pelo próprio script, e não precise fazer algo como isso
env -i script.sh
, é possível executar o script novamente.Isso fará com que o script seja reexecutado se a
CLEANED
variável de ambiente não estiver definida. Em seguida, na reexecução, ele define a variável para garantir que ela não entre em loop.fonte
env
dos coreutils do GNU agora têm uma opção-S
para solucionar problemas semelhantes a este, mas não exatamente o mesmo. Por exemplo#!/usr/bin/env -S perl -T
.#!/usr/bin/env -S -i /bin/sh
. Esteja ciente dos problemas de portabilidade.Execute seu script com
env -i
:E o script como de costume:
Se você deseja executar com um ambiente limpo, sem dizer isso explicitamente ao executar. Eduardo Ivanec fornece algumas idéias nesta resposta . Você pode chamar seu script recursivamente
exec
quando o ambiente não estiver limpo (por exemplo, $ HOME está definido):fonte
Com o bash, você pode fazer assim:
o
set -e
set -u
comandos e não são estritamente necessários, mas eu os incluo para demonstrar que essa abordagem não depende do acesso a variáveis não definidas (como[ "$HOME" != "" ]
seria o caso) e é compatível com umaset -e
configuração.Testando o
HOME
variável deve ser seguro porque o bash executa scripts no modo não interativo, ou seja, arquivos de configuração como~/.bashrc
(onde variáveis de ambiente podem ser definidas) não são originados durante a inicialização.Exemplo de saída:
fonte
Infelizmente, não vai funcionar dessa maneira - o Linux considera
-i /bin/sh
como um argumento a ser passadoenv
(veja Shebang ).fonte
A limitação shebang de 2 argumentos 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 intérprete que possa fazer algo útil com um único argumento:
O que isso faz é chamar
perl
com um script de uma linha (-e
) que limpa%ENV
(mais barato queenv -i
) e chamaexec /bin/sh
, citando corretamente os argumentos. Mais longeperl
lógica pode ser adicionada, se necessário (embora nãoBINPRM_BUF_SIZE
exista muito no Linux, pois você está limitado a caracteres, o que provavelmente é 128)Infelizmente, isso é específico do Linux, não funcionará em um sistema que permita vários argumentos shebang: - /
perl
processa essa sequência como um argumento único, portanto não é citada acima, como você faria normalmenteperl -e ...
na linha de comando (se você adicionar aspas, estas são preservadas, o perl vê apenas uma string literal, com avisos queixam-se de que é inútil constante).Observe também que há uma ligeira mudança no comportamento quando usado dessa maneira,
@ARGV
normalmente contém apenas os argumentos e$0
contém o script, mas com esse shebang$ARGV[0]
está o nome do script (e$0
é-e
), o que facilita um pouco.Você também pode resolver isso com um intérprete que "reprocessa" sua linha de comando (sem um
-c
argumento extra ) que a antiga AT&Tksh93
faz:embora talvez
ksh
não seja tão comum hoje em dia ;-)(
bash
possui um recurso semelhante--wordexp
, mas é "não documentado" nas versões em que trabalha e não é ativado 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 de @Patrick e @ maxschlepzig:
Em vez de usar uma nova variável, ela usa a
_
variável " " especial , se não estiver definida exatamente como "bash", substitua o script porexec
use-a
para fazerARGV[0]
(e, portanto$_
) apenas "bash" e usar-c
para limpar o ambiente.Como alternativa, se é aceitável limpar o ambiente no início do script (somente bash):
Que usa
compgen
(auxiliar de conclusão) para listar os nomes de todas as variáveis de ambiente exportadas eunset
as seleciona de uma só vez.Consulte também Vários argumentos no shebang para obter mais detalhes sobre o problema geral do comportamento do shebang.
fonte