for i in $(xrandr); do echo "$i" ; done
for i in "$(xrandr)"; do echo "$i"; done
for i in "$(xrandr)"; do echo $i; done
Я понимаю, почему 1 отличается от 2. Но почему 3 дает отличный результат от 2? Пожалуйста, объясните вывод тоже. Как цитаты работают на новых строках?
Ответы:
Переменная без кавычек (как в
$var
) или подстановка команд (как в$(cmd)
или`cmd`
) - это оператор split + glob в оболочках типа Борна.То есть их содержимое разделяется в соответствии с текущим значением
$IFS
специальной переменной (которая по умолчанию содержит пробел, символы табуляции и символы новой строки)И затем каждое слово, полученное в результате этого разделения, подвергается генерации имени файла (также известной как глобализация или расширение имени файла ), то есть они рассматриваются как шаблоны и расширяются до списка файлов, которые соответствуют этому шаблону.
Таким
for i in $(xrandr)
образом$(xrandr)
, поскольку он не находится в кавычках, он разбит на последовательности символов пробела, табуляции и новой строки. И каждое слово, полученное в результате этого разбиения, проверяется на совпадение имен файлов (или оставляется как есть, если они не совпадают ни с одним файлом) иfor
проходит по всем.В
for i in "$(xrandr)"
, мы не используем оператор split + glob, так как подстановка команды заключена в кавычки, поэтому в цикле есть одно проходное значение для одного значения: выходxrandr
(без завершающих символов новой строки, которые заменяет подстановка команды ).Однако в
echo $i
,$i
снова не заключаются в кавычки, поэтому снова содержимое$i
разделяется и подвергается генерации имени файла, и они передаютсяecho
команде как отдельные аргументы (иecho
выводят ее аргументы через пробелы).Итак, урок усвоен:
$IFS
соответствующим образом и / или включите или отключите создание имени файла, если необходимо (set -f
,set +f
).Как правило, в приведенном выше примере, если вы хотите перебрать пустой разделенный список слов в выходных данных
xrandr
, вам необходимо:$IFS
по умолчанию (или сбросить его) для разделения на пробелыset -f
чтобы отключить генерацию имени файла, если вы не уверены, чтоxrandr
никогда не выводите символы*
или?
или[
(которые являются подстановочными знаками, используемыми в шаблонах генерации имени файла)И только затем используйте оператор split + glob (оставьте подстановку команды или расширение переменной без кавычек) в
in
частиfor
цикла:Если вы хотите , чтобы цикл по (непустым) линиям в
xrandr
выходе, вы должны установить$IFS
на символ новой строки:источник
Цитируемый перевод строки - это перевод строки. Таким образом,
echo "$1"
дает один аргумент командной строки для echo, который затем печатает новые строки напрямую.Новая строка без кавычек - это пробел. Таким образом,
echo $1
дает много аргументов командной строки для эха, который печатает их один за другим через пробел.источник