Что это за специальные левые < и почему пробелы имеют значение?

У меня была эта проблема на Dell Optiplex, и проблема оказалась в пробуждении -по -функции расписания -в BIOS,не будить -по -лан. Он был настроен на загрузку моей машины каждое утро. Подробнее об этой функции можно прочитать здесь:http://www.inspectmygadget.com/2009/01/08/little-known-bios-features-wake-up-a-computer-on-a-scheduleи здесь https://www.makeuseof.com/answers/bios-computer-boot-specific-time/.

0
11.04.2021, 15:58
1 ответ

Три вещи <, <<и <(являются различными операторами. У вас не может быть пробела внутри оператора, но в некоторых случаях требуется пробел между ними, чтобы помочь оболочке правильно определить, что вы имеете в виду.

Обычно лексеры поглощают самый длинный набор символов, который создает допустимый оператор, а затем возвращают токен, представляющий этот оператор, синтаксическому анализатору, который затем обрабатывает фактический синтаксис языка.

.:

  • cat < filenameвыдает три токена «слово cat», «оператор перенаправления ввода», «слово filename».

  • cat << EOFвыдает «слово cat», «оператор heredoc», «слово EOF» и

  • cat < < EOFвыдаст четыре токена «слово cat», «оператор перенаправления ввода», «оператор перенаправления ввода», «слово EOF», но это синтаксически бессмысленно и дает ошибку.

  • cat<filenameдействует идентично первому, так как символ <не может быть частью слова, если он не заключен в кавычки, поэтому токен здесь прерывается.

Точно так же <(— это начало подстановки процесса, но < (— это всего лишь два оператора <и (, поскольку пробел их разбивает. И, из-за самого длинного соответствия префикса -, <<(здесь -оператор документа <<, за которым следует (и , а не оператор перенаправления <, за которым следует начало замена процесса, хотя это может быть более полезной интерпретацией.

Использование самого длинного префикса довольно распространено и в других языках. Например. в C i+++aсовпадает сi ++ + a(или i++ + a), а для i + ++aвам нужен пробел после первого +. Оба являются допустимыми выражениями, они просто означают разные вещи. А в С++,долгое время вам приходилось писать вложенные шаблоны как vector<vector<int> >, так как без пробела >>будет рассматриваться как несвязанный оператор сдвига вправо -вместо двух >, которые шаблон требует синтаксис.


Тем не менее, ваша последняя команда,sshpass -f<(printf '%s\n' $PASSWORD)должна работать так же, как cat<filename, и на самом деле она работает для меня:

$ sshpass -f<(echo password) ssh foo@localhost 'echo hi'
hi

С помощью set -xмы видим, что на самом деле выполняется команда

sshpass -f/dev/fd/63 ssh foo@localhost 'echo hi'

т. е. с заменой процесса на имя файла до того, как sshpassего увидит. Для некоторых программ между -f fooи -ffooможет быть разница, но это не то, как разбираются операторы оболочки.

6
28.04.2021, 22:53

Теги

Похожие вопросы