Pergunta sobre shebang, bash – Qual é o preferido Bash shebang?

904

Existe algumBash shebang objetivamente melhor do que os outros para a maioria dos usos?

#!/usr/bin/env bash#!/bin/bash#!/bin/sh#!/bin/sh -etc

Lembro-me vagamente de que há muito tempo ouvi dizer que adicionar um traço ao final impede que alguém passe um comando para seu script, mas não consegue encontrar detalhes sobre isso.

E os seus/usr/local/bin/bash no OpenBSD. jww

Sua resposta

5   a resposta
1231

Você deveria usar#!/usr/bin/env bash paraportabilidade: diferentes * nixes colocadosbash em lugares diferentes, e usando/usr/bin/env é uma solução para executar o primeirobash encontrado noPATH. Esh não ébash.

hey @KolobCanyon "Basicamente bash é sh, com mais recursos e melhor sintaxe" (vejaaskubuntu.com/a/141932) Jamie Mason
Qual idioma ésh? Kolob Canyon
Essa resposta é enganosa. POSIX não diz queenv está em/usr/bin/env. Pode ser em/bin/env ou em qualquer lugar, desde que esteja no caminho. Pode ser em/dummy/env E se/dummy é emPATH. O próprio Shebang é indefinido no POSIX, então eu poderia fazer#!stop toaster inicie a máquina de café USB e seja compatível com POSIX. assim#!/usr/bin/env bash não é particularmente melhor do que#!/bin/bash, poderia ser menos portável dependendo. darkfeline
@darkfeline A portabilidade não é absoluta - é matematicamente impossível fazer qualquer script que faça o mesmo em todas as plataformas. De 2012 a 2018/usr/bin/env existe em mais máquinas do que qualquer um dos/bin/bash xor/usr/bin/bash, então um script que comece com esta linhafaça a coisa esperada em tantas máquinas quanto possível. l0b0
17

Usar uma linha shebang para invocar o intérprete apropriado não é apenas para BASH. Você pode usar o shebang para qualquer linguagem interpretada em seu sistema, como Perl, Python, PHP (CLI) e muitos outros. By the way, o shebang

<code>#!/bin/sh -
</code>

(também pode ser dois traços, ou seja--) termina todas as opções bash depois serão tratadas como nomes de arquivos e argumentos.

Usando oenv comando torna seu script portátil e permite que você configure ambientes personalizados para o seu script, portanto, scripts portáteis devem usar

<code>#!/usr/bin/env bash
</code>

Ou para qualquer que seja a linguagem, como para Perl

<code>#!/usr/bin/env perl
</code>

Certifique-se de olhar para oman páginas parabash:

<code>man bash
</code>

eenv:

<code>man env
</code>

Nota: No Debian e em sistemas baseados em Debian, como o Ubuntu,sh é ligado àdash nãobash. Como todos os scripts do sistema usamsh. Isso permite que o bash cresça e o sistema permaneça estável, de acordo com o Debian.

Além disso, para manter a invocação * nix como nunca uso extensões de arquivo no shebang invocava scripts, já que você não pode omitir a extensão em invocação em executáveis ​​como é possível no Windows. O comando file pode identificá-lo como um script.

68

/bin/sh geralmente é um link para o shell padrão do sistema, que é frequentementebash mas em, por exemplo, sistemas Debian é o peso mais levedash. De qualquer maneira, o shell Bourne original ésh, então se o seu script usa algumbash (2ª geração, "Bourne Again sh") características específicas ([[ ]] testes, matrizes, várias coisas açucaradas, etc), então você deve ser mais específico e usar o mais tardar. Dessa forma, nos sistemas em que o bash não está instalado, o script não será executado. Eu entendo que pode haver uma excitante trilogia de filmes sobre essa evolução ... mas isso pode ser boato.

Observe também que quando evocado comosh, bash até certo pontocomporta-se como padrão POSIX sh (Veja tambémos documentos GNU sobre isso).

@aij Eu não sei porque eu coloquei "muitos ou mais" lá - eu sou um usuário fedora, onde/bin e/sbin há anos tem sido apenas symlinks por padrão, para/usr/bin e/usr/sbin, então nesse contexto/bin/sh é um link parabash e o diretório atual é/usr/bin. Mas vou corrigir o que precede. delicateLatticeworkFever
"Eu posso digitar por meia milha antes de minhas mãos começarem a tremer." xdhmoore
O Domínio Público Korn Shell (pdksh) é o padrão no OpenBSD. jww
A maioria dos sistemasnão ligação/bin/sh para qualquer lugar/usr como isso tornaria difícil para os scripts init rodarem antes/usr está montado. aij
3

Isso realmente depende de como você escreve seus scripts bash. Se seu/bin/sh é symlinked para bash, quando bash é invocado comosh, alguns recursos não estão disponíveis.

Se você quiser recursos específicos de bash, não-POSIX, use#!/bin/bash

O Bash não está instalado no OpenBSD. Se você instalá-lo viapkg_add, então está localizado em/usr/local/bin, que pode não estar no caminho. jww
7

Eu recomendo usar:

<code>#!/bin/bash
</code>

Não é 100% portátil (alguns sistemas colocambash em um local diferente de/bin), mas o fato de muitos scripts existentes usarem#!/bin/bash pressiona vários sistemas operacionais para fazer/bin/bash pelo menos um link simbólico para o local principal.

A alternativa de:

<code>#!/usr/bin/env bash
</code>

tem sido sugerido - mas não há garantia de que oenv o comando está em/usr/bin (e eu usei sistemas onde não é). Além disso, este formulário usará a primeira instância dobash nos usuários atuais$PATH, que pode não ser uma versão adequada do shell bash.

Se você precisa de um script para rodar em um sistema que não tem/bin/bash, você pode modificar o script para apontar para o local correto (que é reconhecidamente inconveniente).

Eu discuti as compensações em maior profundidademinha resposta paraessa questão.

Perguntas relacionadas