Avaliando uma sequência no script de shell

8

Estou seguindo este guia de script do shell bash:

Na seção Comparações Numéricas, cita um exemplo:

anny > num=`wc -l work.txt`

anny > echo $num
201

anny > if [ "$num" -gt "150" ]
More input> then echo ; echo "you've worked hard enough for today."
More input> echo ; fi

O que parece acontecer acima é que armazenamos uma sequência de comandos em uma variável bash e, em seguida, invocamos eco na variável. O que parece acontecer é que a cadeia é avaliada e o comando wc é executado e retorna a contagem de linhas para o terminal de controle.

Ok, então inicio o meu terminal no Ubuntu 12.04 e tento algo semelhante:

$ touch sample.txt && echo "Hello World" > sample.txt
$ cat sample.txt
Hello World
$ num='wc -l sample.txt'
echo $num
wc -l sample.txt

Espere um segundo, que não avaliou a string e retornou a contagem de linhas. Isso ecoou a corda de volta ao terminal. Por que obtive resultados diferentes?

JohnMerlino
fonte
Note-se que num nunca é atribuído a corda wc -l work.txt, em vez disso, é atribuído o número 201.
Ignis
Recurso relacionado: 3.5.4 Substituição de comando no manual de referência do Bash .
Eliah Kagan 22/01

Respostas:

2

Você precisa usar backticks para avaliar a expressão.

$ num=`wc -l sample.txt`
$ echo $num
1 sample.txt

Se você deseja ver apenas "1" na saída, use o comando

$ num=`cat sample.txt | wc -l`
$ echo $num
1

E também funciona:

$ num=`wc -l < sample.txt`
$ echo $num
1

Para obter informações adicionais, consulte Diferenças entre de aspas "", singlequotes '' e acentos graves '' na linha de comando?

Danatela
fonte
Alguma idéia de por que recebo '1 sample.txt' e não apenas o número '1'?
31414 JohnMerlino
É assim que o wccomando funciona. Tente cat sample.txt | wc -l.
Danatela
wc -l exibe o número de linhas presentes em um arquivo junto com seu nome de arquivo.
precisa
5

Observe esse símbolo:

"

Citação única

   Enclosing characters in single quotes preserves the  literal  value  of
   each character within the quotes.  A single quote may not occur between
   single quotes, even when preceded by a backslash.

e

`

Backquote

   Command substitution allows the output of a command to replace the com
   mand name.  There are two forms:

          $(command)
   or
          `command`

   Bash performs the expansion by executing command and replacing the com
   mand  substitution  with  the  standard output of the command, with any
   trailing newlines deleted.

Portanto, o Backquote está retornando o resultado do comando para Saída padrão. É por isso que

`wc -l sample.txt`

retorna resultados do comando, enquanto

'wc -l sample.txt'

basta retornar "wc -l sample.txt" como uma string usual

Considere fazer isso como exemplo:

$ A='wc -l /proc/mounts'
$ B=`wc -l /proc/mounts`
$ C=$(wc -l /proc/mounts)

E agora faça eco das três variáveis:

$ echo $A
wc -l /proc/mounts
$ echo $B
35 /proc/mounts
$ echo $C
35 /proc/mounts
c0rp
fonte
4

Se você deseja capturar a saída de um comando em uma variável, é necessário usar backticks ``ou colocar o comando em $():

$ d=$(date)
$ echo "$d"
Mon Mar 17 10:22:25 CET 2014
$ d=`date`
$ echo "$d"
Mon Mar 17 10:22:25 CET 2014

Observe que a string é realmente avaliada no momento da declaração da variável, não quando você a reproduz. Na verdade, o comando é executado dentro dos $()backticks ou e a saída desse comando é salva como o valor da variável.

Em geral, você deve sempre usar, em $()vez de backticks, que foram descontinuados e apenas disponíveis por razões de compatibilidade e muito mais limitados. Você não pode, por exemplo, aninhar comandos nos backticks, mas pode $():

$ echo $(date -d $(echo yesterday))
Sun Mar 16 10:26:07 CET 2014

Veja este tópico no U&L para obter mais detalhes sobre por que ``deve ser evitado.

Terdon
fonte
1
Concordo scripts devem preferir $( )a ` `. Mas, como wag diz , crase fazer ninho. echo $(date -d $(echo yesterday))torna-se echo `date -d \`echo yesterday\``; echo $(echo $(date -d $(echo yesterday)))torna-se echo `echo \`date -d \\\`echo yesterday\\\`\``. Digo isso não para refutar sua tese, mas para fortalecê-la : citações internas vazias tornam a ` `sintaxe mais poderosa do que se costuma admitir, mas o tratamento especial \é estranho, surpreendente e difícil de raciocinar. Com o $( )que você vê é geralmente o que você recebe.
Eliah Kagan 22/01