Команды Bash выполняются в терминале, но не в скрипте Jenkins/Bash

Я использую Jenkins для создания и развертывания HTML-документации на локальном веб-сервере Apache для использования нашими разработчиками. Когда я запускаю команды в терминале, все устанавливается правильно (проверка правильности настройки сервера). Однако при запуске тех же команд из Jenkins они вызываются, но ничего не меняется. Не удаляет html.zip (Строка 18), не перемещает файлы в /var/html/www/subdirи не сообщает об ошибках за пределами curl запрос не выполнен Я немного растерялся относительно того, что я делаю неправильно.

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

Дженкинс называет этот сценарий так:sudo ./documentation-publisher.sh

Разрешения на скрипт являются наименее ограничивающими на данный момент, 777. Вызов ls -l по сценарию сообщает:-rwxrwxrwx 1 devop developers 1144 Dec 3 10:29 documentation-publisher.sh

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

#!/bin/sh -x

echo "Archiving generated HTML for transfer..."
cd Example/docs/html/
zip -r html.zip ./
scp -i ~/.ssh/id_rsa html.zip user@my.host.example.com:/home/user 
ssh -i ~/.ssh/id_rsa user@my.host.example.com 

echo "Extracting generated HTML into www directory..."
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
unzip -o html.zip -d ./subdir
rm -r /var/www/html/subdir
mkdir /var/www/html/subdir
cp -r ./subdir/* /var/www/html/subdir/

echo "Cleaning up after file transfer..."
rm -rf ./subdir 
rm ./html.zip 

echo "Testing install..."
curl -f my.host.example.com/subdir/index.html 
exit 

Что я могу делать не так?

2 ответа

Решение

Похоже, вы хотите ssh в my.host.example.com, затем оставьте скрипт на этом хосте. Если это так, вам нужно передать оставшуюся часть скрипта в качестве входных данных для ssh команда; как сейчас, ssh принимает входные данные из stdin скрипта, который, вероятно, пустой, поэтому он открывает сеанс удаленной оболочки, отправляет ему конец файла, который закрывает ssh сеанс и выполняет оставшуюся часть сценария локально. Для того чтобы выполнить эти команды удаленно, вам необходимо передать их в качестве входных данных ssh команда, что-то вроде этого:

ssh -i ~/.ssh/id_rsa user@my.host.example.com <<EOF

echo "Extracting generated HTML into www directory..."
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
[...]
exit
EOF

Во-вторых, в скрипте нет проверки ошибок. В целом, это хорошая идея, чтобы посмотреть на каждую команду в сценарии и спросить себя, что произойдет, если она потерпит неудачу. Должна ли продолжаться остальная часть сценария, или он "сбежит с рельсов" и сделает что-то глупое? Например, если scp команда должна была потерпеть неудачу (по какой-либо причине), не было бы никакого смысла в запуске остальной части скрипта (и это могло бы быть разрушительным, стирая /var/www/html/subdir и затем заменяя его на... oops, ничего такого). Вы можете запустить проверку ошибок для состояния выхода каждой отдельной команды, например:

scp -i ~/.ssh/id_rsa html.zip user@my.host.example.com:/home/user || {
    echo "Failed to scp the html files to my.host.example.com." >&2
    exit 1
}

... или использовать оболочку -e возможность заставить его выйти из скрипта, если какая-либо команда не удалась. Эта опция избавляет вас от необходимости проверять каждую команду по отдельности, но не дает информативных сообщений об ошибках и может вызвать проблемы при выходе из сценария, если что-то неважное возвращает состояние ошибки по какой-либо причине (см. BashFAQ #105 для некоторых примеров того, почему -e может вызвать неожиданное поведение). Кроме того, если вы используете эту опцию, убедитесь, что вы используете set -e оба в начале сценария (или использовать -xe на линии Шебанга) и добавить set -e как первая команда, отправленная на удаленный компьютер.

Кстати, cd Команда в строке 4, скорее всего, потерпит неудачу, так как использует относительный путь. Это означает, что каталог, который он пытается cd зависит от рабочего каталога, из которого был запущен скрипт. Обратите внимание, что это не обязательно каталог, в котором находится скрипт, он наследуется от процесса, который запустил скрипт, и, следовательно, может быть почти любым. Дженкинс может запускать сценарий с другим рабочим каталогом, чем у вас, что приводит к его выходу из строя. Ну, на самом деле не сбои, просто запустите все оставшиеся команды в неправильном каталоге (и из-за ssh проблема ввода, на неправильном хосте).

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

rm ./html.zip cp -r ./subdir/* /var/www/html/subdir/

изменить ./ часть до полного пути к этому файлу или каталогу.

Другие вопросы по тегам