O que significa no shell quando colocamos um comando entre o cifrão e parênteses: $ (comando)

110

Eu só quero entender a seguinte linha de código no shell. É usado para obter o diretório de trabalho atual. Estou ciente de que $(variable)name retorna o valor dentro do nome da variável, mas o que $(command)deveria retornar? Ele retorna o valor após a execução do comando? Nesse caso, podemos usar `para executar o comando.

CWD="$(cd "$(dirname $0)"; pwd)"

A mesma saída pode ser obtida na linha de código a seguir também em versões diferentes do shell

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Não consigo entender o significado de $(cd..e $(dirname.

Alguém poderia me ajudar a descobrir como esse comando é executado?

KItis
fonte
1
E aqui está uma pergunta sobre as vantagens / desvantagens de $()vs ``.: stackoverflow.com/questions/9449778/…
Nenhum

Respostas:

115

O uso de $semelhantes ${HOME}fornece o valor de HOME. O uso de $semelhantes $(echo foo)significa executar o que quer que esteja entre parênteses em uma subcamada e retornar isso como o valor. No meu exemplo, você obteria, uma foovez echoque escreverá foopara o padrão

Eric Urban
fonte
37
Sim; $(...)é a melhor maneira de escrever um comando do que tentar usar aspas. Considere escrever: gcclib=$(dirname $(dirname $(which gcc)))/libusando aspas. Mesmo antes de entrar nas dificuldades de fazer isso no Markdown, é mais difícil porque você tem que escapar das crases dos comandos aninhados, ao passo que você não faz com a $(...)notação.
Jonathan Leffler
7
Tecnicamente, $(echo foo)cria uma substituição de comando, não um subshell. A outra resposta atual acerta. Acho que a substituição de comando é executada em um subshell, mais ou menos, mas eles ainda são conceitos diferentes.
trysis
4
@trysis - a substituição do comando definitivamente é executada em um subshell , portanto, vale a pena observá-lo.
Eliran Malka
2
Eu entendo que os crases produzem o mesmo resultado que $ (), mas a diferença é puramente cosmética? há uma razão para usar um em relação ao outro, além de $ () ser mais legível?
Mitchell Tracy
2
"O uso de $ like $ (echo foo) significa executar o que quer que esteja entre parênteses em uma subshell e retornar isso como o valor." ... Isso é confuso, pois este comando $(echo foo)tentará executar o que é retornado dos parênteses, ele executará primeiro e echo foodepois tentará executar o fooque dá um erro
Contador م
21
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Alguém poderia me ajudar a descobrir como esse comando é executado?

Vejamos as diferentes partes do comando. BASH_SOURCEé uma variável de matriz bash contendo nomes de arquivos de origem. Portanto "${BASH_SOURCE[0]}", retornaria o nome do arquivo de script.

dirnameé um utilitário fornecido pelo GNU coreutils que remove o último componente do nome do arquivo. Portanto, se você executar seu script dizendo bash foo, "$( dirname "${BASH_SOURCE[0]}" )"retornará .. Se você disse bash ../foo, ele retornaria ..; por bash /some/path/fooque ia voltar /some/path.

Finalmente, todo o comando "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"obtém o diretório absoluto que contém o script que está sendo invocado.

$(...) permite a substituição do comando, ou seja, permite que a saída de um comando substitua o próprio comando e pode ser aninhado.

Devnull
fonte
1
Desculpe pelo atraso de 3 anos na festa, mas você poderia explicar por que a frase funciona? Você disse que dirnameretorna o caminho do arquivo executado (relativo ou absoluto ao diretório de trabalho atual), cdaltera o pwd para esse diretório e pwdimprime o caminho absoluto do diretório de trabalho atual. Mas por que eles estão unidos &&? E o que acontecerá DIRse cdfalhar?
Christian,
2
@Christian, &&impede que o pwdseja executado se cdfalhar, de forma que DIRficará vazio ao invés de ter um diretório incorreto.
Charles Duffy