Eu li o seguinte nesta pergunta :
O bash suporta um switch --posix, que o torna mais compatível com POSIX. Ele também tenta imitar o POSIX se invocado como sh .
A citação acima assume que /bin/sh
é um link que aponta para /bin/bash
.
Mas não entendo bem o que se entende por "invocado como sh" .
Diga que eu tenho o seguinte script chamado "script.sh":
#!/bin/bash
echo "Hello World"
Diga-me, em cada um dos seguintes casos, se o script será executado no bash
modo normal ou no modo POSIX (suponha que eu executei os seguintes comandos em um terminal em execução bash
):
sh script.sh
bash script.sh
./script.sh
Agora diga que eu tenho o seguinte script chamado "script.sh" (que é como o script acima, mas sem o shebang):
echo "Hello World"
Diga-me, em cada um dos seguintes casos, se o script será executado no bash
modo normal ou no modo POSIX (suponha que eu executei os seguintes comandos em um terminal em execução bash
):
sh script2.sh
bash script2.sh
./script2.sh
Respostas:
Apenas os casos 1 e 4 serão executados no modo POSIX (assumindo que o
sh
bash e não alguma outra implementação do sh). Qualquer caso que chame explicitamentebash
sem--posix
, não será, seja do shebang ou não. Qualquer caso que ligue explicitamentesh
será. O shebang é usado apenas quando nenhum shell já foi explicitamente iniciado para o script.Caso 6, se o seu terminal estiver em execução
bash
, não será executado no modo POSIX e o Bash o chamará usando-se. Se o seu terminal estivesse executando o zsh, o caso 6 também seria executado no modo POSIX. O POSIX é ambíguo sobre exatamente o que deveria acontecer nesse caso , e Bash e zsh fizeram escolhas diferentes lá. O Bash chama o script usando-se, enquanto o zsh usash
(o que quer que seja). Outras conchas também variam nesse ponto.Uma maneira simples de dizer em que modo você está é criar o corpo do script:
que falhará com um erro no modo POSIX , mas fornecerá instruções de uso para
kill
fora dele. Essa é uma distinção fácil e funciona através de uma longa variedade de versões do Bash, que remontam até onde você provavelmente encontrará.fonte
bash
a execução no modo POSIX, como aPOSIXLY_CORRECT
variável de ambiente ouSHELLOPTS=posix
.[ -o posix ]
é uma maneira mais óbvia de verificar se você está executando no modo posix no bash (não em outros shells (exceto yash), para que não queira fazer isso em umsh
script).POSIXLY_CORRECT=1 bash -c '[ -o posix ] && echo yes'
saídasyes
`O "invocado como" refere-se a qualquer coisa que o processo que inicia o Bash coloca em seu argumento de linha de comando "zeroth"
argv[0]
,.Quando um programa é iniciado com os
exec*()
syscalls , eles realmente não conhecem o nome do arquivo binário que contém o programa, mas o processo de chamada é livre para colocar o que quiser lá. Normalmente, é claro, o nome é retirado do sistema de arquivos, portanto, se você executar/bin/sh
, é isso que é colocado lá. E se/bin/sh
for o Bash, ele não precisa ser um link simbólico, pode ser um link físico ou apenas outra cópia do programa shell.Como um exemplo de configuração do "nome do programa", o
exec
comando do Bash pode definir o argumento zeroth com a-a
opção (Poderíamos fazer o mesmo com Perl, ou diretamente com C, etc.)Aqui
myname
está um programa C simples que apenas imprime seu argumento zero, o nome que ele próprio vê:Fonte:
Mas, para responder às perguntas numeradas ...
(1 e 4) a execução
sh somescript
executará o quesh
estiver no seuPATH
, provavelmente,/bin/sh
mas possivelmente algo como/usr/xpg4/bin/sh
.sh
.sh
, mas será executado no modo "Compatível com SH", que visa ser compatível com o shell Bourne e é sutilmente diferente do modo compatível com POSIX completo em ambos os shells. .(2 e 5) A corrida
bash somescript
será executada no modo Bash regular (novamente, é claro, depende do que estábash
no seuPATH
.)(3) Aqui, o nome do script é dado diretamente à chamada do sistema no lugar do arquivo do programa. O kernel lê a linha hashbang e a usa para executar o script.
(6) Esse é o complexo. É semelhante a (3), mas a chamada do sistema para iniciar o programa falha (
ENOEXEC (Exec format error)
), pois não há linha hashbang. O que acontece a seguir depende de se o shell que você está executando é em si no modo POSIX. O POSIX requer que um shell compatível com POSIX se comporte de uma maneira específica em resposta aENOEXEC
. No entanto, há alguma margem de manobra em "um comando equivalente a invocar um shell", o que significa que diferentes tipos de conchas fazem coisas diferentes./bin/sh
com o nome do script inserido antes dos outros argumentos como o primeiro argumento da linha de comando. O shell Z, o shell Almquist e o Korn estão (tentando) invocar um shell compatível com POSIX com a suposição de que o/bin/sh
programa é um.fonte
int main(int argc, char *argv[]){printf("I am %s\n",argv[0]);}
O shell executado é tanto o chamado na linha de comando ou a do shebang (se a linha de comando não especificá-lo).
Portanto, as versões 1 e 4 serão executadas com
sh
, 2 e 5 com bash e 6 podem não ser executadas se você estiver usando sh (e alguns outros) interativamente. Bash inicia o script. Ksh também. Zsh começa como sh.Somente aqueles iniciados como
sh
usarão a opção posix se o bash estiver vinculado/bin/sh
.Adicione esta linha ao seu script para detectar se alguma versão do bash ksh ou zsh está executando:
fonte