我正在尝试写一个git钩子,它可以让我在提交后收集单元测试报告。
我在windows机器上,但使用bash为钩子本身。它似乎运行得很好。以下是目前为止的内容:
#!/bin/sh
test_summary=$(pytest -v | grep -E ".+.py::.+[A-Z]+")
commit_id=$(git rev-parse HEAD)
问题是变量test_summary
只保留grep
匹配的最后一行。我知道我的管道pytest
/grep
是好的,因为在交互式msys终端上运行它会给出所有匹配项的正确输出:
$ pytest -v | grep -E ".+.py::.+[A-Z]+"
test_main.py::test_main PASSED [ 33%]
test_main.py::test2 FAILED [ 66%]
test_main.py::test3 PASSED [100%]
test_summary
包含以下内容:
$ echo $test_summary
test_main.py::test3 PASSED [100%]3%]
为什么它只保留最后一行加上第一行的一些胡言乱语?
我不明白....
br
OP在windows环境中运行这些命令,因此(在本例中)变量被加载为rn
行结尾。
$ test_summary=$(pytest -v | grep -E ".+.py::.+[A-Z]+")
$ test_summary="$(test_summary//$'r'/}" # strip out 'r' characters
$ echo $test_summary
test_main.py::test_main PASSED [ 33%]
test_main.py::test2 FAILED [ 66%]
test_main.py::test3 PASSED [100%]
继续查看详情…
我们可以用下面的命令模拟这个行为:
$ cat pytest.out
test_main.py::test_main PASSED [ 33%]
test_main.py::test2 FAILED [ 66%]
test_main.py::test3 PASSED [100%]
# convert to windows/dos line endings:
$ unix2dos pytest.out
# load variable:
$ test_summary=$(cat pytest.out)
# verify 'rn' lines endings loaded into variable:
$ od -c <<< "$test_summary"
... snip ... 3 3 % ] r n t e s t ... snip ...
# eumlate OP's echo/output:
$ echo $test_summary
test_main.py::test3 PASSED [100%]3%] <== 'r' causes lines to overwrite the same one line
用双引号括起$test_summary
有帮助:
$ echo "$test_summary"
test_main.py::test_main PASSED [ 33%]
test_main.py::test2 FAILED [ 66%]
test_main.py::test3 PASSED [100%]
或者,我们可以从变量中删除r
行结尾,例如:
$ test_summary="$(test_summary//$'r'/}"
$ od -c <<< "$test_summary"
... snip ... 3 3 % ] n t e s t ... snip ...
$ echo $test_summary
test_main.py::test_main PASSED [ 33%] test_main.py::test2 FAILED [ 66%] test_main.py::test3 PASSED [100%]
# still need to wrap in double quotes to properly display all spaces and line endings:
$ echo "$test_summary"
test_main.py::test_main PASSED [ 33%]
test_main.py::test2 FAILED [ 66%]
test_main.py::test3 PASSED [100%]
在将输出保存在变量中之前剥离r
字符的其他几个想法:
$ test_summary=$(pytest -v | grep -E ".+.py::.+[A-Z]+" | tr -d 'r')
$ test_summary=$(pytest -v | grep -E ".+.py::.+[A-Z]+" | sed 's/r//g')
$ test_summary=$(pytest -v | grep -E ".+.py::.+[A-Z]+" | dos2unix)
删除r
字符也可以在pytest
调用之后和grep
调用之前应用(例如,pytest -v | dos2unix | grep -E ...
)。
试试mapfile:
...
mapfile -t test_summary <(pytest -v | grep -E ".+.py::.+[A-Z]+")
...
或
mapfile -t test_summary <<< $(pytest -v | grep -E ".+.py::.+[A-Z]+")