![Chamada de função de script: função vs $(função)](https://rvso.com/image/192236/Chamada%20de%20fun%C3%A7%C3%A3o%20de%20script%3A%20fun%C3%A7%C3%A3o%20vs%20%24(fun%C3%A7%C3%A3o).png)
Tomando como referência o código a seguir para simplificar
#!/bin/bash
number=7
function doSomething() {
number=8
}
doSomething
echo "$number"
Ele imprime 8
.
Mas com:
#!/bin/bash
number=7
function doSomething() {
number=8
}
$(doSomething)
echo "$number"
Ele imprime 7
.
Tenho as seguintes perguntas:
- O que são asnomes técnicospara cada um?, quero dizer
functioncall
e$(functioncall)
- Como funciona cada abordagem? Parece que o primeiro considera (afeta) as variáveis fora da própria função, o último não
- Quando é obrigatório usar uma abordagem em vez de outra (principalmente sobre questões de desempenho - é claro - se houver), se houver outros motivos, eles serão bem-vindos.
Responder1
Você está vivenciando as sutilezas da Substituição de Comando.
A chamada
doSomething
é uma chamada de função simples. Ele executa a função, praticamente como se você tivesse copiado e colado os comandos da função no local onde você a chamou. Portanto, ele substitui a variável number
pelo novo valor 8
.
A chamada
$(doSomething)
por outro lado é umsubstituição de comando. Destina-se a executar a função eretornar qualquer que seja a função impressa stdout
. Geralmente não é usado "autônomo", mas em atribuições de variáveis, por exemplo,
os_type=$(uname)
Isso executará o comando uname
, que em um sistema Linux seria impresso Linux
no console e armazenaria seu resultado na variável shell os_type
. Portanto, não faz sentido usar uma substituição de comando por um comando ou função que não produza nada, como o seu arquivo doSomething
. Na verdade, como a substituição $(doSomething)
é basicamente um espaço reservado para a saída de doSomething
, a única razão pela qual você não recebe um erro de script é que sua função não produz nada. Você tinha declarado, por exemplo,
$(uname)
em vez de
$(doSomething)
seu shell teria tentado executar o comando Linux
e gerado um
Linux: No such file or directory
erro (1) .
O ponto chave para entender o efeito que você observa é que em uma substituição de comando,o comando é executado em um subshell, ou seja, quaisquer alterações feitas nas variáveis não são retropropagadas para o shell onde você executa o script principal. Portanto, embora internamente ele execute os comandos de doSomething
e defina uma variável number
como 8
, ele o faz em seu próprio processo de shell que não tem nada a ver com o processo de shell que executa seu script (exceto pelo fato de que ele stdout
está sendo recuperado) e, portanto, não é possível modificar a variável number
usada no script principal.
Para ler mais, você pode querer dar uma olhada em
aqui neste site, ou
para obter mais visão geral.
(1) Por outro lado, isso significa que você pode usar uma substituição de comando para executar um comando cujo nome você não conhece no momento em que escreve o script, mas que pode descobrir executando outro comando que você conhece.