我有一个 THEN 部分,用于在循环内更新变量,变量可以正确打印,但似乎 IF 条件仍然等于 true,因为 THEN 部分在每个循环中都会触发。我对此有点困惑,因为 IF 语句
#!/bin/bash
highscore=0
for i in {1..5}
do
dt=$(date '+%d/%m/%Y %H:%M:%S');
lastEntry=$(perl -ne '/(Score: \d+)/ && print "$1\n";' scorelist.txt | tail -1 | awk '{print $2}')
highestEntry=$(perl -ne '/(Score: \d+)/ && print "$1\n";' scorelist.txt | sort | tail -1 | awk '{print $2}')
echo $dt
echo "Round: $i"
echo "Your score: $lastEntry"
echo "Highscore: $highscore"
if [ $highestEntry > $highscore ]
then
echo $highscore
highscore=$highestEntry
echo $highscore
fi
sleep 1
done
成绩单是一个简单的文本文件:
Score: 15
Score: 13
Score: 18
Score: 12
Score: 16
Score: 15
Score: 10
由于 IF 语句基本上表示if [ 18 > 18 ]
我不明白为什么 THEN 部分在每一轮都会被触发
答案1
由于 IF 语句基本上表示如果 [ 18 > 18 ] 我不明白为什么 THEN 部分在每一轮都会被触发
因为>
即使在这里也是一个重定向运算符,而不是比较运算符。
shell 'if' 语句的条件遵循与常规命令相同的语法。值得记住的是,真正的语法是if CMD; then CMD...; fi
,这[
只是一个看起来很奇怪的命令,不是一个真正的语法元素。
因此,您得到的等于[ 18 ] > 18
,它检查的是完全不同的东西——它检查字符串“18”是否为非空,这确实成功了(同时将命令的输出重定向到也名为“18”的文件)。此后,您可能会得到一堆带有数字名称的空文件。
虽然[
(和[[
)能比较数字,真正的运算符是-gt
和-lt
,而不是< >
。例如,[ $aa -gt $bb ]
。
只有((
与[[
运算符有一个特殊的例外;(( a > b ))
确实会对变量进行数字比较。
因此正确的选项应该是以下任意一个:
[ $aa -gt $bb ]
– 所有 sh 类 shell 中的标准;[[ $aa -gt $bb ]]
– 仅限 Bash/ksh(/zsh?);(( aa > bb ))
– 仅限 Bash/ksh(/zsh?),但支持算术表达式;如果您为 /bin/bash 编写,推荐使用;test $aa -gt $bb
– ; 的同义词[
,在脚本中很少使用,但可能使您更容易理解“if”条件的实际工作原理(if test foo; then..
);- 不是
[[ $aa > $bb ]]
– 虽然这不会调用重定向,但它实际上检查词汇顺序(即按字母顺序对字符串进行排序),而不是像的数字比较-gt
。
答案2
if (( $highestEntry > $highscore ))
应该可以解决问题。参见BASH 手册, 了解更多信息。
答案3
$ man bash
输入/COND
、点击Enter、向下滚动以查找...
string1 > string2
True if string1 sorts after string2 lexicographically.
注意:不作为数字进行比较。
就在它下面,你会发现...
arg1 OP arg2 OP 是 -eq、-ne、-lt、-le、-gt 或 -ge 之一。如果 arg1 等于、不等于、小于、小于,则这些算术二元运算符返回 true 或等于、大于或大于或等于 arg2。Arg1 和 arg2 可以是正整数或负整数。当与 [[ 命令,Arg1 和 Arg2 被评估为算术表达式(参见上面的算术评估)。
...告诉使用-gt
数值。
www.tldp.org-> Bash 指南 - 将告诉您更多详细信息...