Назад | Перейти на главную страницу

Команды 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 

Что я делаю не так?

Похоже, ты хочешь 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/

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