与本地用户相比,Grep在Travis上的行为有所不同

时间:2019-01-04 06:28:44

标签: bash grep travis-ci

我继承了一个构建脚本,该脚本通过获取已更改文件的列表并确保文件上包含当年的版权声明来检查Travis构建中的版权声明。脚本中得出年份的部分是使用grep提取年份,如下所示:

GOSRCFILES=($(git diff --name-only origin/master | grep -v vendor | grep '\.go$'))
for GOFILE in "${GOSRCFILES[@]}"; do
  if grep -q "(C) Copyright" $GOFILE; then
      YEAR_LINE=$(grep -m 1 "(C) Copyright" $GOFILE)
      echo "Year line in ${GOFILE} is '${YEAR_LINE}'"
      YEARS=($(echo $YEAR_LINE | grep -oE '\d{4}'))
      echo "Years is ${YEARS[@]}"
  fi
done

这在本地(在Mac上)运行良好,但是在Travis上运行时失败。本地输出为:

Year line in main.go is ' * (C) Copyright IBM Corp. 2017, 2018 All Rights Reserved.'
Years is 2017 2018

在Travis上打印:

Year line in main.go is ' * (C) Copyright IBM Corp. 2017, 2018 All Rights Reserved.'
Years is 

如您所见,它正在找到“版权”行,但是从中提取YEARSYEARS=($(echo $YEAR_LINE | grep -oE '\d{4}')))的命令失败了。我已经阅读了grep的手册页,看不到为什么此命令的行为会有所不同。

1 个答案:

答案 0 :(得分:1)

转义\d是Perl扩展,grep通常不支持不带其他选项的扩展。请改用[0-9]或POSIX类[[:digit:]]。 (了解细微的差异; POSIX依赖于语言环境,但是在Travis上,语言环境可能不太实际。)

根据切线,如果只使用一次数组,则不要使用数组;并且您可以避免执行第一个grep两次;并且不要对您的私有变量使用大写;并引用您的变量;并将您的诊断信息打印为标准错误。

for gofile in $(git diff --name-only origin/master | grep -v vendor | grep '\.go$'); do
  if year_line=$(grep -m 1 "(C) Copyright" "$gofile"); then
    echo "Year line in $gofile is '$year_line'" >&2
    years=($(echo "$year_line" | grep -oE '[[:digit:]]{4}'))
    echo "Years is ${years[@]}" >&2
  fi
done