BASH:while循环读入

时间:2010-08-24 19:21:35

标签: bash loops

while [ $done = 0  ]
  do
  echo -n "Would you like to create one? [y/n]: "
  read answer
  if [ "$(answer)" == "y" ] || [ "$(answer)" == "Y" ]; then
    mkdir ./fsm_$newVersion/trace
    echo "Created trace folder in build $newVersion"
    $done=1
  elif [ "$(answer)" == "n" ] || [ "$(answer)" == "N" ]; then
    $done=2
  else
    echo "Not a valid answer"
  fi
done

好的,所以我上面有这个简单的bashscript,只是试图从用户那里获取输入并验证它。但是我一直收到这个错误

./test.sh: line 1: answer: command not found
./test.sh: line 1: answer: command not found
./test.sh: line 1: answer: command not found
./test.sh: line 1: answer: command not found

我不知道为什么,因为“回答”远不及第1行。所以我遇到了article

这是有道理的,因为它指的是第1行而无法找到答案。所以它似乎开始了一个新的子shell。但是我并没有真正理解解决方案,也无法看到我如何将它应用到我的案例中。我只想让它发挥作用。

2 个答案:

答案 0 :(得分:7)

$(answer)不会替换变量answer的值。它执行answer作为命令,并替换该命令的输出。您希望${answer}到处都有$(answer)。在这种情况下,您也可以使用$answer,但过度使用${...}是一种很好的偏执狂。

(您是否习惯于编写Makefile?$(...)${...}在Makefile中是相同的,但shell是不同的。)

顺便说一句,你还有其他一些错误:

  • 在shell中,您不会在作业左侧的变量名称上放置美元符号。您需要将$done=1更改为done=1,同样更改为$done=2
  • 你对变量替换不够偏执。除非你知道某个事实它在某些特定情况下做错了,否则你应该总是用双引号包装所有变量替换。这会影响mkdir命令和while循环上的条件。
  • 你对test(又名[)的论点不够偏执。您需要使用x为等式测试的两侧添加前缀,以便它们不会被误解为开关。
  • ==不是可移植的shell,而是使用=(bash没有区别,但许多非bash shell根本不支持==

把它们放在一起,这就是你的脚本应该是这样的:

while [ "x${done}" = x0 ]; do
  echo -n "Would you like to create one? [y/n]: "
  read answer
  if [ "x${answer}" = xy ] || [ "x${answer}" = xY ]; then
    mkdir "./fsm_${newVersion}/trace"
    echo "Created trace folder in build $newVersion"
    done=1
  elif [ "x${answer}" = xn ] || [ "x${answer}" = xN ]; then
    done=2
  else
    echo "Not a valid answer"
  fi
done

答案 1 :(得分:0)

  

我不明白为什么因为   “答案”远不及第1行。所以我   遇到了这篇文章

这不是你的问题。

我运行了脚本并没有得到你得到的错误。我确实收到了错误:

./test.sh: line 1: [: -eq: unary operator expected

当我尝试编译时。定义完成修复此问题。以下脚本应该有效......

#!/bin/bash

done=0
while [ $done -eq 0 ]
do
  echo -n "Would you like to create one? [y/n]: "
  read answer
  if [[ "$(answer)" == "y" || "$(answer)" == "Y" ]]; then
    mkdir ./fsm_${newVersion}/trace
    echo "Created trace folder in build $newVersion"
    $done=1
  elif [[ "$(answer)" == "n" || "$(answer)" == "N" ]]; then
    $done=2
  else
    echo "Not a valid answer"
  fi
done

...请注意,您正在对已完成的变量进行字符串比较,您显然想要数字。在数值类型变量上进行字符串比较通常是不好的形式,尽管它会起作用。请改用-eq(算术比较运算符)。 (还要注意,如果你保持那个测试,你的字符串相等会不一致......你在一个地方有“=”而在另一个地方有“==”......在这里挑剔,但要保持一致是有帮助的。)< / p>

另外,我建议使用复合条件的双括号,因为如果你有更长的条件,它们会更具可读性。 e.g。

if [[($var1 -eq 0 && $var2 -eq 1) || ($var1 -eq 1 && $var2 -eq 0)]]; then

只是一个偏好问题,因为你只有两个条件,但将来可能会有用。

你的newVersion变量周围还缺少大括号'{''}。

最后,我建议将#!/ bin / bash行放在脚本的顶部。否则它取决于您的环境,以确定如何处理您的脚本,这是一个坏主意。