我需要使用 while 循环和 If 语句来仅存储 1 和 0,然后检查哪一个比另一个更受欢迎。当我尝试执行脚本时遇到问题:
输入:
bash vote.sh 1 0 1
输出:
vote.sh: line 18: syntax error near unexpected token `done'
vote.sh: line 18: `done'
巴什代码
#!/bin/bash
zeroSum=0
oneSum=0
while read num do
if [ num -eq 0 ]; then
zeroSum=$zeroSum+num
elif [ num -eq 1 ]; then
oneSum=$oneSum+num
else
echo only 0s and 1s are accepted
if [ zeroSum -gt oneSum ]; then
echo zero won: $zeroSum
elif [ oneSum -gt zeroSum ]; then
echo one won: $oneSum
else
echo it was a draw
fi
done
答案1
您的代码中有几个语法错误。
第一个被触发的是循环头中;
前面缺失的部分。解决这个问题会产生do
for
while read num; do
fi
第一条语句也有缺失if
。解决这个问题:
if [ num -eq 0 ]; then
zeroSum=$zeroSum+num
elif [ num -eq 1 ]; then
oneSum=$oneSum+num
else
echo only 0s and 1s are accepted
fi
现在的代码运行,但是由于您忘记添加$
多个变量扩展,因此一旦开始将数据输入到正在运行的脚本中,您就会收到更多错误。
解决这个问题:
#!/bin/sh
zeroSum=0
oneSum=0
while read num; do
if [ "$num" -eq 0 ]; then
zeroSum=$(( zeroSum+1 ))
elif [ "$num" -eq 1 ]; then
oneSum=$(( oneSum+1 ))
else
echo only 0s and 1s are accepted
fi
if [ "$zeroSum" -gt "$oneSum" ]; then
echo "zero won: $zeroSum"
elif [ "$oneSum" -gt "$zeroSum" ]; then
echo "one won: $oneSum"
else
echo it was a draw
fi
done
我在这里做了一些更改:
- 该脚本由 运行
/bin/sh
,而不是由 运行bash
,因为它不包含任何sh
不能执行的操作。 - 变量扩展是用
$
变量名称前缀编写的,和双引号。 - 算术展开式写为
$(( ... ))
。算术扩展中使用的变量不需要$
在它们前面。 - 您可能打算将变量
zeroSum
和增加oneSum
1,而不是$num
。
但这仍然没有多大意义。为什么要在每次迭代中宣布获胜者?
另外,在这个问题中,您似乎是在命令行上给出输入,而不是在脚本的标准输入流上给出输入......
我可能会写类似的东西
#!/bin/sh
unset s0 s1
for arg do
case $arg in
0) s0=$(( s0 + 1 )) ;;
1) s1=$(( s1 + 1 )) ;;
*) printf 'Expecting 0 or 1 only, got "%s"\n' "$arg" >&2
esac
done
if [ "$s0" -gt "$s1" ]; then
printf 'Zeros won with %d against %d\n' "$s0" "$s1"
elif [ "$s0" -lt "$s1" ]; then
printf 'Ones won with %d against %d\n' "$s1" "$s0"
else
echo 'It is a draw'
fi
在这里,循环迭代给定的命令行参数,完成后,if
最后的语句会打印出结果。
在循环中,我使用了一个case ... esac
语句(它就像一个 switch 语句),因为它比长if
- then
-else
语句更紧凑。
测试:
$ sh script 0 1 1 0 0 0
Zeros won with 4 against 2
$ sh script 1 2 1 0 0 1
Expecting 0 or 1 only, got "2"
Ones won with 3 against 2