【问题标题】:Same bash script involving grep succeeds on one machine but fails on another涉及 grep 的相同 bash 脚本在一台机器上成功,但在另一台机器上失败
【发布时间】:2020-04-19 00:54:51
【问题描述】:

我有以下 shell 脚本:


#!/bin/bash

# Calls AWS CloudFormation and creates the stack
STACKNAME="bootstrapStack"
TEMPLATEBODY=file://\$PWD/templates/bootstrapStack.yml
TEMPLATEVERSION=v0.1.0-alpha

if $( aws $AWSENDPOINTPARAM cloudformation describe-stacks --output text | grep -Eq "$STACKNAME" )
then 
    # output of above was similar to:
    # STACKS  2010-07-27T22:28:28Z    False   arn:aws:cloudformation:us-east-1:123456789:stack/bootstrapStack/16766dc5-75c9-4e3f-b4cf-7814d7fbbc6f      bootstrapStack  CREATE_COMPLETE
    # OUTPUTS TemplatesBucket dw-cloudformation-templates
    # PARAMETERS      TemplateVersion v0.1.0-alpha

    aws $AWSENDPOINTPARAM cloudformation update-stack \
        --template-body $TEMPLATEBODY \
        --stack-name $STACKNAME \
        --parameters "ParameterKey=TemplateVersion,ParameterValue=$TEMPLATEVERSION" \
        $*
else
    aws $AWSENDPOINTPARAM cloudformation create-stack \
        --template-body $TEMPLATEBODY \
        --stack-name $STACKNAME \
        --parameters "ParameterKey=TemplateVersion,ParameterValue=$TEMPLATEVERSION" \
        $*
fi

我使用shunit2 和moto_server 为上述脚本编写了一些单元测试。这是测试脚本:

#!/bin/sh

# Unit test for the deploy script of the stack

SCRIPT_UNDER_TEST=./scripts/createStack.sh
# set up
oneTimeSetUp(){
    if [[ ! -d "./test-logs" ]]
    then
        mkdir ./test-logs
    fi
}

setUp(){
    ( moto_server cloudformation >>test-logs/moto_server.log 2>&1 ) &
    export AWSENDPOINTPARAM=--endpoint="http://localhost:5000"
    sleep 5
}

match_stack_output(){
    # example match:
    # arn:aws:cloudformation:us-east-1:123456789:stack/bootstrapStack/2f255d54-f426-46b6
    assertTrue "Output Pattern does not match" \
        '$( \
            cat test_log | \
            grep -Eq \
                "^arn:aws:cloudformation:[[:alpha:]]{2}[-](east|west|south|north)-[[:digit:]]:[[:digit:]]*:stack\/bootstrapStack\/[[:alnum:]]*(-[[:alnum:]]*)*$" \
        )'
}

test_createStack(){
    . $SCRIPT_UNDER_TEST --output text >test_log

    match_stack_output
}

test_updateStack(){
    # if the stack already exists, the script should update the stack
    . $SCRIPT_UNDER_TEST --output text >test_log

    match_stack_output

    # call it again for update
    . $SCRIPT_UNDER_TEST --output text >test_log

    match_stack_output
}

# tear down
tearDown(){
    pkill moto_server
    echo Test Logs:
    cat test_log
    echo " "
    rm -rf test_log
}

. shunit2

现在我在本地机器上运行代码,测试顺利通过。

然后我将它推送到 gitlab,在这里测试脚本由 gitlab 运行器使用 python:3.8 图像执行。

运行器上的测试失败,并且模式匹配的断言似乎失败了。

我注意到运行器使用 grep 版本 3.3-1,而我在本地机器上使用的是 3.4 版本,但经过查看,并没有太大区别。

此外,我确实采用了运行器生成的输出并在本地对其进行了测试,以尝试匹配相同的正则表达式,它确实匹配。

我不知道为什么会存在这种差异。

【问题讨论】:

  • 请先将您的脚本粘贴到那里:shellcheck.net
  • @Cyrus,我再次检查了 shellcheck,这次它帮助我修复了它。谢谢,我会发布更正的脚本作为答案。
  • pluse-uno 获得优于平均水平的早期海报 Q 和以下建议!祝你好运,继续发帖。

标签: regex bash grep gitlab moto


【解决方案1】:

按照@Cyrus 的建议,转到shellcheck.net 并进行建议的更改。

解决它的解决方案 - 以下脚本:

assertTrue "Output Pattern does not match" \
        '$( \
            cat test_log | \
            grep -Eq \
                "^arn:aws:cloudformation:[[:alpha:]]{2}[-](east|west|south|north)-[[:digit:]]:[[:digit:]]*:stack\/bootstrapStack\/[[:alnum:]]*(-[[:alnum:]]*)*$" \
        )'

应该是:

assertTrue "Output Pattern does not match" \
        'grep -Eq "^arn:aws:cloudformation:[[:alpha:]]{2}[-](east|west|south|north)-[[:digit:]]:[[:digit:]]*:stack\/bootstrapStack\/[[:alnum:]]*(-[[:alnum:]]*)*$" <test_log'

【讨论】:

  • 如果有人能解释我的本地机器如何正确解释脚本,我将不胜感激。这是一些 bash 内部的东西吗?
  • 如果您自己运行 grep,您将获得您期望的退出代码。 $() 将始终返回 true - 除非由于资源问题而无法运行子进程。尝试在两种环境中执行此脚本:echo $( exit 1) &amp;&amp; echo That was successful 尽管退出时出现错误代码,但表达式的计算结果为 true 并且 That was successful 被打印出来。
  • 请注意x=$(exit 1); echo $? 与1 相呼应。当您执行echo $(exit 1); echo $? 时,您将获得echo 命令的状态,该命令成功地回显了一个换行符。
  • 或者干脆(exit 1); echo $?
  • 上面的好东西,我想说使用grep... &lt; test_log 可以进一步简化为grep .... test_log。 &lt; 并不是真正需要的,并且可能会使您的脚本的未来维护者感到困惑,使用通常意味着正在发生其他事情的功能。保持简单 ;-) 祝你好运,继续发帖。
猜你喜欢
  • 1970-01-01
  • 2015-01-14
  • 2018-01-06
  • 2021-12-03
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
  • 2019-11-20
  • 1970-01-01
相关资源
最近更新 更多