bash - 与本地相比,Grep 在 Travis 上的行为不同
问题描述
我继承了一个构建脚本,该脚本通过获取已更改文件的列表并确保它们具有包含当前年份的版权声明来检查我们的 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
而在特拉维斯它打印:
Year line in main.go is ' * (C) Copyright IBM Corp. 2017, 2018 All Rights Reserved.'
Years is
如您所见,它找到了版权行,但从中提取YEARS
( YEARS=($(echo $YEAR_LINE | grep -oE '\d{4}'))
) 的命令失败。我已经阅读了 grep 的手册页,但不明白为什么这个命令的行为会有所不同。
解决方案
转义是一个 Perl 扩展,如果没有其他选项\d
,通常不支持它。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
推荐阅读
- symfony - 从 composer.json [Symfony] 获取版本
- php - Sqlite 在 php 中没有返回正确的主键
- mqtt - Nifi 错误:无法自动终止“消息”关系,因为此关系已存在连接
- php - 让 ReCaptcha 与 formhandler.php 一起工作的问题
- gulp - gulp-inject 注入错误的文件顺序
- wordpress - 如何在 shopify 博客中添加类别,如 wordpress 博客?
- php - 使用访问者 ip 从页面中抓取 url
- d3.js - 自定义 SVG 形状的信息图条件填充
- javascript - 当我访问对象的值时获取未定义的值
- amazon-web-services - Terraform - AWS EC2 IAM 角色