volta carrapatos vs aspas duplas

6

Venho imaginando isso há muito tempo, mas ainda não descobri como pesquisá-lo -

é isto:

x='command -v r2g'

o mesmo que isto:

x="$(command -v r2g)"

ou é o mesmo que isso:

x=$(command -v r2g)

... se é o último, devo fazer isso para corrigir isso?

x="'command -v r2g'"
    
por Alexander Mills 28.05.2018 / 05:54

4 respostas

7

Todos os exemplos são de atribuição de variáveis a partir da substituição de comandos, então eles são equivalentes. De acordo com a resposta de Gilles, a citação não é necessária à direita da atribuição à variável, pois a divisão de palavras não ocorrer lá. Então todos os quatro estão bem.

Se eles fossem autônomos, ou seja, não em atribuição, você precisaria citar. A forma $(...) comparada aos backticks tem a vantagem de que aspas podem ser aninhadas e divididas em várias linhas, e é por isso que essa forma é geralmente preferida atualmente. Em outras palavras, você pode fazer "$( echo "$var" )" com este formulário para proteger tanto a expansão interna de $var quanto a expansão externa de $(...) da divisão de palavras e da globalização de nomes de arquivos.

Conforme mostrado nas especificações Linguagem de comando do shell POSIX , os scripts de múltiplas linhas incorporados não trabalhe com backticks (à esquerda), mas trabalhe com $() form (à 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 ')'
'                              )
    
por 28.05.2018 / 07:06
3

Os quatro exemplos são funcionalmente equivalentes.

Backticks são obsoletos e, a menos que você esteja usando um shell 1970 como um shell Bourne (como o Heirloom), não é necessário. O principal problema é que eles são muito difíceis de aninhar , tente:

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

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

No lado direito de uma linha de comando com apenas uma atribuição, não é necessário (mas inofensivo) citar a expansão, já que a expansão é considerada de qualquer maneira:

$ var=$(uname)

Mas isso é não sempre verdadeiro, uma atribuição no comando export é considerada como um argumento e será dividida e glob em alguns shells (não no bash):

$ dash -c 'export MYVAR='echo a test';echo "$MYVAR"'
a

O mesmo raciocínio se aplica a local ( As cotações são necessárias para atribuição de variável local? ) e declare (e alguns outros).

O que você deve fazer para "consertar" é:

x=$(command -v r2g)

E às vezes (para scripts portáteis):

export x="$(command -v r2g)"
    
por 28.05.2018 / 07:45
2

Sim, os backticks também devem ser citados.

Isso pode ser uma questão de estilo bash preferido para casos em que a saída do comando não contém espaços. Aqui está uma citação do autor do utilitário shellharden , de " como fazer as coisas com segurança no bash ":

Should I use backticks?
Command substitutions also come in this form:

Correct: "'cmd'"
Bad: 'cmd'
While it is possible to use this style correctly, it looks even more awkward in quotes and is less readable when nested. The consensus around this one is pretty clear: Avoid.

Shellharden rewrites these into the dollar-parenthesis form.

Eu também acredito que é uma boa forma de citar backticks com " , ou (melhor) reescrevê-lo para usar $() . Se a saída do comando contiver espaços ou caracteres especiais ao usar backticks, pode ser problemático se não estiver citando a expressão.

    
por 28.05.2018 / 06:08
-1

Sim, meu palpite parece correto, de acordo com este documento: link

Diz:

# Should I use backticks?
# Command substitutions also come in this form:

Correct: "'cmd'"
Bad: 'cmd'
    
por 28.05.2018 / 06:25