/ usr / bin / env: zsh -: Nenhum arquivo ou diretório

2

Eu recebo o erro

/usr/bin/env: zsh -: No such file or directory

... quando executo um script executável zsh que começa com a seguinte linha shebang:

#!/usr/bin/env zsh -

Além disso, o FWIW, substituindo - por -- , faz com que /usr/bin/env imprima uma reclamação semelhante sobre zsh -- .

Eu só vi esse erro no Ubuntu, e apenas no contexto do hack do shebang. Sob Darwin, o mesmo script é executado corretamente. E sob o Ubuntu, rodando

% /usr/bin/env zsh -

da linha de comando é bem-sucedido. (Na verdade, "sob o Ubuntu" deve ser entendido como breve para "sob o Ubuntu 12.04 LTS e env (GNU coreutils) 8.13 ".)

Minha pergunta é: como posso modificar o shebang acima para evitar esse erro?

Claro, sei que remover o - à direita eliminará o erro, mas essa não é uma solução aceitável. O resto deste post explica porquê.

A linha shebang que está causando o erro surge como uma tentativa de cumprir duas diretrizes totalmente independentes:

  1. Para tornar os scripts portáteis, use #!/usr/bin/env <cmd ...> em vez de #!/path/to/cmd <...> .

  2. Colocar - como o único argumento para zsh na linha shebang de scripts zsh frustra certos tipos de ataques .

Então, eu posso reafirmar minha pergunta mais precisamente da seguinte forma: É possível satisfazer ambas as diretrizes sem acionar o erro mostrado acima no Ubuntu?

    
por kjo 02.05.2013 / 19:41

2 respostas

5

Linux (você mencionou "somente no Ubuntu", mas o único sistema operacional no qual você trabalhou foi o Darwin) não suporta passar múltiplos argumentos para um interpretador 'shebang'. Ele passa a string inteira (no seu caso, "zsh -" ) como um único argumento.

A maneira correta de garantir que o seu pacote não dependa da localização de um intérprete é, como parte do processo de instalação, localizar o intérprete e modificar o script para incluir o caminho correto. Alguns exemplos de código para fazer isso (por sh ) são fornecidos no link .

    
por 02.05.2013 / 20:03
4

Acho que a resposta à sua pergunta é basicamente "não". O mecanismo shebang simplesmente não é tão flexível.

A linha #! apenas permite especificar um comando para executar e (opcionalmente) um único argumento para esse comando. O nome do script é passado como outro argumento. Então, se foo.zsh começar com:

#!/usr/bin/env zsh

a execução foo.zsh é equivalente a executar /usr/bin/env zsh foo.zsh .

Se você especificou o caminho para zsh diretamente, pode passar um argumento adicional:

#!/usr/bin/zsh -

Mas com o #!/usr/bin/env hack, zsh é o argumento adicional.

Aparentemente, esse comportamento varia de sistema para sistema, como você viu. BTW, gostaria de verificar se o - não está sendo ignorado no Ubuntu.

Se você pode confiar em zsh estar em um local consistente em todos os sistemas que você gosta, você pode usar #!/usr/bin/zsh - (ignorando sua primeira diretriz).

Se você não puder, crie um link simbólico para zsh em um local consistente em cada sistema ou modifique a linha #! em seu script à medida que você o instala. (Eu fiz isso para scripts Perl, nos dias em que Perl não era sempre /usr/bin/perl .)

Ou você pode escrever um wrapper que, quando invocado sem argumentos, invoca zsh com um argumento - e altera seu shebang para:

#!/usr/bin/env zsh-wrapper

que requer apenas zsh-wrapper em algum lugar em $PATH , não necessariamente em um local consistente.

Veja também esta pergunta e minha resposta para isso para uma discussão das vantagens e desvantagens do #!/usr/bin/env hack.

E veja esta página para mais informações sobre o comportamento do shebang em vários sistemas do tipo Unix ( obrigado a Stephane Chazelas pelo link).

    
por 02.05.2013 / 20:04