Групповая команда с конвейером в Bash - PullRequest
0 голосов
/ 19 марта 2020

В книге «Linux Командная строка» автор приводит пример сортировки массива:

arr=(f e d c b a)
arr_sorted=($(for i in "${arr[@]}"; do echo $i; done | sort))

Вывод из for l oop (который печатает весь последующий массив значения с echo) передаются по конвейеру на sort.

С другой стороны, в другой главе автор представляет аналогичный пример, но использует Bash «групповую команду», которая обозначается окружающими фигурными скобками { } (я свернул его сценарий, сохранив идею):

declare -A arr  # an associative array
arr["key0"]=val0
arr["key2"]=val2
arr["key1"]=val1
{ for i in "${!arr[@]}"; do
    printf "%s: %s\n" "$i" "${arr["$i"]}"
done } | sort

Авторская точка зрения: "(...) Также обратите внимание, что весь l oop заключен в фигурные скобки, образуя таким образом групповая команда. Это позволяет передать весь вывод l oop в команду сортировки. "

Однако я запустил этот скрипт (как оригинал книги, так и свернутый) как с без скобок «групповая команда», и все они работали совершенно одинаково - вывод эквивалентен.

Так почему автор настаивает на использовании групповой команды в приведенном выше случае, хотя она прекрасно работает без нее и даже он сам показал аналогичную рабочую версию (с arr_sorted) в предыдущей главе? Может быть, я что-то здесь упускаю.

Ответы [ 2 ]

1 голос
/ 19 марта 2020

Нет разницы между введением одной команды в { } фигурных скобок или нет.

:

{ for i in "${!arr[@]}"; do
    printf "%s: %s\n" "$i" "${arr["$i"]}"
done } | sort

эквивалентно:

for i in "${!arr[@]}"; do
    printf "%s: %s\n" "$i" "${arr["$i"]}"
done | sort

Пример:

{ { { { { echo a; }; }; }; }; }

- это просто echo a

1 голос
/ 19 марта 2020

Группа команд будет полезна, если вы хотите объединить вывод двух или более отдельных команд. Например,

{
   for i in "${!arr[@]}"; do
       printf "%s: %s\n" "$i" "${arr["$i"]}"
   done

   while IFS=, read -r a b; do
       printf "%s: %s\n" "$a" "$b"
   done < some_file.txt
} | sort

Но, как вы заметили, for l oop - это уже одна команда, поэтому нет смысла заключать ее в другую составную команду, чтобы собрать ее выходные данные для канала.


Группа команд особенно хороша для предотвращения повторных перенаправлений, которые требуют многократного открытия и закрытия файлов. Код типа

echo ... > some_file.txt
echo ... >> some_file.txt
echo ... >> some_file.txt
echo ... >> some_file.txt
echo ... >> some_file.txt

можно заменить на

{
  echo ...
  echo ...
  echo ...
  echo ...
  echo ...
} > some_file.txt

, который открывает some_file.txt один раз , а не пять раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...