Os backticks (ou seja, `cmd`) em * shells foram descontinuados?


118

Eu já vi esse comentário muitas vezes no Unix e Linux, bem como em outros sites que usam o fraseado "backticks foram descontinuados", com relação a shells como Bash & Zsh.

esta afirmação é verdadeira ou falsa?


Consulte Por que as aspas não retornadas em um script de shell me ajudaram cda um diretório para um exemplo de por que a $(...)notação é mais fácil de usar do que as aspas reversas aninhadas.
Jonathan Leffler


11
Pelo menos um Unix, AIX, documentou que os backticks são obsoletos . "Embora a sintaxe da cota retroativa seja aceita pelo ksh, ela é considerada obsoleta pelos padrões do X / Open Portability Guide Issue 4 e POSIX. Esses padrões recomendam que aplicativos portáteis usem a sintaxe $ (command)." ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.osdevice/…
Christopher

Eu tenho uma diferença definida em "GNU bash, versão 3.2.57 (1) -release (x86_64-apple-darwin14)" no mac 10.10: matchingLines=$( grep -n '\$-PARAMETER' ... | ... )funciona, matchingLines= backtick the same stuff backticknão funciona - parece perder a barra invertida em barra invertida. (Não é o meu script ...)
denis

Respostas:


126

Existem dois significados diferentes de "obsoleto".

ser descontinuado: (principalmente de um recurso de software) pode ser usado, mas é considerado obsoleto e deve ser evitado, geralmente por ter sido substituído.

- Novo dicionário americano de Oxford

Por essa definição, os backticks estão obsoletos.

O status preterido também pode indicar que o recurso será removido no futuro.

- Wikipedia

Por essa definição, os backticks não são preteridos.

Ainda suportado:

Citando a especificação de grupo aberto nas linguagens de comando do shell , especificamente a seção "2.6.3 Substituição de comando", pode ser visto que ambas as formas de substituição de comando, backticks ( `..cmd..`) ou dollar parens ( $(..cmd..)) ainda são suportadas na medida em que a especificação é válida.

excerto

A substituição de comando permite que a saída de um comando seja substituída no lugar do próprio nome do comando. A substituição do comando ocorrerá quando o comando estiver entre os seguintes:

          $(command)

          or (backquoted version):

          `command`

O shell deve expandir a substituição do comando executando o comando em um ambiente de subcasca (consulte Ambiente de Execução do Shell) e substituindo a substituição do comando (o texto do comando mais as notas $()anexas ou de volta) pela saída padrão do comando, removendo sequências de um ou mais <newline> caracteres no final da substituição. Os caracteres <newline> incorporados antes do final da saída não devem ser removidos; no entanto, eles podem ser tratados como delimitadores de campo e eliminados durante a divisão de campo, dependendo do valor do IFS e da citação que estiver em vigor. Se a saída contiver bytes nulos, o comportamento não será especificado.

No estilo de substituição de comando entre aspas posteriores, <barra invertida> manterá seu significado literal, exceto quando seguido por: '$', ' \`' ou <barra invertida> . A pesquisa da cotação correspondente deve ser satisfeita pela primeira cotação não escapada sem aspas; durante esta pesquisa, se uma cotação não escapada for encontrada em um comentário do shell, um documento aqui, uma substituição de comando incorporada do $(command)formulário ou uma seqüência de caracteres citada, ocorrerão resultados indefinidos. Uma sequência de aspas simples ou aspas duplas que começa, mas não termina, na `...`sequência " " produz resultados indefinidos.

Com o $(command)formulário, todos os caracteres que seguem o parêntese aberto ao parêntese de fechamento correspondente constituem o comando. Qualquer script de shell válido pode ser usado para comando, exceto um script que consiste apenas em instruções adicionais que produzem resultados não especificados.

Então, por que todos dizem que os backticks foram preteridos?

Como a maioria dos casos de uso deve usar o formulário parens em dólar, em vez de reticulares. (Descontinuado no primeiro sentido acima.) Muitos dos sites mais respeitáveis ​​(incluindo U&L) também costumam dizer isso o tempo todo, por isso são bons conselhos. Este conselho não deve ser confundido com algum plano inexistente para remover o suporte para backticks das cascas.

  • BashFAQ # 082 - Por que $ (...) é preferido em vez de `...` (backticks)?

    excerto

    `...`é a sintaxe herdada exigida apenas pelos bourne-shells mais antigos e não compatíveis com POSIX. Há vários motivos para sempre preferir a $(...)sintaxe:

    ...

  • Wiki Bash Hackers - Sintaxe obsoleta e obsoleta

    excerto

    Essa é a forma mais antiga de substituição de comando, compatível com Bourne . As sintaxes `COMMANDS`e $(COMMANDS)são especificadas pelo POSIX, mas o último é muito preferido, embora o primeiro ainda seja muito prevalente nos scripts. As substituições de comando de novo estilo são amplamente implementadas por todos os shell modernos (e depois por alguns). O único motivo para usar backticks é a compatibilidade com um shell Bourne real (como o Heirloom). As substituições de comandos do backtick requerem escape especial quando aninhadas, e os exemplos encontrados na natureza são citados incorretamente com mais frequência do que não. Veja: Por que $ (...) é preferido em vez de `...` (backticks)? .

  • Fundamentação padrão do POSIX

    excerto

    Devido a esses comportamentos inconsistentes, a variedade de substituição de comando entre aspas não é recomendada para novos aplicativos que aninham substituições de comando ou tentam incorporar scripts complexos.

NOTA: Este terceiro trecho (acima) continua mostrando várias situações em que os backticks simplesmente não funcionam, mas o método mais recente de parens em dólar funciona, começando com o seguinte parágrafo:

Além disso, a sintaxe com aspas posteriores possui restrições históricas no conteúdo do comando incorporado. Embora o formulário "$ ()" mais recente possa processar qualquer tipo de script incorporado válido, o formulário com aspas posteriores não pode manipular alguns scripts válidos que incluem aspas posteriores.

Se você continuar lendo essa seção, as falhas serão destacadas, mostrando como elas falhariam ao usar backticks, mas funcionam usando a notação de parênteses mais recente.

Conclusões

Portanto, é preferível usar parênteses em dólares em vez de reticulares, mas na verdade você não está usando algo que foi tecnicamente "deprecado", pois em "isso deixará de funcionar totalmente em algum momento planejado".

Depois de ler tudo isso, você deve ter certeza de que é fortemente incentivado a usar parênteses em dólar, a menos que exija especificamente compatibilidade com um shell Bourne original não POSIX original.


26
Pela maioria dos significados de obsoleto , eu (e você) diria que os backticks estão obsoletos. É principalmente uma questão de terminologia.
Stéphane Chazelas

4
@StephaneChazelas - Agreed! Continuarei dizendo às pessoas que elas estão obsoletas, mas os backticks não foram oficialmente "obsoletos" no sentido de que serão removidos ativamente da base de código de qualquer shell no futuro próximo. Pelo menos nenhum que eu saiba.
SLM

3
Minha interpretação é que as aspas são suportadas apenas porque estão muito arraigadas no código existente para serem obsoletas formalmente. Eu nunca ouvi um argumento para continuar a usá-los em novo código.
chepner

3
@ slm Sim, eu acho que você conseguiu - eu me afastei e não percebi. Não há quase nenhuma razão para usar essas coisas, exceto que pode ser um pouco mais limpo ao colocar camadas subconjuntos, por isso $( cmd `cmd`)é um pouco menos bagunçado do que $( cmd $(cmd))- é mais fácil de ler. Eu sempre considerei um recurso reprovado no software um oficialmente marcado para remoção pelo upstream - e nunca ouvi falar de algo assim. Eu não ligo - não tenho amor pelo túmulo.
precisa saber é o seguinte

3
Convém adicionar a seguinte citação a partir da lógica padrão do POSIX : Devido a esses comportamentos inconsistentes, a variedade de substituição de comando entre aspas não é recomendada para novos aplicativos que aninham substituições de comando ou tentam incorporar scripts complexos. Embora essa não seja uma depreciação formal, uma vez que a seção de justificativa é informativa e não normativa, ela sugere que o uso continuado de retalhos deve ser evitado.
jw013

15

Não está obsoleto, mas os backticks ( `...`) são a sintaxe herdada exigida apenas pelos bourne-shells mais antigos e não compatíveis com POSIX e $(...)é POSIX e mais preferido por vários motivos:

  • As barras invertidas ( \) dentro dos backticks são tratadas de maneira não óbvia:

    $ echo "`echo \\a`" "$(echo \\a)"
    a \a
    $ echo "`echo \\\\a`" "$(echo \\\\a)"
    \a \\a
    # Note that this is true for *single quotes* too!
    $ foo=`echo '\\'`; bar=$(echo '\\'); echo "foo is $foo, bar is $bar" 
    foo is \, bar is \\
  • A citação aninhada no interior $()é muito mais conveniente:

    echo "x is $(sed ... <<<"$y")"

    ao invés de:

    echo "x is `sed ... <<<\"$y\"`"

    ou escrevendo algo como:

    IPs_inna_string=`awk "/\`cat /etc/myname\`/"'{print $1}' /etc/hosts`

    porque $()usa um contexto totalmente novo para citar

    o que não é portátil, pois as conchas de Bourne e Korn exigiriam essas barras invertidas, enquanto Bash e dash não.

  • A sintaxe para aninhar substituições de comandos é mais fácil:

    x=$(grep "$(dirname "$path")" file)

    do que:

    x=`grep "\`dirname \"$path\"\`" file`

    como $()impõe um contexto totalmente novo para a citação, cada substituição de comando é protegida e pode ser tratada por si só, sem preocupação especial com a citação e escape. Ao usar as costas, fica cada vez mais feio depois de dois e acima dos níveis.

    Mais alguns exemplos:

    echo `echo `ls``      # INCORRECT
    echo `echo \`ls\``    # CORRECT
    echo $(echo $(ls))    # CORRECT
  • Ele resolve um problema de comportamento inconsistente ao usar aspas:

    • echo '\$x' saídas \$x
    • echo `echo '\$x'` saídas $x
    • echo $(echo '\$x') saídas \$x
  • A sintaxe dos backticks possui restrições históricas no conteúdo do comando incorporado e não pode manipular alguns scripts válidos que incluem aspas, enquanto o $()formulário mais recente pode processar qualquer tipo de script incorporado válido.

    Por exemplo, esses scripts incorporados válidos de outra forma não funcionam na coluna da esquerda, mas no IEEE da direita :

    echo `                         echo $(
    cat <<\eof                     cat <<\eof
    a here-doc with `              a here-doc with )
    eof                            eof
    `                              )
    
    
    echo `                         echo $(
    echo abc # a comment with `    echo abc # a comment with )
    `                              )
    
    
    echo `                         echo $(
    echo '`'                       echo ')'
    `                              )

Portanto, a sintaxe da substituição de comando$ pré-prefixada deve ser o método preferido, porque é visualmente clara com sintaxe limpa (melhora a legibilidade humana e da máquina), é aninhada e intuitiva, sua análise interna é separada e também é mais consistente (com todas as outras expansões analisadas entre aspas duplas), onde os backticks são a única exceção e o caractere é facilmente camuflado quando adjacente a uma leitura ainda mais difícil, especialmente com fontes pequenas ou incomuns.`"

Fonte: Por que é $(...)preferido `...`(backticks)? no BashFAQ

Veja também:

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.