Синтаксис конвейера Дженкинса: боль в кавычках при использовании блоков с несколькими кавычками

У меня какая-то странная настройка, которая мне нужна для запуска команды в качестве контейнера докера в sh заблокировать в Jenkinsfile.

Проблема, с которой я сталкиваюсь, касается awk Команда используется для обрезки вывода.

Вот команда, которая РАБОТАЕТ FINE, когда запускается непосредственно в оболочке 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' '}

Попытка с различными изменениями: ...| sort | tail -n 1 | awk \'{print \$4}\'") приводит к точно такой же ошибке.

Попробовал вот так: awk "'{print \$4}'" и это не выдает ошибку, но в журналах это показывает так: awk "{print' '}" таким образом, желаемое сокращение awk не происходит. Grr!

Так что я знаю, что с кавычками что-то не так, и поскольку я использую тройные кавычки для многострочных команд, это портит их еще больше!

Я ссылался на эту суть, пытаясь понять, как это сделать: https://gist.github.com/Faheetah/e11bd0315c34ed32e681616e41279ef4 но все еще сталкиваюсь с проблемой после проблемы.

Предостережения: - Команда должна выполняться в sshagent блок и на удаленном хосте. Команды не могут быть запущены в локальной рабочей области Jenkins.

1 ответ

Ошибка из-за отсутствия двойной кавычки между '{print \$4}' а также ), У вас есть это в вашем оригинальном сценарии, но нет в Jenkinsfile.

Тем не менее, это очень сложная проблема, так как несколько процессов будут отбрасывать / обрабатывать цитаты. Во-первых, это Groovy. Тогда есть Дженкинс 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

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