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

У меня странная установка: мне нужно запустить команду как контейнер докера в блоке 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.

1
задан 10 January 2019 в 04:00
1 ответ

Ошибка из-за пропущенной двойной кавычки между '{печать \$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

1
ответ дан 3 December 2019 в 23:09

Теги

Похожие вопросы