É um sub-shell a mesma coisa que um shell filho

11

Existem dois nomes: um subshell e um child-shell .

Sim, um processo filho será iniciado por qualquer um destes:

sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat

São todos equivalentes e compartilham o mesmo nome? Todos compartilham as mesmas propriedades?

POSIX tem essa definição :

A shell execution environment consists of ....

Mas o último parágrafo do link acima tem isto:

A subshell environment shall be created as a duplicate of the shell environment, except that signal traps that are not being ignored shall be set to the default action.

E especialmente:

Command substitution, commands that are grouped with parentheses, and asynchronous lists shall be executed in a subshell environment. Additionally, each command of a multi-command pipeline is in a subshell environment; ....

O sh -c 'echo "Hello"' não está incluído lá, isso também deve ser chamado de subshell?

    
por Gilles 11.02.2016 / 23:06

2 respostas

12

Um subshell duplica o shell existente. Tem as mesmas variáveis¹, as mesmas funções, as mesmas opções, etc. Sob o capô, um subshell é criado com o fork chamada do sistema²; o processo filho continua a fazer o que se espera dele enquanto o pai espera (por exemplo, $(…) ) ou continua sua vida (por exemplo, … & ) ou faz o que é esperado dele (por exemplo, … | … ).

sh -c … não cria um subshell. Ele lança outro programa. Esse programa é uma concha, mas isso é apenas uma coincidência. O programa pode até ser um shell diferente (por exemplo, se você executar sh -c … do bash e sh for traço), ou seja, um programa completamente diferente que por acaso tenha semelhanças significativas em seu comportamento. Sob o capô, lançar um comando externo ( sh ou qualquer outro) chama a chamada de sistema fork e, em seguida, a execve chamada do sistema para substituir o programa shell no subprocesso por outro programa (aqui sh ).

¹ Incluindo $$ , mas excluindo algumas variáveis específicas do shell, como bash e mksh BASHPID .
² Pelo menos, essa é a implementação tradicional e usual. Os reservatórios podem otimizar o garfo, caso contrário, podem imitar o comportamento.

Páginas de manual relevantes: fork (2) , execve (2) .

    
por 12.02.2016 / 01:28
1

Um ambiente de sub-shell não precisa viver em um processo separado, apenas precisa duplicar o ambiente de execução atual. Em ksh93 isso é feito por um mecanismo virtual sub-shell que não chama fork() . Isso torna o ksh93 muito rápido em plataformas arcaicas como Win-DOS , já que Win-DOS é extremamente lento em bifurcações.

sh -c cmd no outro lado cria um novo processo com o shell padrão que não precisa ser o mesmo que o seu shell interativo atual.

Mesmo quando sh e seu shell atual são idênticos, isso não duplica o ambiente de execução e, portanto, não cria um sub-shell .

    
por 12.02.2016 / 11:48