As funções são executadas como subprocessos no Bash?


28

No Advanced Bash-Scripting Guide , no exemplo 27-4 , 7ª linha da parte inferior, li o seguinte:

Uma função é executada como um subprocesso.

Fiz um teste no Bash e parece que a declaração acima está errada.

As pesquisas neste site, Bash Man e meu mecanismo de pesquisa não trazem nenhuma luz.

Você tem a resposta e gostaria de explicar?


12
Como observado, esse guia é enganoso ao extremo. Eu recomendo o Guia Wooledge Bash .
Curinga

Respostas:


36

O Advanced Bash-Scripting Guide nem sempre é confiável e seus scripts de exemplo contêm práticas desatualizadas, como o uso de backticks efetivamente preteridos para substituição de comandos, ou seja, em `command`vez de $(command).

Nesse caso em particular, é flagrantemente incorreto.

A seção Funções do Shell no manual Bash (canônico) afirma definitivamente que

As funções do shell são executadas no contexto atual do shell; nenhum novo processo é criado para interpretá-los.


10
"O Advanced Bash-Scripting Guide geralmente não é confiável" . Verdade.
precisa saber é o seguinte

1
Você pode dar referências para apoiar sua primeira frase?
Will Vousden

5
@WillVousden, como seria uma referência aqui? Um monte de exemplos de deficiências técnicas do guia? Um documento em que especialistas da comunidade do bash observaram anteriormente que não é confiável? Ajudaria se um membro do stackoverflow com um distintivo dourado no bash concordasse em um comentário? : p
kojiro 24/08

3
@ WillVousden Eu não acho que o que você quer exista de uma forma confiável. Mendel Cooper atualizou e corrigiu problemas com o guia no passado, mas não há rastreador de erros público ou lista de erratas. (Talvez essa seja a declaração mais condenatória que posso fazer.) Portanto, quando encontramos uma falha (percebida ou real), tudo o que podemos fazer é enviar um e-mail ao autor e esperar o melhor.
Kojiro # 24/16

3
@WillVousden, ... se você quiser um histórico de quanto tempo o consenso no canal #breen freenode tem sido de que o ABS deve ser evitado, consulte wooledge.org/~greybot/meta/abs - o segundo campo em cada linha é o carimbo de data e hora e o primeiro é o nome de usuário; Espero que seja suficiente a afirmação de que os nomes de usuário em questão são indivíduos muito respeitados.
Charles Duffy

32

As funções de chaves curvadas serão executadas dentro do processo do shell de chamada, a menos que precisem de seu próprio subshell, que é:

  • quando você os executa em segundo plano com &
  • quando você os executa como um link em um pipeline

Redirecionamentos ou env extra. variáveis ​​não forçam um novo subshell:

hw(){
    echo hello world from $BASHPID
    echo var=$var
} 
var=42 hw >&2
echo $BASHPID  #unexports var=42 and restores stdout here

Se você definir a função entre parênteses, em vez de curvas:

hw()(
  echo hello world from $BASHPID
)
hw 
echo $BASHPID

sempre será executado em um novo processo.

A substituição de comandos $()também sempre cria processos no bash (mas não no ksh se você executar os componentes internos dentro dele).


Eu não sabia que f() (...)é permitido. Existem outras definições além de {...}e (...)? No Bash, ainda não gosto de outras pessoas.
Tomasz

1
@tomas Você pode usar a function hw { echo hello world; } sintaxe (sem necessidade de ()se digitar functione você pode especificar redirecionamentos logo após a final }ou )como no hw(){ echo error; } >&2que é sobre ele..
PSkocik

2
Esta é a resposta em que pensei imediatamente e é absolutamente correta. Deve ser votado como a resposta correta. f()(...)sempre execute um próprio shell, enquanto f(){...}não.
Rexkogitans

11
As funções bash do NB aceitam qualquer comando composto, assim foo() [[ x = x ]]como uma definição de função válida também. No entanto, se você olhar para a função, type fooverá que ainda é um açúcar sintático foo() { [[ x = x ]]; }. O mesmo vale para as funções do subshell: bar() ( : )torna - se bar() { ( : ); }.
Kojiro #

1
@kojiro nice +1. não sabia que
PSkocik

9

O comando em questão desse exemplo se parece com:

echo ${arrayZ[@]/%e/$(replacement)}

O exemplo posterior afirma:

#    $( ... ) is command substitution.
#    A function runs as a sub-process.

Sendo caridoso com o ABS Guide, o que eles aparentemente pretendiam escrever é que a função é executada dentro de uma substituição de comando e o comando dentro de uma substituição de comando é executado em uma subshell .


Isso é muito enganador. Obrigado pela sua interpretação.
Tomasz

5
@tomas "muito enganadores". Sim muito. Em contraste com o Guia do ABS, o Greg's Wiki é uma excelente fonte de informações avançadas sobre o bash.
precisa saber é o seguinte

1
Felicidades. Qual sua opinião sobre este: wiki.bash-hackers.org/start ?
Tomasz

@tomas Não tenho conhecimento em primeira mão desse.
precisa saber é o seguinte

2
@tomas, ... minha opinião quanto ao wiki do bash-hackers é que é uma excelente fonte. Eu não passei por isso de maneira tão abrangente quanto eu tenho no wiki do Wooledge, mas tende a ser exato e preciso.
Charles Duffy
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.