涉及 grep 的相同 bash 脚本在一台机器上成功但在另一台机器上失败
Same bash script involving grep succeeds on one machine but fails on another
我有以下 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 运行ner 使用 python:3.8 图像执行。
测试在 运行ner 上失败,似乎模式匹配断言失败。
我注意到 运行ner 使用的是 grep 版本 3.3-1,而我在本地机器上使用的是版本 3.4,但在查看之后,并没有太大区别。
此外,我确实获取了 运行ner 生成的输出并在本地测试它以尝试匹配相同的正则表达式,并且确实匹配。
我不知道为什么会存在这种差异。
按照@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'
我有以下 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 运行ner 使用 python:3.8 图像执行。
测试在 运行ner 上失败,似乎模式匹配断言失败。
我注意到 运行ner 使用的是 grep 版本 3.3-1,而我在本地机器上使用的是版本 3.4,但在查看之后,并没有太大区别。
此外,我确实获取了 运行ner 生成的输出并在本地测试它以尝试匹配相同的正则表达式,并且确实匹配。
我不知道为什么会存在这种差异。
按照@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'