Chamada de função de script: função vs $(função)

Chamada de função de script: função vs $(função)

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 functioncalle$(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 numberpelo 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 Linuxno 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 Linuxe 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 doSomethinge defina uma variável numbercomo 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 stdoutestá sendo recuperado) e, portanto, não é possível modificar a variável numberusada 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.

informação relacionada