sh shell double if语句

时间:2014-07-22 20:35:57

标签: bash if-statement sh

谁能看到我在这里做错了什么?我不断收到以下错误消息:[[:not found

read INPUT
if [[ "$INPUT" -ge 1 ]] && [[ "$INPUT" -le 10 ]]; then
  Do something
else
  printf "Please enter a value between 1 and 10"
fi

3 个答案:

答案 0 :(得分:6)

[[在以#!/bin/sh开头或以sh yourscript开头的脚本中不可用。如果要使用,请使用#!/bin/bash启动脚本。

另见http://mywiki.wooledge.org/BashGuide/Practices#Choose_Your_Shell


顺便提一下,如果 要使用bash,那么数字比较会有更好的语法:

if (( input >= 1 && input <= 10 )); then ...

请注意,小写变量名称是本地使用的首选 - 全大写的名称是为环境变量和shell内置保留的。


如果你要使用bash,请使用POSIX测试运算符:

if [ "$input" -ge 1 ] && [ "$input" -le 10 ]; then ...

请注意,使用[ ]正确引用至关重要,而使用[[ ]]则通常是多余的;另外,[ ]缺少一些扩展,例如模式匹配和正则表达式运算符。

答案 1 :(得分:1)

这很复杂:

首先,构建if语句有三种不同的方式。每种方式都有自己独特的语法来加入两个布尔值。 (实际上,由于一种方式允许您使用列表运算符,因此有四种方法。)

一点背景......

if命令是shell中内置的复合命令if命令执行if之后的命令。如果该命令返回零值,则if语句被视为 true ,并且 then 子句将执行。否则,如果存在, else 子句将执行。请记住,if只是一个命令。你可以这样做:

if ! mv "$foo" "$bar"
then
    echo "I can't move $foo to $bar"
    exit 2
fi

我们需要的是命令为我们做一些测试。如果测试成功,则 test 命令返回零退出代码。如果不是,则返回非零退出代码。然后,它可以与if命令一起使用!

test 命令(是的,确实有一个!)。

[test命令的别名,该命令的创建允许您测试 {/ 1}}语句的文件,字符串和数字。 (现在这是Bash中的内置命令,但其根源实际上是if/bin/test的一部分。这些都是一样的:

/bin/[

if test "$foo" -eq "$bar"
then
    ...
fi

test 命令(如果您阅读联机帮助页有if [ "$foo" -eq "$bar" ] then ... fi 和测试以及-a或测试。您可以这样做:

-o

这是一个包含三个测试参数(if [ "$INPUT" -ge 1 -a "$INPUT" -le 10 ] then .... fi -ge-a)的测试语句。

使用列表运算符

这不是进行复合布尔测试的唯一方法。 Bash shell有两个列表运算符-le&&。列表运算符介于两个命令之间。如果使用||并且左手命令返回非零退出代码,则不执行右手命令,整个列表返回左手命令的退出值。如果使用&&,并且左手命令成功,则不执行右手命令,整个列表返回零退出值。如果第一个命令返回非零退出值,则执行右手命令,整个列表返回右手命令的退出值。

这就是为什么你可以做这样的事情:

||

由于[ $bar -eq 0 ] || echo "Bar doesn't have a zero value"! 只是一个返回零或非零值的命令,我们可以使用这些列表运算符作为测试的一部分:

[ ... ]

请注意,这是两个单独的测试,由if [ "$INPUT" -ge 1 ] && [ "$INPUT" -le 10 ] then ... fi 列表运算符分隔。

Bash的特殊&&复合命令

在Kornshell,Zsh和Bash中,有一些特殊的复合命令可供测试。这些是双方括号。它们看起来就像单个方括号命令,但由于它们是复合命令,因此解析会受到影响。

例如:

[[

shell扩展foo="This has white space" bar="" #No value if [ ! $foo = $bar ] # Doesn't work! then $foo,测试将变为:

$bar

哪个不起作用。然而,

if [ This has white space = ]

因特殊的解析规则而正常工作。双括号允许您使用括号进行分组,并使用if [[ $foo != $bar ]] &&作为布尔运算符。因此:

||

请注意,if [[ $INPUT -ge 1 && $INPUT -le 10 ]] then ... fi 在内部出现一组双方括号。 (注意,不需要引号)

数学布尔表达式

Bash内置了数学处理,包括数学布尔表达式。如果你在双括号之间放置一些东西,Bash将以数学方式对其进行评估:

&&

在这种情况下,评估if (( $INPUT >= 1 && $INPUT <= 10 )) then ... fi 。如果(( $INPUT >= 1 && $INPUT <= 10 ))包含在1到10之间,则数学表达式将计算为 true (零退出代码),因此将执行$INPUT子句。

所以,你可以:

  • 使用原始的then(单方括号)命令,并使用test在一次测试中将两个布尔语句串在一起。
  • 使用列表运算符将两个单独的-a命令(单个方括号)串在一起。
  • 使用现在包含test&&的较新的复合测试命令(双方括号)作为布尔运算符,因此您只需进行一次复合测试。
  • 忘记测试命令,只使用数学评估(双括号)来评估布尔表达式。

答案 2 :(得分:-1)

测试结构可以通过Shell改变

正如其他帖子中所提到的,[[是Bourne shell中不存在的Bash shell关键字。您可以使用以下命令从Bash提示符中看到此内容:

type '[['
[[ is a shell keyword

在Bourne shell中,您将获得“找不到命令”。

更便携:使用-a测试操作员

更便携的构造是使用-a测试运算符来连接条件(有关详细信息,请参阅man test)。例如:

if [ "$INPUT" -ge 1 -a "$INPUT" -le 10 ]; then
    : # do something when both conditions are true
else
    : # do something when either condition is false
fi

这将适用于我曾经使用的每个与Bourne兼容的shell,以及任何具有/bin/\[可执行文件的系统。