Что означают паратезис и $ sign в echo $ (ls)

7

Вывод

# ls

и

# echo $(ls)

совпадают. Что означает знак $ и скобка?

Кроме того, что происходит на техническом уровне, который приводит к тому, что вывод этих двух команд одинаковый?

    
задан user784637 04.12.2011 в 01:53
источник

4 ответа

5

Это подстановка команды для bash.

  

Подстановка команд позволяет выводить команду на замену   сама команда. Замена команды происходит, когда команда заключена   следующим образом:

 $(command) or

 'command'

Ссылка

Подробнее:

Ссылка

Ссылка

И хороший пример, похожий на ваш вопрос:

Ссылка

    
ответ дан heartsmagic 04.12.2011 в 02:12
источник
2

Когда оболочка встречает текст, заключенный в $( ) , он:

  1. Делает это командой и (как bodhi.zazen говорит ) запускает команду в subshell .
  2. Заменяет output команды вместо всего выражения (включая открытие $( и закрытие ) ).

В качестве ответа heartsmagic объясняется, что это один из двух доступных синтаксисов для .

«Что ... приводит к тому, что вывод этих двух команд одинаковый?»

На самом деле несколько необычно, что вывод ls будет точно таким же, как вывод echo $(ls) :

[email protected]:~/tmp$ ls
bar  foo
[email protected]:~/tmp$ echo $(ls)
bar foo

ls обычно разделяет имена файлов на два или более пробела или новой строки. Это помогает нам легче рассказать об этом, особенно потому, что пространства в именах файлов несколько обычны (но несколько последовательных пробелов, менее распространены).

Разделение слов

Когда я запустил echo $(ls) , произошло следующее.

  1. Подстановка команд заменила $(ls) на:

    bar
    foo
    

    Вы можете быть удивлены, услышав это, поскольку это, вероятно, не то, что вы видите, когда вы запускаете ls самостоятельно! Это несоответствие в том, что ls выводится ниже, но на самом деле это не причина, по которой вы получаете одно пространство между этими двумя словами. То же самое произойдет, если $(ls) были заменены на bar foo (с двумя пробелами).

  2. Затем оболочка выполнила разбиение слов , обработав bar и foo в качестве отдельного аргументов команды echo вместо одного аргумента, содержащего пробелы.

Когда echo получает несколько аргументов (кроме таких параметров, как -n , которые обрабатываются специально и не печатаются вообще), он распечатывает их все, с одним пробелом между последующими аргументами. echo затем печатает новую строку (если не передана опция -n ).

Таким образом, echo $(ls) показывает результат как bar foo вместо bar foo .

Если вы запустите ls и в нем нет файлов или только одного файла, то выход ls будет часто совпадать с выводом echo $(ls) . Даже тогда это не всегда будет одинаковым, например, когда имя файла содержит пробелы, кроме изолированных (одиночных) пространств:

[email protected]:~/tmp2$ touch 'my   file'
[email protected]:~/tmp2$ ls
my   file
[email protected]:~/tmp2$ echo $(ls)
my file

Когда ls печатает несколько файлов, его вывод вряд ли будет таким же, как и выход $(ls) . Аналогично:

  • echo a b и echo $(echo a b) выдают одинаковый результат, , но
  • echo 'a b' и echo $(echo 'a b') нет.

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

Обнаружение терминала

Если вы хотите предотвратить разбиение слов, вы можете заключить выражение для подстановки команды в двойные кавычки ( " ). Обычно это достаточно и, в частности, будет работать с примерами echo , приведенными выше, а также с примером ls в каталоге с одной записью, содержащей пробелы:

[email protected]:~/tmp2$ echo "$(ls)"
my   file

Однако, как отмечалось выше, вы можете быть удивлены, обнаружив, что то, что вы видите при запуске ls , часто не является тем, что передается echo вместо "$(ls)" :

[email protected]:~/tmp$ ls
bar  foo
[email protected]:~/tmp$ echo "$(ls)"
bar
foo

Это связано с тем, что ls проверяет, является ли стандартный вывод терминалом чтобы решить, как форматировать свой результат , когда форматирование вывода явно не указано.

  • Когда stdout является терминалом, ls выводит в вертикально отсортированных столбцах, например ls -C .
  • Когда stdout не является терминалом, ls перечисляет каждую запись в своей строке, например ls -1 .

В подстановке команд стандартный вывод не является терминалом, потому что вывод команды не отправляется непосредственно на терминал, чтобы вы могли видеть - вместо этого он захватывается оболочкой и используется как часть другой команды.

Чтобы получить форматирование нескольких столбцов при запуске ls с помощью подстановки команды, передайте ему флаг -C :

[email protected]:~/tmp$ echo "$(ls -C)"
bar  foo

( dir иногда предлагается в качестве альтернативы ls -C и также будет работать для этого, хотя dir ведет себя как ls -C -b , а не только ls -C .)

Сглаживание оболочки

Другая причина, по которой ls может иногда отличаться от echo "$(ls)" , состоит в том, что ls может быть a псевдоним оболочки . Запустите alias ls для проверки; на Ubuntu вы обычно получаете alias ls='ls --color=auto' , что означает, что когда ls отображается как первое слово команды, которую вы запускаете в интерактивном режиме (и в некоторых, но не во всех других случаях), она заменяется на ls --color=auto .

Например, когда я запускаю ls , он отображает каталоги, окрашенные в синий цвет, и исполняемые файлы окрашены в зеленый цвет (а также реализуют многие другие правила раскраски). --color=auto вызывает ls для печати цветного вывода, когда стандартный вывод является терминалом, а не иначе.

Чтобы получить цветной вывод при запуске ls с помощью подстановки команды, передать его --color или --color=always . Если вам нравится, вы можете комбинировать это с -C :

echo $(ls -C --color)

Обратите внимание, что хотя вы можете сделать ls псевдонимам ls --color или ls --color=always вместо ls --color=auto , а ls --color=always не заботится о том, является ли стандартный вывод терминалом ... этот псевдоним все равно не будет вызвать ls для создания цветного вывода при вызове путем подстановки команды. Это связано с тем, что псевдонимы оболочки (в оболочках в стиле Бурна , такие как bash ) расширяются только тогда, когда оболочка видит их в качестве первого слова команды (и они не унаследованы подоболочками).

    
ответ дан Eliah Kagan 17.10.2014 в 00:48
1

() и $ () используются для запуска команд в подоболочке

Подробнее см. Ссылка .

    
ответ дан Panther 04.12.2011 в 01:59
0

Использование $ перед именем переменной вызывает значение, присвоенное переменной. Echo без $ будет просто печатать имя переменной на экране (или стандартном выходе).

    
ответ дан haziz 04.12.2011 в 06:22