Na página Shell Command Language da especificação POSIX:
Se a primeira linha de um arquivo de comandos shell começar com os caracteres "#!", os resultados não serão especificados.
Por que o comportamento de #!
não especificado pelo POSIX? Acho desconcertante que algo tão portátil e amplamente usado tenha um comportamento não especificado.
Acho que principalmente porque:
o comportamento varia muito entre a implementação. Veja https://www.in-ulm.de/~mascheck/various/shebang/ para todos os detalhes.
No entanto, agora poderia especificar um subconjunto mínimo da maioria das implementações do tipo Unix: como
#! *[^ ]+( +[^ ]+)?\n
(com apenas caracteres do caractere de nome de arquivo portátil definido nessas uma ou duas palavras) onde a primeira palavra é um caminho absoluto para um executável nativo, a coisa não é muito longo e comportamento não especificado se o executável é setuid/setgid, e implementação definida se o caminho do interpretador ou o caminho do script é passado comoargv[0]
para o interpretador.O POSIX não especifica o caminho dos executáveis de qualquer maneira. Vários sistemas têm utilitários pré-POSIX em
/bin
//usr/bin
e têm utilitários POSIX em outro lugar (como no Solaris 10 onde/bin/sh
está um Bourne shell e o POSIX está em/usr/xpg4/bin
; Solaris 11 o substituiu por ksh93 que é mais compatível com POSIX, mas a maioria dos outros ferramentas/bin
ainda são antigas não-POSIX). Alguns sistemas não são POSIX, mas possuem um modo/emulação POSIX. Tudo o que o POSIX exige é que haja um ambiente documentado no qual um sistema se comporte POSIXly.Veja Windows+Cygwin por exemplo. Na verdade, com o Windows+Cygwin, o she-bang é respeitado quando um script é invocado por um aplicativo cygwin, mas não por um aplicativo nativo do Windows.
Portanto, mesmo que o POSIX tenha especificado o mecanismo shebang, ele não poderá ser usado para escrever scripts POSIX /
sh
/sed
... marcador).awk
sed
awk
Agora, o fato de não ser especificado não significa que você não pode usá-lo (bem, ele diz que você não deve começar com a primeira linha
#!
se espera que seja apenas um comentário regular e não um she-bang), mas que POSIX não lhe dá nenhuma garantia se você fizer isso.Na minha experiência, usar shebangs lhe dá mais garantia de portabilidade do que usar a maneira POSIX de escrever scripts de shell: deixe de fora o she-bang, escreva o script na
sh
sintaxe POSIX e espere que o que quer que invoque o script invoque um POSIX compatívelsh
com ele, que é tudo bem se você souber que o script será invocado no ambiente certo pela ferramenta certa, mas não de outra forma.Você pode ter que fazer coisas como:
Se você quiser ser portátil para Windows + Cygwin, talvez seja necessário nomear seu arquivo com uma extensão
.bat
ou e usar algum truque semelhante para ou invocar o cygwin no mesmo arquivo..ps1
cmd.exe
powershell.exe
sh
Você não está olhando profundamente o suficiente.
Na década de 1980, esse mecanismo não era padronizado de fato. Embora Dennis Ritchie a tenha implementado, essa implementação não chegou ao público no lado da AT&T do universo. Foi efetivamente apenas publicamente disponível e conhecido no BSD; com scripts de shell executáveis não disponíveis no AT&T Unix. Assim, não era razoável padronizá-lo. O estado de coisas é exemplificado por este doco contemporâneo, um dos muitos:
— Stephen Frede (1988). "Programação no System X Versão Y". Boletim Australiano do Grupo de Usuários de Sistemas Unix . Volume 9. Número 4. p. 111.Um ponto importante aqui é que você está olhando para shells, enquanto a existência de scripts de shell executáveis é, na verdade, uma questão de
exec…()
funções. O que os shells fazem inclui os precursores do mecanismo de script executável, ainda encontrado em alguns shells até hoje (e também hoje obrigatório para oexec…p()
subconjunto de funções), e é um pouco enganoso. O que o padrão precisa abordar a esse respeito é comoexec…()
um script interpretado funciona e, no momento em que o POSIX foi originalmente criado , ele simplesmente não funcionava em grande parte do espectro de sistemas operacionais de destino .Uma questão secundária é por que isso não foi padronizado desde então, especialmente porque o mecanismo de número mágico para intérpretes de script atingiu o público no lado da AT&T do universo e foi documentado
—exec…()
na Definição de Interface do Sistema 5 , na virada da década de 1990 :exec
. Definição da Interface do System V . Volume 1. 1991.Infelizmente, o comportamento permanece hoje quase tão divergente quanto na década de 1980 e não há um comportamento verdadeiramente comum para padronizar. Alguns Unices (famosos HP-UX e FreeBSD, por exemplo) não suportam scripts como intérpretes de scripts. Se a primeira linha é um, dois ou muitos elementos separados por espaços em branco varia entre MacOS (e versões do FreeBSD anteriores a 2005) e outros. O comprimento máximo do caminho suportado varia.
␀
e caracteres fora do conjunto de caracteres de nome de arquivo portátil POSIX são complicados, assim como espaços em branco iniciais e finais. O que os argumentos 0, 1 e 2 acabam sendo também é complicado, com variação significativa entre os sistemas. Alguns atualmente em conformidade com POSIX, mas não-Os sistemas Unix ainda não suportam nenhum mecanismo desse tipo, e sua obrigatoriedade os converteria em não serem mais compatíveis com POSIX.Leitura adicional
script
. Manual de Informações Diversas do NetBSD . 2005-05-06.Conforme observado por algumas das outras respostas, as implementações variam. Isso torna difícil padronizar e preservar a compatibilidade com os scripts existentes. Isso é verdade mesmo para sistemas POSIX modernos. Por exemplo, o Linux não tokeniza totalmente a linha shebang por espaços. O macOS não permite que o interpretador de scripts seja outro script.
Veja também http://en.wikipedia.org/wiki/Shebang_(Unix)#Portability