Прекратить работу сценария bash, если соединение SSH не может быть установлено без взаимодействия

Вот решение, которое:

  1. устраняет [с] время, необходимое каждой оболочке для загрузки и инициализации

  2. может быть запущено из в каждой оболочке

  3. Использует

    нет встроенных в оболочку команд time , так как ни одна из них не является переносимой или общей

  4. Работает во всех POSIX-совместимых оболочках.
  5. Работает на всех POSIX-совместимых и XSI-совместимых системах с компилятором C , или где вы можете заранее скомпилировать исполняемый файл C.
  6. Использует одну и ту же реализацию синхронизации во всех оболочках.

Есть две части: короткая программа на C, которая завершает gettimeofday , которая устарела, но все еще более переносима, чем clock_gettime , и короткий сценарий оболочки, который использует эту программу для получения часы с точностью до микросекунды, считывающие обе стороны источника сценария. Программа на C - единственный переносимый способ с минимальными накладными расходами получить метку времени с точностью до секунды.

Вот эпоха программы C.c :

#include 
#include 
int main(int argc, char **argv) {
    struct timeval time;
    gettimeofday(&time, NULL);
    printf("%li.%06i", time.tv_sec, time.tv_usec);
}

И сценарий оболочки таймер :

#!/bin/echo Run this in the shell you want to test

START=$(./epoch)
. "$1"
END=$(./epoch)
echo "$END - $START" | bc

Это стандартный командный язык оболочки и bc и должен работать как сценарий под любая POSIX-совместимая оболочка.

Вы можете использовать это как:

$ bash timer ./test.sh
.002052
$ dash timer ./test.sh
.000895
$ zsh timer ./test.sh
.000662

Он не измеряет системное или пользовательское время, а только немонотонное время, прошедшее с настенных часов. Если системные часы изменятся во время выполнения скрипта, это даст неверные результаты. Если система находится под нагрузкой, результат будет ненадежным. Я не думаю, что можно переносить что-то лучшее между оболочками.

В модифицированном сценарии таймера вместо этого может использоваться eval для выполнения команд вне сценария.

1
13.04.2017, 15:36
2 ответа

Итак, вместо автоматического добавления хоста в известные_хосты вы хотите отказать в подключении, если он там еще не существует. StrictHostKeyChecking все еще является опцией для этого (как в вопросе по ссылке), но вместо того, чтобы установить no, установите yes. Это приведет к сбою соединения, если ключ хоста неизвестен.

$ ssh -oStrictHostKeyChecking=yes me@somehost.somewhere
No ECDSA host key is known for somehost.somewhere and you have requested strict checking.
Host key verification failed.

ssh завершает работу со статусом 255, если произошла ошибка, включая этот случай, поэтому вы можете проверить это в скрипте, используя что-то вроде

if [ "$?" = 255 ] ; then
    echo "there was an error"
fi

Конечно, это может быть и другая ошибка, вам нужно проверить вывод от ssh, чтобы убедиться в этом.

3
27.01.2020, 23:24

Клиент OpenSSH может запрашивать пользователя либо через терминал, либо через дисплей X11. Если вы хотите быть уверенным, что пользователю не будет предлагаться запрос, организуйте запуск клиента без управляющего терминала и без X-дисплея. Избавиться от отображения X легко: отключите переменную среды DISPLAY или установите для нее пустую строку. Чтобы запустить процесс без управляющего терминала, запустите его в отдельном сеансе. Для этого нет утилиты POSIX, но в Linux есть утилита setsid .

DISPLAY= setsid ssh …

Обратите внимание, что запуск клиента SSH в его собственном сеансе также запускает его в своей собственной группе процессов. Основное практическое следствие использования setsid состоит в том, что если сценарий выполняется из интерактивной оболочки, Ctrl + C не убивает клиента SSH; вы должны поместить ловушку для SIGINT в свой скрипт, которая убивает клиента SSH.

ssh_pid=
trap INT TERM 'if [ -n "$ssh_pid" ]; then kill "$ssh_pid"; fi'
DISPLAY= setsid ssh … &
wait "$ssh_pid"
unset ssh_pid

Помните, что ssh возвращает код состояния 0, если он не может установить соединение из-за ошибки проверки ключа хоста. Вам нужно будет полагаться на что-то еще, чтобы определить, удалась ли команда.

0
27.01.2020, 23:24

Теги

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