Оценка строки в сценарии оболочки

7

Я следую этому руководству по сценарию оболочки bash:

В разделе «Численные сравнения» приведен пример:

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

Что, кажется, происходит выше, мы храним строку команд в переменной bash, а затем вызываем эхо на переменную. Похоже, что строка оценивается и выполняется команда wc и возвращает счетчик строк на управляющий терминал.

Итак, я запустил свой терминал в Ubuntu 12.04 и попробую что-то подобное:

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

Подождите секунду, чтобы не оценить строку и вернуть счетчик строк. Это просто повторило строку обратно на терминал. Почему у меня были разные результаты?

    
задан JohnMerlino 17.03.2014 в 05:07
источник

3 ответа

2

Вам нужно использовать обратные выражения для оценки выражения.

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

Если вы хотите видеть только «1» на выходе, используйте команду

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

И также работает:

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

Дополнительную информацию см. в разделе Различия между двойными значениями "", singlequotes ' 'и backticks' 'в командной строке?

    
ответ дан Danatela 17.03.2014 в 05:12
источник
5

Обратите внимание, что символ:

  

Одиночная цитата

   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.

и

  

кавычка

   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.

Итак, Backquote возвращает результат команды на стандартный вывод. Вот почему

'wc -l sample.txt'

возвращает результаты команды, а

  

'wc -l sample.txt'

просто верните «wc -l sample.txt» как обычно строку

Рассмотрим это как пример:

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

И теперь повторяем все три переменные:

$ echo $A
wc -l /proc/mounts
$ echo $B
35 /proc/mounts
$ echo $C
35 /proc/mounts
    
ответ дан c0rp 17.03.2014 в 05:20
3

Если вы хотите захватить вывод команды в переменной, вам нужно либо использовать backticks '' , либо заключить команду в $() :

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

Обратите внимание, что строка фактически оценивается в момент объявления переменной, а не когда вы ее эхо. Команда фактически выполняется внутри $() или backticks, и выход этой команды сохраняется как значение переменной.

В общем, вы всегда должны использовать $() вместо backticks, которые устарели, и только вокруг по причинам совместимости и гораздо более ограничены. Например, вы не можете вставлять команды в backticks, но вы можете использовать $() :

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

См. этот поток в U & amp; L для получения более подробной информации о том, почему следует избегать '' .     

ответ дан terdon 17.03.2014 в 05:26