Avaliando uma string no shell script

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 string de comandos em uma variável bash e então invocamos echo na variável. O que parece acontecer é que a string é avaliada e o comando wc é executado e retorna a contagem da linha ao terminal de controle.

Ok, então eu lanço meu terminal no Ubuntu 12.04 e tento algo parecido:

$ 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 apenas ecoou a corda de volta ao terminal. Por que recebi resultados diferentes?

    
por JohnMerlino 17.03.2014 / 06:07

3 respostas

2

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

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

Se você quiser 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 doublequotes "", singlequotes ' 'e backticks ´´ na linha de comando?

    
por Danatela 17.03.2014 / 06:12
5

Por favor, note que o símbolo:

  

'

Citação simples

   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.

Assim, o Backquote está retornando o resultado do comando para a saída padrão. É por isso que

'wc -l sample.txt'

retorna os resultados do comando, enquanto

  

'wc -l sample.txt'

apenas retorne "wc -l sample.txt" como uma string normal

Considere fazer isso como exemplo:

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

E agora ecoa as três variáveis:

$ echo $A
wc -l /proc/mounts
$ echo $B
35 /proc/mounts
$ echo $C
35 /proc/mounts
    
por c0rp 17.03.2014 / 06:20
3

Se você deseja capturar a saída de um comando em uma variável, é necessário usar backticks '' ou incluir 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

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

Em geral, você deve sempre usar $() em vez de backticks que estão obsoletos e apenas por motivos de compatibilidade e muito mais limitados. Você não pode, por exemplo, aninhar comandos dentro de backticks, mas você pode com $() :

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

Veja este tópico em U & amp; L para mais detalhes sobre por que '' deve ser evitado.

    
por terdon 17.03.2014 / 06:26