В чем разница, и в bash?

60

В чем разница между << , <<< и < < в bash?

    
задан Searene 27.09.2015 в 09:42
источник

4 ответа

67

Здесь документ

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

Вот что я имею в виду:

$ wc << EOF
> one two three
> four five
> EOF
 2  5 24

В этом примере мы говорим программе wc для ожидания строки EOF , затем введите пять слов, а затем введите EOF , чтобы сообщить, что мы закончили ввод ввода. Фактически, он похож на запуск wc сам по себе, набрав слова, а затем нажав Ctrl D

Здесь строка

<<< известен как here-string . Вместо того, чтобы вводить текст, вы даете предварительно созданную строку текста программе. Например, с такой программой, как bc , мы можем сделать bc <<< 5*4 , чтобы просто получить вывод для этого конкретного случая, нет необходимости запускать bc в интерактивном режиме.

Замена процесса

Как tldp.org объясняет,

  

Замена процесса подает вывод процесса (или процессов) в   stdin другого процесса.

Таким образом, это похоже на соединение stdout одной команды с другим, например. echo foobar barfoo | wc . Но обратите внимание: в файле bash вы увидите, что он обозначается как <(list) . Таким образом, вы можете перенаправить вывод нескольких (!) Команд.

Примечание: технически, когда вы говорите < < , вы не имеете в виду одну вещь, но два перенаправления с одним < и перенаправление процесса выхода из <( . . .) .

Теперь, что произойдет, если мы просто заменим процесс?

$ echo <(echo bar)
/dev/fd/63

Как вы можете видеть, оболочка создает временный файловый дескриптор /dev/fd/63 , где идет выход. Это означает, что < перенаправляет этот файловый дескриптор в качестве ввода в команду.

Так что очень простой пример - сделать замену процессов из двух команд эха в wc:

$ wc < <(echo bar;echo foo)
      2       2       8

Итак, здесь мы создаем оболочку, создаем файловый дескриптор для всего вывода, который происходит в скобках, и перенаправляем его как вход в wc . Как ожидается, wc получает этот поток из двух команд эха, который сам будет выводить две строки , каждый из которых имеет слово, и соответственно у нас есть 2 слова, 2 строки и 6 символов плюс две подсвеченные строки.

Боковое примечание: Подстановка процесса может упоминаться как bashism (команда или структура, используемые в расширенных оболочках, таких как bash , но не указанных POSIX) но он был реализован в ksh до существования bash как man-страницы ksh и этот ответ . Однако оболочки, такие как tcsh и mksh , не имеют замены процесса. Итак, как мы могли бы перенаправить вывод нескольких команд в другую команду без замены процесса? Группировка плюс трубопровод!

$ (echo foo;echo bar) | wc
      2       2       8

Фактически это то же самое, что и в приведенном выше примере. Однако это отличается от капота от замены процесса, поскольку мы делаем stdout сгруппированных команд и stdin wc , связанный с каналом . С другой стороны, замещение процесса заставляет команду читать временный файловый дескриптор.

Итак, если мы сможем объединиться с трубопроводом, зачем нужна замена процесса? Потому что иногда мы не можем использовать трубопроводы. Рассмотрим приведенный ниже пример - сравнение выходов двух команд с diff (для которых нужны два файла, и в этом случае мы даем два дескриптора файла)

diff <(ls /bin) <(ls /usr/bin)
    
ответ дан Sergiy Kolodyazhnyy 27.09.2015 в 09:56
источник
22

< < - синтаксическая ошибка:

$ cat < <
bash: syntax error near unexpected token '<'

< <() замещение процесса ( <() ) в сочетании с перенаправлением ( < ):

Надуманный пример:

$ wc -l < <(grep ntfs /etc/fstab)
4
$ wc -l <(grep ntfs /etc/fstab)
4 /dev/fd/63

При замене процесса путь к файловому дескриптору используется как имя файла. Если вы не хотите (или не можете) использовать имя файла напрямую, вы комбинируете замену процесса с перенаправлением.

Чтобы быть понятным, нет оператора < < .

    
ответ дан muru 27.09.2015 в 10:05
10

< < - синтаксическая ошибка, вы, вероятно, имеете в виду command1 < <( command2 ) , которая является простым перенаправлением ввода, а затем заменой процесса и очень похожа, но не эквивалентна:

command2 | command1

Разница, предполагающая, что вы используете bash , command1 запускается в подоболочке во втором случае, когда она выполняется в текущей оболочке в первом. Это означает, что переменные, установленные в command1 , не будут потеряны с вариантом замены процесса.     

ответ дан jlliagre 27.09.2015 в 10:09
8

< < даст синтаксическую ошибку. Правильное использование:

Объяснение с помощью примеров:

Пример для < <() :

while read line;do
   echo $line
done< <(ls)

В приведенном выше примере вход в цикл while будет получен из команды ls , которая может быть прочитана по очереди и echo ed в цикле.

<() используется для замещения процесса. Более подробную информацию и пример для <() можно найти по этой ссылке:

Замена и обработка процессов

    
ответ дан snoop 27.09.2015 в 10:06