У меня была эта проблема на 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/.
Три вещи <
, <<
и <(
являются различными операторами. У вас не может быть пробела внутри оператора, но в некоторых случаях требуется пробел между ними, чтобы помочь оболочке правильно определить, что вы имеете в виду.
Обычно лексеры поглощают самый длинный набор символов, который создает допустимый оператор, а затем возвращают токен, представляющий этот оператор, синтаксическому анализатору, который затем обрабатывает фактический синтаксис языка.
.:
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
может быть разница, но это не то, как разбираются операторы оболочки.