Bash while 循环,如何读取输入直到条件为假

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22231266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:43:09  来源:igfitidea点击:

Bash while loop, how to read input until a condition is false

bash

提问by Tyler Pfaff

I keep getting a run time error. I'm running this in a terminal on OSX. The error is,

我不断收到运行时错误。我在 OSX 上的终端中运行它。错误是,

test.sh: line 15: while[!false]: command not found
test.sh: line 16: syntax error near unexpected token `do'
test.sh: line 16: `do'

I just can't figure where I've got wrong syntactically as I'm new to writing bash scripts.

因为我是编写 bash 脚本的新手,所以我无法弄清楚我在语法上哪里出错了。

ipa build &
TASK_PID=$!
sleep 5
kill $TASK_PID

finished=false
declare -a schemes

echo "*****************************************************************************************"
echo "| View the list of available build configs above."
echo "| Enter the name of the build you want,one at a time."
echo "| Type \"done\" to finish entering scheme names"
echo "*****************************************************************************************"

while[!${finished}]
do
read input
  if[$input == "done"]
  then
      finished=true
  else
  schemes=("${schemes[@]}" $input)
  echo ${schemes[0]}
  fi
done

echo "Do you want a verbose build? (y/n)"
read verbose


echo "Building your selected schemes....."
ipa build -s ${schemes[0]}

回答by chepner

trueand falseare not boolean keywords in bash; they are simply strings (and the names of commands; more on that in a moment). Even if you fix your syntax by supplying whitespace where necessary:

true并且false不是bash; 中的布尔关键字 它们只是字符串(以及命令的名称;稍后会详细介绍)。即使您通过在必要时提供空格来修复语法:

while ! [ "${finished}" ]; do
    ...
done

this loop will never run. Why? Whether finishedhas the value trueor false, it is simply a non-empty string. This code will run the [command (yes, it's a command, not syntax) and succeed because its argument is a non-empty string. The !negates it, so that the condition for the whileloop then alwaysfails.

这个循环永远不会运行。为什么?无论是否finished具有值trueor false,它都只是一个非空字符串。此代码将运行[命令(是的,它是一个命令,而不是语法)并成功,因为它的参数是一个非空字符串。The!否定它,因此while循环的条件总是失败。

The most direct fix is to explicitly compare $finishedto the string "true".

最直接的解决方法是明确$finished地与字符串“true”进行比较。

while [ "$finished" != "true" ]; do
   ...
done


I mentioned that trueand falseare also commands: truealways succeeds, and falsealways fails. Usually, you do not want to do what I am about to suggest, but here it's OK because trueand falseare about as simple a pair of commands as you can imagine.

我提到,truefalse也命令:true总是成功,false总是失败。通常,您不想执行我将要建议的操作,但是这里可以,因为truefalse是您可以想象的简单命令对。

finished=false
while ! $finished; do
    ...
    # At some point
    finished=true
done

Here, we are letting $finishedexpand to the name of a command, which then executes and has its exit status negated by the !. As long as finished=false, the negated exit status is always 0 and the while loop will continue to run. Once you change the value of finished, the negated exit status will be 1 and the loop will exit.

在这里,我们让$finished扩展为命令的名称,然后执行该命令并使其退出状态由!. 只要finished=false,否定退出状态始终为 0,while 循环将继续运行。一旦更改 的值finished,否定退出状态将为 1,循环将退出。

回答by Amit Verma

Give space around brackets in test conditions

在测试条件下在括号周围留出空间

while [ ! ${finished} ]

&

&

if [ $input = "done" ]

回答by Emmet

Why not try something like this:

为什么不尝试这样的事情:

#!/bin/bash

list='Foo Bar Baz Quux Xyzzy QUIT'

select item in $list; do
    case $item in
    QUIT)
        break
        ;;
    *)
        echo "You picked '$item'!"
        ;;
    esac
done