Qual é a diferença entre $ (stuff) e `stuff`?


265

Existem duas sintaxes para substituição de comando: com parênteses em dólar e com reticulares. Em execução top -p $(pidof init)e top -p `pidof init`dá a mesma saída. Existem duas maneiras de fazer a mesma coisa ou existem diferenças?


18
Veja também: BashFAQ / 082 .
Dennis Williamson

43
Por um segundo, pensei que fosse uma pergunta sobre jQuery.
David Murdoch

O resultado pode depender do shell - alguns suportam ambos.
Artdanil

Respostas:


360

As citações de estilo antigo ` `tratam barras invertidas e aninhadas um pouco diferentes. O novo estilo $()interpreta tudo no meio ( )como um comando.

echo $(uname | $(echo cat))
Linux

echo `uname | `echo cat``
bash: command substitution: line 2: syntax error: unexpected end of file
echo cat

funciona se as aspas aninhadas forem escapadas:

echo `uname | \`echo cat\``
Linux

barra invertida divertida:

echo $(echo '\\')
\\

echo `echo '\\'`
\

O novo estilo $()se aplica a todos os shells compatíveis com POSIX .
Como mouviciel apontou, o estilo antigo ` `pode ser necessário para as conchas mais antigas.

Além do ponto de vista técnico, o estilo antigo ` `também tem uma desvantagem visual:

  • Difícil perceber: I like $(program) better than `program`
  • Facilmente confundido com uma única citação: '`'`''`''`'`''`'
  • Não é tão fácil de digitar (talvez nem no layout padrão do teclado)

(e o SE usa ` `para fins próprios, foi difícil escrever esta resposta :)


10
A única coisa que eu gostaria de acrescentar, é que eu chamo de '(' a parêntese, não um suporte (que é '[').
Kendall Helmstetter Gelner

@Kendall: e aqui eu pensei '{' foi o suporte esquerdo durante todos esses anos ...
Samb

5
@Sam: { }é geralmente chamado de "chaves" ou "chaves" en.wikipedia.org/wiki/Braces_(punctuation)#Braces
Jørn Schou-Rode

2
Também me refiro a '{' como chaves. Embora pareça estranho, você precisa adicionar o qualificador "curly" se você chamar as outras coisas de colchetes ... Acho que é só porque elas realmente se enrolam.
Kendall Helmstetter Gelner

1
@slim Eu não sei nos teclados dos EUA / Reino Unido, mas nos teclados espanhóis `é uma chave morta, então eu tenho que digitar um backtick duplo (algo que geralmente esqueço que posso fazer) ou backtick e espaço, o que é um dor.
precisa saber é o seguinte

41

A diferença óbvia que observo é que você não pode aninhar backticks enquanto pode aninhar $(). Talvez ambos existam por motivos legados. Da mesma forma, os comandos .e sourcesão sinônimos.


10
Algumas conchas derivadas de Bourne não reconhecem source. Dash é um exemplo.
Dennis Williamson

14
Isso não é verdade. Você pode aninhar backtick para qualquer nível, apenas mais dolorosamente. Note-se que tanto $(...)e `...`são padrão (o último sendo preterido), enquanto .é padrão, mas nãosource
Stéphane Chazelas

3
Correção, somente (t)csheles não podem ser aninhados. (t)cshnão suporte $(...)embora. Eles suportam source(e não .) embora.
Stéphane Chazelas

28

$()não funciona com shell Bourne antigo. Mas faz anos décadas desde que trabalhei com a velha concha Bourne.


Velho como nos anos 70 e início dos 80, correto?
Christopher

6

Outra observação: $()usará mais recursos do sistema do que backticks, mas é um pouco mais rápido.

No domínio do script de shell do Unix , Randal K. Michael fez um teste em um capítulo chamado "24 maneiras de processar um arquivo linha por linha".


2
Esta afirmação é um absurdo. Não há razão para que seja mais rápido, pois está apenas usando uma notação diferente para o analisador.
schily

@ Schily: Talvez, apenas cite o livro, você pode lê-lo para mais detalhes.
cuonglm

3
Eu tenderia a concordar com @schily ... por que seriam necessários mais recursos?
Curinga

2
@ Wildcard, suponho que é porque $()torna o seu script um byte maior do que se fosse usado `(supondo que você não os aninhe e não use barras invertidas). Quanto ao que seria mais rápido de analisar, isso variaria entre as conchas e seria irrelevante e desprezível se comparado ao custo de criação de um tubo e bifurcação do processo que implica substituição de comando.
Stéphane Chazelas

5

Para adicionar ao que os outros disseram aqui, você pode usar os backticks para simular comentários embutidos:

echo foo `# I'm a comment!` bar

A saída é: foo bar.

Consulte o seguinte para obter mais informações: https://stackoverflow.com/a/12797512 (Observe também os comentários abaixo dessa postagem.)


1

A $()sintaxe não funcionará com o antigo shell bourne.
Com shells mais novos ` `e $()equivalentes, $()é muito mais conveniente quando você precisa aninhar vários comandos.

Por exemplo :

echo $(basename $(dirname $(dirname /var/adm/sw/save )))

é mais fácil digitar e depurar do que:

echo `basename \`dirname \\\`dirname /var/adm/sw/save \\\`\``

1
Embora $ () possa parecer bom, é uma dor de cabeça ao implementar um analisador relacionado, pois requer um analisador recursivo duplo.
schily

6
@schily Por outro lado, o que seria uma concha sem um bom analisador.
Emmanuel

1
O problema é que você precisa saber onde a sequência termina antes de chamar o analisador. Isso é relativamente simples com os backticks, mas é difícil com colchetes, pois eles são usados ​​para vários fins no shell. Portanto, você precisa do analisador duas vezes e de uma maneira que não exista no Bourne Shell.
schily
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.