Que tipo de caminho em shebang é mais preferível?

20

Nos scripts, a primeira linha deve especificar o caminho para o intérprete.
Mas em servidores diferentes Linux, Unix ou BSD, esse caminho pode ser diferente.

O que é mais preferível?

#!/usr/bin/env bash 

ou

#!/bin/bash 
Roman Ivanov
fonte

Respostas:

22

Se você deseja usar a versão instalada pelo sistema de um determinado intérprete instalado em um local padrão, use o caminho direto. Se você deseja usar a versão do intérprete que aparece primeiro no usuário $PATH, use #!/usr/bin/env ....

O envcomando chama um comando especificado, permitindo definir ou desmarcar variáveis ​​de ambiente:

env FOO=BAR do-something
env DISPLAY=:0.0 xterm -ls &

Se você não especificar nenhuma variável de ambiente ou outras opções, ele apenas chamará o comando nomeado. (Usar dessa maneira é sem dúvida um pouco complicado.)

O objetivo de escrever o shebang como

#!/usr/bin/env interp

é invocar o que interpaparecer primeiro $PATH.

Isto significa que você não tem que saber, ao escrever o script, exatamente onde interpé (digamos, se poderia ser em qualquer /bin, /usr/binou /usr/local/bin). É claro que você precisa saber o que envé /usr/bin/env, mas isso parece ser razoavelmente universal.

A vantagem é que ele invoca a versão do intérprete que aparece primeiro no usuário $PATH. A desvantagem é que ele invoca a versão do intérprete que aparece primeiro no usuário $PATH.

Por exemplo, suponha que eu instalei uma compilação pessoal perlno meu diretório pessoal, como $HOME/bin/perle eu tenho $HOME/binna frente do meu $PATH. Se eu executar um script cujo shebang é

#!/usr/bin/env perl

então ele será executado com meu próprio perlexecutável instalado - o que pode não ser uma coisa boa. O autor do script provavelmente não o testou com o Perl de ponta que eu criei da fonte há um mês.

Para algo como Perl ou Bash que provavelmente será instalado em um local consistente na maioria dos sistemas ( /usr/bin/perle /bin/bash, respectivamente), eu usaria o caminho direto para o comando. Para algo mais obscuro que possa ser instalado de maneira diferente em sistemas diferentes, eu usaria o /usr/bin/envtruque ou escreveria um instalador que ajusta a linha shebang enquanto o script está sendo instalado. (Eu costumava fazer isso nos meus scripts Perl.)

ATUALIZAÇÃO: Entrei um pouco mais detalhadamente nesta resposta a esta pergunta no site Unix e Linux .

Keith Thompson
fonte
Acabei de começar a olhar para Ruby e descobri que a convenção em Ruby é começar com [code] #! / Usr / bin / env ruby ​​[/ code] por questões de portabilidade. Alguns observaram que isso dificulta o fornecimento de argumentos de linha de comando para o interpretador de ruby, como '-w', o que também seria um problema para o Perl.
bgvaughan
@bgvaughan Para o Perl, hoje em dia é tradicional apenas usar #!/usr/bin/perle depois usar use strict; use warnings;no corpo do script #!/usr/bin/perl -w. Mas -Ttem que estar na moda.
Keith Thompson.
então por que não usar #! perl se queremos apenas o primeiro no caminho?
partir de
@wheredidthatnamecomefrom: Porque isso não funciona. O tratamento da #!linha não usa $PATH. Você precisa especificar o caminho do intérprete. (Eu só percebi que, pelo menos no meu sistema, ele pode ser um caminho relativo, mas isso é raramente útil.)
Keith Thompson
6

A melhor prática é esta:

#!/usr/bin/env bash 
#!/usr/bin/env sh
#!/usr/bin/env python

E assim por diante...

Quando o Ubuntu começou a usar o dash, alguns scripts foram interrompidos. Houve uma discussão sobre isso. A maioria dos scripts foram escritos, o #!/bin/shque era um link para / bin / bash. O consenso é este: o redator do roteiro é responsável por especificar o intérprete. Portanto, se seu script sempre deve ser chamado com BASH, especifique-o no ambiente. Isso evita que você adivinhe o caminho, que é diferente em vários sistemas Unix / Linux. Além disso, funcionará se amanhã / bin / sh se tornar um link para algum outro shell como / bin / wthsh ou alguma outra bobagem.


fonte
A solução alternativa óbvia para o problema do traço era escrever #!/bin/bash. Concordo que o roteirista é responsável por especificar o intérprete, mas tudo o que significa é se você precisa de bater, dizem o bash não sh
Martin Bonner suporta Monica
1

Para sua informação, é um grande golpe #!, você precisa do #. Você usa esta linha para identificar com qual intérprete executar o script.

Por padrão, o Ubuntu vincula /bin/shao dash

Dependendo de quanto você gostaria de saber sobre o traço e por que o traço é usado para os shells do sistema ou do deamon, consulte:

traço cyberciti.biz

Página de manual do traço do Ubuntu

Bash é o shell padrão usado pela maioria dos usuários de Linux e possui recursos diferentes do que o dash. Um script escrito para o bash pode ou não ser executado corretamente se for executado com dash, quanto mais complexo o script, menor a probabilidade de ele ser executado.

O script escrito para perl, python, etc. não será executado com /bin/shou /bin/bash.

Então, quando você escreve um script, identifica qual intérprete deve ser usado com o shee-bang

A seleção do que usar é feita pelo autor do script, e um não é melhor que outro, todos eles têm vários recursos, vantagens e desvantagens.

Pantera
fonte