Jenkins实现持续集成中的那些坑

小伙伴在《这些年我们一起搞过的持续集成~Jenkins+Perland Shell script》中详细介绍了优化后的job流,接下来总结一下在构建这一套job中遇到的Shell  Script和Jenkins的问题。

1.      比较两个文件后有特殊字符< 会导致Jenkins job failure;

解决方法:过滤特殊字符<同时利用diff–b去除最后的错位行,更多diff使用请参考diff--help;

-------------1)

[[email protected]]$ diff current.txt base.txt

1,2d0

<annzan

<wadexu

52c50

<davima

---

>davima

-----------2)

[[email protected]]$ diff -b current.txt base.txt

1,2d0

<annzan

<wadexu

-------------3)

[[email protected]]$ diff -b current.txt base.txt | grep "<"|sed ‘s/^<//g‘

annzan

wadexu

2.      awk按分隔符分段输出,例如 echo $PROJECT_LIST|awk –F “,”‘{print $1}’ 。 将PROJECT_LIST遍历输出,需要参数化输出段数,$$id肯定是不行的;

解决方法: echo $PROJECT_LIST|awk  -v id=$id  -F”,” ‘{print$id}’

这边之前也试过cut这个命令去分隔字符串, echo $PROJECT_LIST|cut  -f $id  -d “,” 但是这里有个问题,当PROJECT_LIST中没有,这个分隔符的时候,不论id是几结果都是本身。所以cut命令无法实现我们想要遍历所有project的初衷,除非强制PROJECT_LIST一定要有一个分隔符。

3.      用curl命令调用下一个job大大提高了我们job流程的灵活机动性,同时用data json将参数值也一起传递到下一个job,实现我们整个流程的参数化。

curl -X POST --user "jadmin:71103407"-s http://vm10686.global.test.net:8080/view/Template/job/Template_Service_Commit_Auto_Build/build --data json=‘{"parameter":[{"name":"PROJECT_NAME","value":"‘$projectName‘"},{"name":"PIPELINE_NUM","value":"‘$BUILD_NUMBER‘"}]}‘

注意: value后面双引号里面直接加值,如果是参数的话,需要在参数名外面加单引号。

4.       这里着重讲一下我们遇到的天坑,单引号,双引号再顺便提一下反引号和反斜杠。[转自互联网]

1. 单引号( ‘‘ )

# grep Susan phonebook

Susan Goldberg 403-212-4921

Susan Topple 212-234-2343

如果我们想查找的是SusanGoldberg,不能直接使用grep Susan Goldberg phonebook命令,grep会把Goldberg和phonebook当作需要搜索的文件

# grep ‘Susan Gold‘ phonebook

Susan Goldberg 403-212-4921

当shell碰到第一个单引号时,它忽略掉其后直到右引号的所有特殊字符

2. 双引号( " " ) 

双引号作用与单引号类似,区别在于它没有那么严格。单引号告诉shell忽略所有特殊字符,而双引号只要求忽略大多数,具体说,括在双引号中的四种特殊字符不被忽略:$,\,`,!,即双引号会解释字符串的特别意思,而单引号直接使用字符串.如果使用双引号将字符串赋给变量并反馈它,实际上与直接反馈变量并无差别。如果要查询包含空格的字符串,经常会用到双引号。

# x=*

# echo $x

hello.sh menus.sh misc.sh phonebook tshift.sh

# echo ‘$x‘

$x

# echo "$x"

*

这个例子可以看出无引号、单引号和双引号之间的区别。在最后一种情况中,双引号告诉shell在引号内照样进行变量名替换,所以shell把$x替换为*,因为双引号中不做文件名替换,所以就把*作为要显示的值传递给echo。对于第一种情况需要进一步说明,shell在给变量赋值时不进行文件名替换(这从第三种情况中也能看出来),各步骤发生的精确次序如下:
shell扫描命令行,把x的值设为星号*;

shell再次扫描命令行,碰到星号*,把它替换成当前目录下的文件清单;

shell启动执行echo命令,把文件清单作为参数传递给echo.

这个赋值的先后次序非常重要:shell先作变量替换,然后作文件名替换,最后把这行处理为参数

3. 反引号(``)

命令替换是指shell能够将一个命令的标准输出插在一个命令行中任何位置。shell中有两种方法作命令替换:把shell命令用反引号或者$(...)结构括起来,其中,$(...)格式受到POSIX标准支持,也利于嵌套。

# echo The date and time is `date`

The date and time is 三 6月 15
06:10:35CST 2005

# echo Your current working directory is $(pwd)

Your current working directory is/ home/annzan/test

4. 反斜杠backslash-escaped( \ )

反斜杠一般用作转义字符,或称逃脱字符,linux如果echo要让转义字符发生作用,就要使用-e选项,且转义字符要使用双引号

echo -e "\n"

反斜杠的另一种作用,就是当反斜杠用于一行的最后一个字符时,shell把行尾的反斜杠作为续行,这种结构在分几行输入长命令时经常使用。

5.      由单双引号引发的血案还有很多,比如下面遇到的中括号,if后面加中括号,注意加空格,可是结果却总是不对:

整了半天发现还是双引号的问题,字符串比较需要把$test放在双引号里,或者在外面再加一个中括号:

6.      grep和egrep的使用区别

1)     grep  [option]  pattern  filename 注意: pattern如果是表达式或者超过两个单词的, 需要用引号引用. 可以是单引号也可双引号, 区别是单引号无法引用变量而双引号可以.

2)     egrep= grep -E 可以使用基本的正则表达外, 还可以用扩展表达式. 注意区别.

扩展表达式:

+ 匹配一个或者多个先前的字符, 至少一个先前字符.

? 匹配0个或者多个先前字符.

a|b|c 匹配a或b或c

() 字符组, 如: love(able|ers) 匹配loveable或lovers.

(..)(..)\1\2 模板匹配. \1代表前面第一个模板, \2代第二个括弧里面的模板.

x{m,n} =x\{m,n\} x的字符数量在m到n个之间.

具体使用请参考grep –help;  egrep -- help

7.      当参数名是参数时,取值用eval。 例如configfile中每个定义两个project的GIT_PROJECT_NAME,用projectname作为前缀:

PROA_GIT_PROJECT_NAME=git_proa

PROB_GIT_PROJECT_NAME=git_prob

当用project name作为参数时,$($PROJECT_NAME_GIT_PROJECT_NAME)是没有这种写法的,正确取值如下: GIT_PROJECT_NAME=${PROJECT_NAME}"_GIT_PROJECT_NAME"

GIT_PROJECT_NAME=$(eval echo\${$GIT_PROJECT_NAME})

8.      大侠用perl语言写了打包安装等核心功能,需要执行这些脚本前,需要把脚本路径加到path里,要不然有核心代码也执行不了:

1)     把路径添到PATH路径里面

cd ${SCRIPTS_HOME}

chmod 755 *

export PATH=$PATH:`pwd`

2)      直接修改.bashrc文件

[[email protected] ~]$ vim .bashrc

文件被打开如下

# .bashrc

# Source global definitions

if [ -f /etc/bashrc ]; then

. /etc/bashrc

fi

# User specific aliases and functions

export PATH=/home/annzan/bin:$PATH

-----增加自己的Path,在已有:$PATH的之前 保存并退出

[[email protected] ~]$ . .bashrc

.相当于source让修改生效

[[email protected] bin]$ echo $PATH

/home/annzan/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin

9.      上面讲到.bashrc文件,就顺便记录一下.bashrc和.bash_profile文件的区别:

/etc/profile: 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。并从/etc/profile.d目录的配置文件中搜集shell的设置;

/etc/bashrc: 为每一个运行bashshell的用户执行此文件.当bashshell被打开时,该文件被读取;

~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件;

~/.bashrc:该文件包含专用于你的bashshell的bash信息,当登录时以及每次打开新的shell时,该文件被读取;

~/.bash_logout:当每次退出系统(退出bashshell)时,执行该文件;

另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承/etc/profile中的变量,他们是"父子"关系。

~/.bash_profile 是交互式、login方式进入bash 运行的

~/.bashrc 是交互式non-login 方式进入bash 运行的

通常二者设置大致相同,所以通常前者会调用后者。

设置生效:可以重启生效,也可以使用命令:source

10.  小数之间的比较用bc, 不是整数比较,不可以简单的用大于小于来比较;

if [ $(echo "$code_coverage_integer< $SONAR_MIN_COVERAGE" |
bc) ]   or

if (( $(echo "$code_coverage_integer< $SONAR_MIN_COVERAGE" |
bc) ))

注意 : 对于数据比较有以下两种格式:

以下是文件,字符串和算术比较运算符:

11.  换行问题;

1)     字符串换行:

mail_body="Hi,${PROJECT_NAME}"" project member"$‘\n‘"Alerts"

2)     echo写入文件换行:

echo -e "exportCONFIG_TIME=${CURRENT_TIME}\n

exportPROJECT_LIST=${PROJECT_LIST}\n

exportSHARED_FOLDER=~/jenkins/common\n" > config.txt

12.  通过git commit hash来判断代码有没有更新,取当前commit hash与base hash对比,有不一样,打包安装,并把当前的commithash放入base文件;同理,取出当前所有的author list,与base list对比,取出代码修改的所有作者。

git log --max-count=1--pretty=format:"%H" > ${CURRENT_MD5_FILE}

gitlog --pretty=format:"Author: %an" > ${CURRENT_AUTHOR_LIST}

Refer to git log paras: https://www.kernel.org/pub/software/scm/git/docs/git-log.html

13.  从pom.xml 文件中取一指定节点的值:

例如<name>testService</name>,取testService值:

1)sed -n‘/name/{s/.*<name>\(.*\)<\/name>.*/\1/p;q;}‘ pom.xml

2)catpom.xml|sed -n ‘/name/p‘|awk -F "[<>]" ‘{print $3}‘

如果取的值是一个数字,例如<num>12</ num >,我们可以通过取数字得到;

cat pom.xml | sed -n ‘/ num /p‘ | sed -r‘s/([^0-9]*([0-9]*)){1}.*/\2/‘

但是当num显示的值为1,000时,就只能取到1 而 不是1,000。所以 还是上面两种方法比较奏效。

14.  JSON对象取值,示例如下:

JSON 对象:

response=‘{"name"="annzan","value"="test"}‘

用如下方法取值:

function jsonValue(){

KEY=$1

VALUE=$2

awk -F"[,:}]" ‘{for(i=1;i<=NF;i++){if($i~/‘$KEY‘\042/){print $(i+1)}}}‘ | tr -d ‘"‘ | sed -n ${VALUE}p

}

如果要取到name里的值annzan,调用jsonValue方法并输入相应的Key值:

15.  在linux系统中,可以使用mount命令挂载光盘镜像文件、移动硬盘、U盘以及Windows网络共享和UNIX NFS网络共享等,这里主要介绍一下Linux系统中NFS文件共享;

1) 首先要看一下需要被挂载盘的文件地址:  df  /mnt/ifs10001

2)在需要挂载的系统中创建相应文件夹:mkdir /mnt/ifs10001

3)实现挂载共享文件:mount -t nfs isiloncwy0001.transfer.test.net:/ifs/data/transfer/clients /mnt/ifs10001

具体可以参考http://www.jb51.net/os/RedHat/1109.html

16.  Jenkins自身设定的按时启动job,时间是有延迟的,比如我设置为下午4点,可是却发现没有动静,后来发现每天都是4点15运行job。而且这个设置的时间是jenkins服务器的时间不是本机时间。设置格式如下:

例如设置每周一到周五,3点钟执行job。设置定时任务:  H 3 * *  1-5

17.  Jenkins中执行job前大都需要先export 环境变量,我们可以不需要手动写shell 脚本,可以在Jenkins Nodeconfig页面设置Node属性,如下图:

18.  除了在Node端设置环境变量,我们也可以在Jenkins系统设置进行全局设置,例如MAVEN_OPTS或者账号密码, $ENV{USERNAME}即为调用账号;

19.  因为我们现在用Git管理代码库,所以在Jenkins中要checkout代码,需要先设置git账号,把key配置在Jenkins的ManageCredentials中,如下图:

时间: 2024-08-26 17:38:26

Jenkins实现持续集成中的那些坑的相关文章

jenkins+github持续集成中的坑

1.前言 刚开始开发自己的独立博客的时候,每次发布都要手动打包,上传服务器,杀tomcat进程,重启,来回这么重复性工作,很快就有点不耐烦了.如果能自动化的东西,就绝不要手动了,所以自己搭建了个持续集成环境,配好了结合github进行push时自动构建,自动发布的流程,提交代码,泡杯咖啡就发布好了.本以为很简单,但没想到中间细节还是有不少坑,查了很多资料,墙都翻了好几次,把遇到的问题记录在这里. 2.正文 详细安装教程就不复制粘贴了,推荐此文手把手教你搭建Jenkins+Github持续集成环境

Jenkins Gitlab持续集成打包平台搭建

相关概念 Jenkins Jenkins,一个用Java编写的开源的持续集成工具,提供了软件开发的持续集成服务,可监控并触发持续重复的工作,具有开源,支持多平台和插件扩展,安装简单,界面化管理等特点.更多介绍参考[维基](https://en.wikipedia.org/wiki/Jenkins_(software)介绍. Gitlab GitLab是一个利用Ruby on Rails开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目,更多介绍参考维基

【iOS】Jenkins Gitlab持续集成打包平台搭建

Jenkins Gitlab持续集成打包平台搭建 SkySeraph July. 18th 2016 Email:[email protected] 更多精彩请直接访问SkySeraph个人站点:www.skyseraph.com 1. 相关概念 Jenkins Jenkins,一个用Java编写的开源的持续集成工具,提供了软件开发的持续集成服务,可监控并触发持续重复的工作,具有开源,支持多平台和插件扩展,安装简单,界面化管理等特点.更多介绍参考维基介绍. Gitlab GitLab是一个利用R

使用jenkins构建持续集成平台

jenkins +   Maven + svn/git + tomcat 的持续集成平台 项目管理流程: 需求分析----原型设计----开发代码----提交测试-----内部测试-----确认上线(确认上线前可能经过多种环境的测试) ------上线到生产环境-----最终测试------如果出现问题代码回滚. 传统代码上线: 开发人员开发完成-----打好包(war.jar)-----交给运维人员上线(上传.拷贝) jenkins持续集成简介: 持续集成是一种软件开发实践,对于提高软件开发效

jenkins gulp 持续集成环境搭建

本文假设你之前没有用过任何任务脚本(task runner)和命令行工具,一步步教你上手Gulp.然后教你jenkins如何集成前端构建工具Gulp.不要怕,jenkins gulp 持续集成环境搭建其实也很简单,我会分为五步向你介绍jenkins gulp 持续集成并帮助你完成一些惊人的事情.那就直接开始吧. 第一步:安装Node 首先,最基本也最重要的是,我们需要搭建node环境.访问 https://nodejs.org/en/download/ 下载得到这样的一个文件node-v6.9.

用MSBuild和Jenkins搭建持续集成环境(2)

http://www.infoq.com/cn/articles/MSBuild-2 作者 Mustafa Saeed Haji Ali ,译者 李剑 发布于 2012年10月23日 | 注意: 挥一挥衣袖,带走满满干货,关注活动大本营,时不时发福利呦!3 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 稍后阅读 我的阅读清单 这是持续集成系列的下半部分,如果你还没看过上半部分的话,请点击这里:用MSBuild和Jenkins搭建持续集成环境(1). 与Jenkins相会

jenkins + Tomcat 持续集成环境搭建

今天在跑selenium用例时需要用到导入数据库来恢复数据,以便每次测试都保持环境是有效数据,于是想到了jenkins,这里简单介绍一下tomcat + jenkins的环境搭建: 步骤一.下载符合版本的jdk7,触压到某个目录,设置好JAVA_HOME并加入path. 步骤二.下载tomcat,这里使用的是apache-tomcat-7.0.42步骤三.下载Jenkins,把Jenkins.war放入tomcat的webapps目录下,启动tomcat,通过http://localhost:8

RF+Jenkins构建持续集成

引入RF是为了能够快速的开展自动化验收测试,Jenkins而一种持续集成工具,用于监控持续重复的工作,持续的软件版本发布/测试项目,而通过RF+Jenkins可以有利的对RF构建的接口项目进行持续集成测试.Jenkins另一个强大之处就是它的分布式构建(在Jenkins的配置中叫做节点),分布式构建能够让同一套代码在不同的环境(如:Windows和Linux系统)中编译.测试等.而且Jenkins构建的代码和产物最后自动拷贝到主节点. 简单概括而言,结合RF+Jenkins开展持续集成基本步骤:

使用jenkins实现持续集成

一.jenkins 介绍 它是一个自动化的周期性的集成测试过程,从检出代码.编译构建.运行测试.结果记录.测试统计等都是自动完成的,无需人工干预,有利于减少重复过程以节省时间.费用和工作量: 它需要有专门的集成服务器来执行集成构建: 它需要有代码托管工具支持,比如SVN: 官网地址地址:https://jenkins.io Jenkins的主要目标是监控软件开发流程,快速显示问题: jenkins持续集成中的任何一个环节都是自动完成的,无需太多的人工干预,所以它有利于减少重复过程以节省时间.费用