我有以下代码段:
#!/bin/bash
while true; do
ls "$1"
exitstatus=$?
if [[ $exitstatus != 0 ]]; then
read -n 1 -p "Retry? (y/n)" ch
echo
if [[ ! $ch =~ [Yy] ]]; then
break
fi
fi
exit $exitstatus
done
执行此脚本表明无论[[ ! $ch =~ [Yy] ]]
的内容如何,都会执行$ch
。
$ ./test.sh /foo
ls: cannot access /foo: No such file or directory
Retry? (y/n)y
$ ./test.sh /foo
ls: cannot access /foo: No such file or directory
Retry? (y/n)n
$
我试着评论一些事情,这似乎表明了预期的行为:
#!/bin/bash
while true; do
#ls "$1"
#exitstatus=$?
#if [[ $exitstatus != 0 ]]; then
read -n 1 -p "Retry? (y/n)" ch
if [[ ! $ch =~ [Yy] ]]; then
break
fi
#fi
#exit $exitstatus
done
在shell中执行以上命令:
$ ./test.sh
Retry? (y/n)y
Retry? (y/n)y
Retry? (y/n)n
$
在第一种情况下我做错了什么?
答案 0 :(得分:3)
exit $exitstatus
退出循环。它应该在循环之外。
答案 1 :(得分:1)
您有几个逻辑问题:
(1)您要求重试,但如果答案是y,则您从未读过要测试的新文件名,因此它总是会失败。
(2)当你要求重试的时候也很明显,你就这样做了:你在重试时得到了Y,但是然后只是将用户转入break
并且你无处可去:)
read -n 1 -p "Retry? (y/n)" ch
echo
if [[ ! $ch =~ [Yy] ]]; then ## testing for y, then we will retry right! - NOPE, just break :(
break
(3)那些讨厌而真正的循环。考虑你的循环应该打破什么并使用该测试,而不是永远的循环,并希望在正确的位置打破。然而,绕过你的几个逻辑可以让它像这样工作:
#!/bin/bash
## initialize variables
ch=y
srchfile="$1"
## while loop test for Y or y
while [[ $ch == [Yy] ]]; do
# attempt listing on srchfile
ls "$srchfile"
exitstatus=$?
# if bad exit status, prompt to retry?
if [[ $exitstatus != 0 ]]; then
read -n 1 -p "Retry? (y/n)" ch
echo
# test for y or Y answer
if [[ $ch == [^Yy] ]]; then
break
fi
# if retry, read new filename to test
read -p "Enter a new name for $srchfile : " srchfile
else
# that pesky file has been found, let's do something with it!
printf "You have successfully found file : %srchfile\n"
printf "(now do something useful with with it)\n"
break
fi
done
exit $exitstatus