Na página Linguagem de Comando do Shell 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.
exec()
função. Portanto, checar contra várias conchas realmente não diz como é portátil.Respostas:
Penso principalmente porque:
o comportamento varia muito entre a implementação. Consulte https://www.in-ulm.de/~mascheck/various/shebang/ para obter todos os detalhes.
No entanto, agora ele pode especificar um subconjunto mínimo da maioria das implementações do tipo Unix: como
#! *[^ ]+( +[^ ]+)?\n
(com apenas caracteres do conjunto de caracteres portátil nomeado nessas uma ou duas palavras) em que 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 for setuid / setgid e a implementação definida se o caminho do interpretador ou o caminho do script é passadoargv[0]
para o intérprete.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 possuem utilitários POSIX em outro lugar (como no Solaris 10, onde/bin/sh
há um shell Bourne e o POSIX/usr/xpg4/bin
, o Solaris 11 o substituiu pelo ksh93, que é mais compatível com POSIX, mas a maioria dos outros as ferramentas/bin
ainda são antigas que não são POSIX). Alguns sistemas não são POSIX, mas têm um modo / emulação POSIX. Tudo o que o POSIX exige é que exista um ambiente documentado no qual um sistema se comporte no POSIX.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 especifique o mecanismo shebang, ele não poderá ser usado para escrever scripts POSIX
sh
/sed
/awk
... (observe também que o mecanismo shebang não pode ser usado para gravar scripts confiáveissed
/awk
, pois não permite a passagem de um final de opção marcador).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 ter a primeira linha
#!
se você espera que seja apenas um comentário regular e não um golpe de mulher), mas esse POSIX não oferece garantia se você o fizer.Na minha experiência, o uso de shebangs oferece mais garantia de portabilidade do que a maneira de escrever scripts de shell do POSIX: deixe de lado, escreva o script na
sh
sintaxe do POSIX e espere que o que chama o script, seja compatível com o POSIXsh
, o que é Tudo bem se você souber que o script será chamado no ambiente certo pela ferramenta certa, mas não o contrário.Você pode ter que fazer coisas como:
Se você deseja ser portável para Windows + Cygwin, pode ser necessário nomear seu arquivo com uma extensão
.bat
ou.ps1
e usar algum truque semelhante paracmd.exe
oupowershell.exe
invocar o cygwinsh
no mesmo arquivo.fonte
sh
, ele não precisaria de uma linha hashbang, pois seria executado pelo POSIXsh
.execlp
ouexecvp
foi usado, certo? Se eu fosse usarexecve
, isso resultaria em ENOEXEC?Você não está olhando o suficiente.
Na década de 1980, esse mecanismo não era de fato padronizado. Embora Dennis Ritchie a tivesse implementado, essa implementação não havia atingido o público no lado AT&T do universo. Ele era efetivamente disponível apenas publicamente e conhecido no BSD; com scripts de shell executáveis não disponíveis no AT&T Unix. Portanto, não era razoável padronizá-lo. O estado de coisas é exemplificado por este doco contemporâneo, um de muitos:
- Stephen Frede (1988). "Programando no System X Release Y". Boletim informativo do grupo de usuários do Australian Unix Systems . Volume 9. Número 4. p. 111Um ponto importante aqui é que você está observando shells, enquanto a existência de scripts de shell executáveis é realmente uma questão de
exec…()
função. O que os shells fazem inclui os precursores do mecanismo de script executável, ainda hoje encontrado em alguns shells (e também hoje em dia é obrigatório para oexec…p()
subconjunto de funções), e é um tanto enganador. O que o padrão precisa abordar a esse respeito é como,exec…()
em um script interpretado, funciona e, no momento em que o POSIX foi criado, ele simplesmente não funcionava em primeiro lugar em grande parte do espectro dos sistemas operacionais de destino .Uma pergunta subordinado é por que isso não foi padronizado, já que, sobretudo porque o mecanismo número mágico para intérpretes de script tinha alcançado o público no lado AT & T do universo e foi documentado para
-exec…()
na Definição do Sistema 5 de interface , na virada da década de 1990 :exec
. System V Interface Definition . Volume 1. 1991.Infelizmente, o comportamento permanece hoje quase tão divergente quanto na década de 1980 e não existe um comportamento verdadeiramente comum para padronizar. Alguns Unices (famosos HP-UX e FreeBSD, por exemplo) não suportam scripts como intérpretes. Se a primeira linha é um, dois ou muitos elementos separados por espaço em branco varia entre o MacOS (e versões do FreeBSD antes de 2005) e outros. O comprimento máximo do caminho suportado varia.
␀
e os caracteres fora do conjunto de caracteres de nome de arquivo portátil POSIX são complicados, assim como os espaços em branco à esquerda e à direita. O argumento do 0º, 1º e 2º também é complicado, com variação significativa entre os sistemas. Alguns atualmente em conformidade com POSIX, mas nãoOs sistemas -Unix ainda não suportam nenhum mecanismo desse tipo e exigir que os convertesse para não serem mais compatíveis com POSIX.Leitura adicional
script
. Manual de Informações Diversas do NetBSD . 06-05-2005.fonte
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 os 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 script seja outro script.
Veja também http://en.wikipedia.org/wiki/Shebang_(Unix)#Portability
fonte