Executando um script de shell quando “/ bin / sh” aponta para “/ bin / bash”

10

Eu li o seguinte nesta pergunta :

bash supports a --posix switch, which makes it more POSIX-compliant. It also tries to mimic POSIX if invoked as sh.

A citação acima assume que /bin/sh é um link que aponta para /bin/bash .

Mas eu não entendo muito bem o que significa "invocado como sh" .

Digamos que eu tenha o script a seguir chamado "script.sh":

#!/bin/bash
echo "Hello World"

Por favor, diga-me em cada um dos casos a seguir se o script será executado no modo bash normal ou no modo POSIX (suponha que executei os seguintes comandos em um terminal que está executando bash ):

  1. sh script.sh
  2. bash script.sh
  3. ./script.sh

Agora diga que eu tenho o seguinte script que é chamado "script.sh" (que é como o script acima, mas sem o shebang):

echo "Hello World"

Por favor, diga-me em cada um dos casos a seguir se o script será executado no modo bash normal ou no modo POSIX (suponha que executei os seguintes comandos em um terminal que está executando bash ):

  1. sh script2.sh
  2. bash script2.sh
  3. ./script2.sh
por user269904 10.01.2018 / 22:24

3 respostas

18

Apenas casos 1 & 4 será executado no modo POSIX (assumindo que sh é bash e não alguma outra implementação de sh). Qualquer caso que chame explicitamente bash sem --posix não será, seja da shebang ou não. Qualquer caso que chame explicitamente sh será. O shebang é usado apenas quando nenhum shell foi iniciado explicitamente para o script.

Caso 6, se o seu terminal estiver executando bash , não será executado no modo POSIX e Bash irá invocá-lo usando-se. Se o seu terminal estava executando o zsh, o caso 6 também será executado no modo POSIX. POSIX é ambíguo sobre exatamente o que deveria acontecer naquele caso , e Bash e zsh fizeram escolhas diferentes lá. Bash invoca o script usando a si mesmo, enquanto o zsh usa sh (o que quer que isso aconteça). Outras conchas também variam nesse ponto.

Uma maneira simples de saber em que modo você está é criar seu corpo de script:

kill -SIGHUP

que falha com um erro no modo POSIX , mas dê instruções de uso para kill fora dele. Esta é uma distinção fácil e funciona através de uma longa gama de versões do Bash, indo tão longe quanto é provável encontrar.

    
por 10.01.2018 / 22:36
8

O "invocado como" refere-se ao que quer que seja 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 conheça 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, então se você executar /bin/sh , é o que é colocado lá. E se /bin/sh é Bash, não precisa ser um link simbólico, pode ser um link físico ou apenas outra cópia do programa shell.

Como exemplo de configuração do "nome do programa", o comando exec do Bash pode definir o argumento zeroth com a opção -a . (Nós poderíamos fazer o mesmo com o Perl, ou diretamente com o C, etc.)

Aqui, myname é um programa C simples que apenas imprime seu argumento zeroth, o nome que ele vê:

$ ./myname 
I am ./myname
$ (exec -a something ./myname )
I am something
$ mv ./myname somename
$ ln -s somename othername
$ ./somename 
I am ./somename
$ ./othername
I am ./othername

Fonte:

#include <stdio.h>
int main(int argc, char *argv[]) {
    printf("I am %s\n", argv[0]);
    return 0;
}

Mas, para responder às perguntas numeradas ...

(1 & 4) executando sh somescript será executado em sh do seu PATH , provavelmente /bin/sh , mas possivelmente algo como /usr/xpg4/bin/sh .

  • Se for Bash, ele será executado no modo POSIX, já que ele verá o nome sh .
  • Se for o shell Z ou o shell Korn, ele também verá o nome sh , mas será executado no modo "SH compatible", que é compatível com o shell Bourne e é sutilmente diferente do POSIX. modo em ambas as conchas.
  • Pode ser a casca de Almquist, uma casca Bourne real ou qualquer outra coisa, é claro.

(2 & 5) A execução de bash somescript será executada no modo normal de Bash (novamente, é claro que depende de qual bash no seu PATH ).

(3) Aqui, o nome do script é fornecido diretamente para a chamada do sistema no lugar do arquivo do programa. O kernel lê a linha hashbang e a usa para executar o script.

(6) Este é o complexo. É semelhante a (3), mas a chamada do sistema para iniciar o programa falha ( ENOEXEC (Exec format error) ), uma vez que não há linha de hashbang. O que acontece a seguir depende se o shell que você está executando é em si no modo POSIX. POSIX requer que um shell em conformidade com POSIX se comporte de maneira específica em resposta a ENOEXEC . No entanto, há alguma margem de manobra em "um comando equivalente a ter um shell chamado", o que significa que diferentes shells fazem coisas diferentes.

  • O shell Bourne Again é executado novamente no mesmo modo com o nome do script como seu primeiro argumento de linha de comando. Em seu modo compatível com POSIX, é claro que ele está executando em seu modo POSIX-conformant, obedecendo assim ao requisito POSIX de invocar um shell em conformidade com POSIX.
  • O shell Z, o shell Almquist e o shell Korn executam /bin/sh com o nome do script inserido antes dos outros argumentos como seu primeiro argumento de linha de comando. O shell Z, o shell Almquist e o shell Korn estão (tentando) invocar um shell em conformidade com POSIX por meio de supor que o programa /bin/sh é um.
por 10.01.2018 / 22:41
4

O shell executado é aquele chamado na linha de comando ou o da shebang (se a linha de comando não especificar).

Portanto, as versões 1 e 4 serão executadas com sh , 2 e 5 com bash e 6 não serão 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 a /bin/sh .

Adicione esta linha ao seu script para detectar se alguma versão do bash ksh ou zsh está rodando:

echo "Hello World $BASH_VERSION $KSH_VERSION $ZSH_VERSION"
    
por 10.01.2018 / 22:50