Я работаю над платформой, которая использует много таких команд: ssh login@server.com 'curl http://some_server/script.sh | bash'
Это действительно чисто и удобно для удаленного выполнения сценариев, однако я не вижу возможности получить код вывода / выхода сценария. Любой может что-то выяснить, чтобы убедиться, что сценарий был правильно выполнен (с хоста, запускающего точку зрения ssh).
Как отмечает @Zoredache, ssh
передает статус удаленной команды как собственный статус выхода, поэтому обнаружение ошибок прозрачно работает через SSH. Однако два важных момента требуют особого внимания в вашем примере.
Первый, curl
имеет тенденцию быть очень снисходительным, рассматривая многие ненормальные состояния как успех. Например, curl http://serverfault.com/some-non-existent-url-that-returns-404
на самом деле имеет статус выхода 0. Я считаю такое поведение нелогичным. Чтобы рассматривать эти условия как ошибки, мне нравится использовать -fsS
флаги:
--fail
флаг подавляет вывод при сбое, так что bash
не будет возможности выполнить страницу ошибки 404 веб-сервера, как если бы это был код.--silent --show-error
флаги вместе обеспечивают разумное количество сообщений об ошибках. --silent
подавляет все комментарии от curl
. --show-error
повторно включает сообщения об ошибках, которые отправляются в STDERR.Во-вторых, у вас есть канал, а это означает, что сбой может произойти либо в первой, либо во второй команде. Из раздела про Конвейеры в bash (1):
Статус возврата конвейера - это статус выхода последней команды, если только
pipefail
опция включена (см. Набор Встроенный). Еслиpipefail
включен, статус возврата конвейера - это значение последней (самой правой) команды для выхода с ненулевым статусом или ноль, если все команды завершаются успешно.
Боковое примечание: bash
документация актуальна не потому, что вы bash
, но потому что (я предполагаю) это оболочка входа в систему вашего удаленного пользователя и, следовательно, это программа, которая интерпретирует удаленную командную строку и обрабатывает выполнение конвейера. Если у пользователя другая оболочка входа в систему, обратитесь к документации по этой оболочке.
В качестве конкретного примера:
( echo whoami ; false ) | bash
echo $?
дает результат
login
0
демонстрируя, что bash
в конце конвейера маскирует статус ошибки, возвращаемый false
. Он вернет 0, пока он успешно выполняется whoami
.
Напротив,
set -o pipefail
( echo whoami ; false ) | bash
echo $?
дает
login
1
так что сообщается об отказе в первой половине трубопровода.
Собирая все вместе, решение должно быть
ssh login@server.com 'set -s pipefail ; curl -fsS http://some_server/script.sh | bash'
Таким образом, вы получите ненулевой статус выхода, если любой из следующих результатов вернет ненулевое значение:
ssh
curl
bash
в конце конвейераКроме того, если curl -fsS
обнаруживает ненормальный код состояния HTTP, затем он:
bash
быть выполненнымКогда SSH вернется, он должен выдать код выхода из скрипта.
Пытаться ssh user@host 'echo "exit 2" | bash' ; echo $?
. Вы должны увидеть значение 2
вернулся.
Просто напишите много хороших проверок ошибок в вашем скрипте и убедитесь, что ваш скрипт завершается с полезными ошибками и кодами выхода. Убедитесь, что ваш скрипт возвращает ненулевые коды выхода при любых ошибках.
Это ужасный взлом. Если вы хотите удаленное выполнение, используйте что-то, что выполняет удаленное выполнение должным образом, например func или mcollective.
Вот несколько вариантов, которые вы можете попробовать.
Другой способ - использовать echo $? запускается сразу после выполнения скрипта,
# ssh login@server.com 'curl http://some_server/script.sh | bash; echo $?'
Это даст вам статус выхода скрипта. или Предоставляйте текст, только если статус выхода равен 0
# ssh login@server.com 'curl http://some_server/script.sh | bash && echo "Script Completed!"'
Появится сообщение «Сценарий завершен!» при успешном исполнении. или Отображать код ошибки, только если статус выхода не равен 0
# ssh login@server.com 'curl http://some_server/script.sh | bash || echo "Script Failed: $?"'
Будет отображено сообщение «Script Failed:». Как было предложено @Zoredache, добавление нескольких статусов выхода к вашему скрипту поможет вам определить, что пошло не так.
Все будет зависеть от того, что script.sh ДЕЛАЕТ / выполняет свою работу. Если он подробный (выполняет то, что имеет вывод), вы сможете увидеть их в STDOUT / STDERR в своем потоке ssh. Если если не измените его, сделайте это.