Судя по тому, как я читал документацию, если вы используете ssh-agent
, ssh-copy-id
установит туда все ключи которые еще не работают, так что это должно работать (но я не тестировал):
# spawn a new agent for this so we know it's not keeping keys
$(ssh-agent)
# add keys
ssh-add new-key.pem old-key.pem
# check if those keys made it in
ssh-add -l
# and now add extra keys
ssh-copy-id user@remote
# stop the extra ssh-agent
kill $SSH_AGENT_PID
;
разделяет утверждения (грубо говоря). (Почти) всегда можно заменить ;
новой строкой.
Сказать, что ;
разделяет две программы, поэтому , если
и , то
должны быть «программами», слишком упрощенно, поскольку утверждение может быть сделано из зарезервированные слова, функции оболочки, встроенные утилиты и внешние утилиты, а также их комбинации с использованием каналов, логических операторов и т. д. и т. д.
Оба if
и , то
являются зарезервированными словами в грамматика оболочки , а не «программы». Здесь они используются для создания того, что технически называется составной командой .
echo
, вероятно, является встроенной утилитой в оболочке (но не обязательно), а ls
, вероятно, является внешней утилитой (или «программой», как вы говорите).
, затем
и else
не являются программами. Остальные части есть. Обратите внимание, что непосредственно после них нет ;
', но после команды, которой они предшествуют.
[...]
является командой и требует ;
, если за ней следует начало другой команды.
AFAIK, все управляющие структуры в Bash и , вероятно, большинство * nix-оболочек, одинаковы. Это инструкции для переводчика. С другой стороны, тест или условие использует программу / процесс, которые «выполняются» и являются командами. Поскольку , то
является частью строки, которая ведет к команде echo
, она должна быть отделена новой строкой от предыдущей команды [...]
. Его не нужно отделять от команды, которую он контролирует, echo yes
.
С юридической точки зрения, хотя это некрасиво и трудночитаемо, вы тоже можете это сделать.
if [ $VARIABLE == abcdef ]
then echo yes
else echo no
fi
Обратите внимание, что здесь нет необходимости в ;
между элементами управления, даже если они не на своей линии.
Интересно, что вся управляющая структура ( if ... fi
) является командой оболочки, и вся структура должна заканчиваться новой строкой или ;
. Последняя строка не может быть fi echo done
, но должна быть fi; эхо сделано
. То же, что и присвоение VARIABLE = 'abcdef'
, является командой.
Несмотря на то, что все управляющие структуры являются командами, они все же не являются программами.
Хотя это хорошее первое приближение, когда кто-то только начинает изучать основы использования оболочек, на уровне «вот как можно запускать программу «и» вот как можно запускать несколько программ одну за другой в одной строке », на самом деле это не так.
Сложнее понять новичку, но более правильное объяснение состоит в том, что язык оболочки - это компьютерный язык . Он имеет синтаксис . Этот синтаксис содержит различные лексические элементы , включая (среди прочего) символы новой строки, операторы, слова и зарезервированные слова.
if
, , то
, else
и fi
- все зарезервированные слова . Они имеют особое значение при синтаксическом анализе входных данных, передаваемых оболочке в соответствии с ее грамматикой . Аналогично, ;
является оператором разделителя .
Таким образом, ввод на языке оболочки - это компьютерная программа, которая интерпретируется другой программой, интерпретатором , оболочкой.Его отдельные грамматические части не являются программами. Язык оболочки - это способ указания (других) программ для запуска оболочки.
[
не является специальным лексическим элементом в грамматике оболочки, например оператором. Это обычное слово , которым названа одна такая программа с именем [
. Многие оболочки имеют встроенную версию этой программы, объединенную в код самой программы оболочки, но вы также можете найти внешнюю программу с этим именем где-нибудь, например, ] / bin / [
или / usr / bin / [
, которые могут вызывать программы , кроме оболочки. Точно так же ]
также не является специальным лексическим элементом оболочки. Обычное слово, которое становится аргументом для программы [
. Программа [
требует, чтобы ее последний аргумент при выполнении был ]
, который затем игнорируется.
Другая похожая программа, названная в вашем вопросе, - echo
. Опять же, у большинства оболочек есть встроенная версия этой программы. Но, опять же, есть и внешняя версия программы, например, / bin / echo
или / usr / bin / echo
, для программ , отличных от оболочек. вызывать.
Третья программа, названная в вашем вопросе, - ls
. Оболочки обычно не имеют встроенных версий этой программы, и это внешняя программа, которую можно найти где-нибудь, например, / bin / ls
или / usr / bin / ls
.
Для оболочки Bourne Again вы можете прочитать больше об этом в Основные функции оболочки документации по оболочке GNU Bourne Again. Другие оболочки, естественно, имеют другую грамматику.Единая спецификация Unix описывает синтаксис, которому должны соответствовать все POSIX-совместимые оболочки (в их POSIX-совместимых режимах).
тест
. Утилиты . Базовые спецификации Выпуск 7. Открытая группа. IEEE 1003.1-2008. ISBN 1937218812. if
, elif
, then
и fi
все зарезервированные ключевые слова, используемые для реализации одной из конструкций, называемых составной командой в оболочке, что означает, что в оболочке не может быть команды (или, скорее, другой команды) с любым из этих имен. Назначение ;
в целом - не разделение команд, а завершение списка команд . Например, следующий допустимый оператор if
:
if echo foo; echo bar; echo baz; then echo done; echo really done; fi
Условием оператора if
является список команд echo foo; эхо-бар; echo baz
. Синтаксический анализатор знает, что условие выполнено, потому что , затем
, которое следует сразу за точкой с запятой, не может быть командой, потому что это зарезервированное ключевое слово. Таким образом, он знает, что то, что следует за , тогда
является началом тела.Аналогично, fi
является зарезервированным ключевым словом и, следовательно, не может быть третьей командой в теле оператора if
, но отмечает конец составной команды.
На самом деле нет ничего удивительного в том, чтобы рассматривать if
, , затем
и else
как внешние программы. Фактически, оболочка Томпсона в исходной 1-й редакции Unix реализовывала if
и goto
как внешние программы. Это возможно, потому что подпроцесс разделяет файловые дескрипторы с процессом оболочки, поэтому (вперед) goto просто нужно было читать ввод, пока он не найдет целевую метку, а затем завершится. См. оболочка Томпсона .