У меня странная установка: мне нужно запустить команду как контейнер докера в блоке sh
в файле Jenkins.
Проблема, с которой я столкнулся, связана с командой awk
, используемой для обрезки вывода.
Вот команда, которая РАБОТАЕТ ОТЛИЧНО при запуске непосредственно в оболочке bash :
OPFILENAME=$(docker run -t \
-e AWS_SECRET_ACCESS_KEY='<omitted>' \
-e AWS_ACCESS_KEY_ID='<omitted>' \
-e AWS_DEFAULT_REGION='us-east-1' \
mydockerimage:0.1 \
bash -c "aws s3 ls my-bucket-name/dir/ | sort | tail -n 1 | awk '{print \$4}' ") && \
echo $OPFILENAME
Так что мне нужно запустить то же самое на удаленном хосте через конвейер Jenkins , вот общий синтаксис:
pipeline {
agent any
environment {
BUILDHOST = 'buildhost.example.com'
SSHCMD = "ssh -o StrictHostKeyChecking=no jenkins@${env.BUILDHOST}"
}
stages {
stage('Get filename from s3') {
steps {
sshagent ( ['ssh_config']) {
sh """${SSHCMD} '''
OPFILENAME=\$(sudo docker run -t \
-e AWS_SECRET_ACCESS_KEY='<omitted>' \
-e AWS_ACCESS_KEY_ID='<omitted>' \
-e AWS_DEFAULT_REGION='us-east-1' \
mydockerimage:0.1 \
bash -c "aws s3 ls my-bucket-name/dir/ | sort | tail -n 1 | awk '{print \$4}') && \
echo \$OPFILENAME
'''
"""
}
}
}
}
}
Вот ошибка, которую выдает Дженкинс:
...bash -c "aws s3 ls my-bucket-name/dir/ | sort | tail -n 1 | awk {print' '}") && echo $OPFILENAME "
'
bash: -c: line 1: unexpected EOF while looking for matching `"'
bash: -c: line 3: syntax error: unexpected end of file
Обратите внимание, как он преобразовал команду awk
как таковую: awk {print ''}
Попытка с различными изменениями: ... | сортировать | хвост -n 1 | awk \ '{print \ $ 4} \' ")
приводит к точно такой же ошибке.
Пробовал вот так: awk" '{print \ $ 4}' "
и это не выдает ошибку , но в журналах это отображается следующим образом: awk "{print ''}"
, поэтому желаемая обрезка awk не выполняется. Grr!
Итак, я знаю, что с цитированием что-то не так, и поскольку я использую тройные кавычки для многострочных команд, это еще больше загрязняет их!
Я сослался на эту суть, пытаясь понять, как это сделать: https://gist.github.com/Faheetah/e11bd0315c34ed32e681616e41279ef4 , но проблема по-прежнему возникает после ошибки.
Предостережения:
- Команда должна выполняться в блоке sshagent
и на удаленном хосте. Команды нельзя запускать в локальной рабочей области Jenkins.
Ошибка из-за пропущенной двойной кавычки между '{печать \$4}'
и )
. Она есть в вашем оригинальном скрипте, но не в Jenkinsfile.
Тем не менее, это очень сложная проблема, так как несколько процессов будут вскрывать/обрабатывать кавычки. Во-первых, есть сам Груви. Затем есть команда Jenkin sh
(плюс процесс оболочки, который запустит команда), затем ssh
, затем удаленная оболочка, которая ssh
будет запущена, затем bash
, которую вы запустите. Один из них - это удаление \
перед $4
, который разбивает ваш скрипт AWK.
Вы можете попытаться исправить эту специфическую проблему, используя awk -f script
или используя sed
, чтобы свести несколько пробелов в один и затем используя cut
: ... | sed -e 's/ +/ /g' | cut -d " " -f 4 | ...
Но в конце концов, он всегда будет хрупким.
Я настоятельно рекомендую создать файл скрипта, скопировать его на удаленный хост и запустить ssh bash ./script.sh
. Это удалит столько головной боли. Кроме того, вы сможете тестировать и отлаживать скрипт из командной строки без необходимости проходить через Jenkins после каждого изменения.
Альтернативно, поместите большую часть скрипта в пользовательский образ докера и выберите это в качестве команды по умолчанию для образа.
Использование плагина SSH Pipeline Steps может помочь, так как у него есть опция "sshScript", которая копирует скрипт на удаленный сервер, а затем выполняет его там же: https://github.com/jenkinsci/ssh-steps-plugin#sshscript