Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Разбиение строки на части в shell скрипте, запускаемом через jenkins pipeline

#linux #bash #shell #jenkins


Дано:

работающий shell код, разбивающий строку по точке и пишущий части полученные в переменные.

version='1.2.3.4'

IFS='.' read -r major minor micro build <<- _EOF_
$version
_EOF_

echo $major $minor


Задача:

Использовать его в рамках pipeline скрипта Jenkins

Проблема:

Т.к. мне надо использовать в shell скрипте переменные из pipeline я должен обернуть
shell код в 3 двойных кавычки. Из-за них мне надо всё подряд экранировать. И всё экранируется
кроме вот этого места:

stage('test') {
    steps {
        sh """
        version='1.2.3.4'

        IFS='.' read -r major minor micro build <<- _EOF_
        \$version
        _EOF_

        echo \$major \$minor
        """
    }
}


Если экранировать так: \$version - происходит попытка чтения pipline переменной и
падение. Если начать как-то извращаться - лезут уж совсем странные ошибки типа unexpected
end of file

Вопрос:

Как тут надо сделать? И почему проблема именно тут? У меня вообще довольно много
там кода, но экранирование не работает именно тут
    


Ответы

Ответ 1



Проблема заключается в том, что перед последовательностью символов, завершающих heredoc, должны быть только табуляторы (0х09), и наких пробелов, ни перед, ни после. Подробнее в этом ответе. О том, что редакторы могут заменять вводимые символы табуляции пробелами, см., например, связанный с ним вопрос. Чтобы не заботится об отступпах, можно просто удалить отступы методом stripIndent(). Фрагмент кода из вопроса будет выглядеть так: stage('test') { steps { sh """ version='1.2.3.4' IFS='.' read -r major minor micro build <<- _EOF_ \$version _EOF_ echo \$major \$minor """.stripIndent() } } PS этот ответ касается только "красоты" кода, о целесообразности здесь heredoc уже подробно отвечено в комментарии @alexanderbarakin.

Ответ 2



В итоге проблема оказалась в пробелах и табах, с помощью которых код станавится читаемым и красивым. Если код изуродовать так(убрав отступы): stage('test') { steps { sh """ version='1.2.3.4' IFS=. read a b c d <

Ответ 3



У меня получилось так: node { sh """echo -e "sqlplus ${dbuser}/${dbpass}@test << EOF select * from dual; EOF " > test.sh """ sh "bash -vx test.sh" }

Комментариев нет:

Отправить комментарий