我需要请求一个页面n次并计算返回的错误页数
ITERATIONS=100000
COUNTER=0;
COUNT_ERROR=0;
COUNT_EXPECTED=0;
while (( $COUNTER < $ITERATIONS )); do
COUNTER=$((COUNTER + 1));
curl http://www.example.com/example/path | grep -cim1 error;
if (( $? == 0 )); then
COUNT_ERROR=$((COUNT_ERROR + 1))
else
COUNT_EXPECTED=$((COUNT_EXPECTED + 1))
fi;
sleep 0.1;
done;
echo COUNT_ERROR=$COUNT_ERROR COUNT_EXPECTED=$COUNT_EXPECTED
此脚本正在返回
COUNT_ERROR=0 COUNT_EXPECTED=0
...所以if子句未按预期执行
以下是修订版(基于triplee的评论):
iterations=100000; count_error=0; count_expected=0; for ((counter = 0; counter < iterations; ++counter)); do if curl http://www.example.com/example/path | grep -iq error; then count_error=$((count_error + 1)) else count_expected=$((count_expected + 1)); fi; sleep 0.1; done; echo count_error=$count_error count_expected=$count_expected
然而输出仍然是
count_error=0 count_expected=0
注意:测试机器包括Windows 7 w / CygWin和MBP OSX Yosemite
这是完整输出:
bash-3.1$ iterations=10; count_error=0; count_expected=0; for ((counter = 0; counter < iterations; ++counter)); do if curl http://www.example.com/example/path
| grep -iq jetty; then count_error=$((count_error + 1)) else count_expected=$((count_expected + 1)); fi; sleep 0.1; done; echo count_error=$count_error count_e
xpected=$count_expected
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 431k 0 --:--:-- --:--:-- --:--:-- 431k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 666k 0 --:--:-- --:--:-- --:--:-- 666k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 735k 0 --:--:-- --:--:-- --:--:-- 735k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 490k 0 --:--:-- --:--:-- --:--:-- 490k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 408k 0 --:--:-- --:--:-- --:--:-- 408k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 735k 0 --:--:-- --:--:-- --:--:-- 735k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 735k 0 --:--:-- --:--:-- --:--:-- 735k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 565k 0 --:--:-- --:--:-- --:--:-- 565k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 432k 0 --:--:-- --:--:-- --:--:-- 432k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 114k 100 114k 0 0 925k 0 --:--:-- --:--:-- --:--:-- 925k
count_error=0 count_expected=0
bash-3.1$
答案 0 :(得分:2)
if
之后使用双圆括号的语法很奇怪。无论如何,检查成功的正确方法是
if curl http://www.example.com/example/path | grep -iq error; then
检查curl
的成功或失败会更加强大,但如果网站总是返回200结果代码,则不能这样做(可能会更改网站以便它如实地报告4xx或出现问题时会出现5xx HTTP错误代码吗?)
作为一种风格的评论,你应该为自己的变量使用小写,counter
循环作为for
循环会更优雅。
iterations=10000
for ((counter = 0; counter < iterations; ++counter)); do
行尾的分号是多余的;你需要语句之间的语句分隔符,但换行也是一个有效的语句分隔符。
答案 1 :(得分:2)
获得一些解决方案:
OP的问题在于,代码尽管在问题中有多行显示,但仍以单行的形式执行。
多个命令,甚至是bash中名为复合命令的单个控制流语句的组件;例如,if
,当放在单行时必须由;
实例分隔,而换行符会自动分隔语句。
bash中的if
复合命令包含if / else形式的这些部分:
if [[ ... ]]; then ...; else ...; fi # Note the `;` chars. separating the components.
在Compound Commands
中搜索man bash
了解完整故事。
在OP的情况下,;
之前缺少else
,导致else
分支被解释为{{1}的一部分(已损坏)分支命令;例如:
if
此处,缺少的$ if true; then echo TRUE else echo FALSE; fi # note missing ';' before `else`
TRUE else echo FALSE
导致整个;
分支被解释为else
的其他参数。
在其他情况下,由于语法错误, 分支都不会执行:
echo
此处,整个命令已中断,$ if true; then i='TRUE' else i='FALSE'; fi
-bash: else: command not found
从未被分配
这就是OP的情况(虽然我不清楚为什么他的输出没有包含语法错误信息)。
建议:
$i
调试命令以查看是否正在执行所有部分。tripleee's answer对bash代码有很好的风格建议;值得补充的是:
在bash中,您可以使用算术评估来增加变量C风格:
set -x
tripleee声明:
我对CygWin并不熟悉,但是如果没有一个shebang它做了正确的事情我会感到有些惊讶 - 它可能在POSIX模式下运行Bash,这意味着许多Bashisms将是语法错误,或者只是表现得不像你想要的那样。
实际上(无论bash是在CygWin(Windows)还是在Unix上运行):
语法,当bash在POSIX mode中运行时,除了进程替换((( ++count_error )) # alternative to count_error=$(( count_error + 1 ))
)之外的所有bashisms仍然可用;但是,行为中有许多微妙的变化,因此它总是优先明确控制给定脚本运行的模式。
当bash运行一个没有shebang行的可执行shell脚本时,它会运行它,好像脚本有一个<(...)
shebang行;换句话说:它不在POSIX模式下运行。