bash (3) 逻辑控制

本文介绍了Bash脚本中的基本逻辑控制结构,包括if条件判断、for循环、while循环、until循环、case多分支选择及break/continue语句,并详细解析了各结构的语法与用法。

bash里也有基本的逻辑控制, 比如 if then else fi.  for do ..done    case ...esac     while do...done等 。

 

其中 对于if ,比较的特殊和其他的一般语言的if 不太一样, 之前每次用都到网上去google一把, 现在整理一下吧,呵呵。

 1. IF

 if...then...else

if 语句用于判断和分支,其语法规则和 C 语言的 if 非常相似。其几种基本结构为: if [ expression ] then   statments fi 或者 if [ expression ] then   statments else   statments fi 或者 if [ expression ] then   statments else if [ expression ]  then     statments   else    statments fi 或者 if [ expression ] then  statments elif [ expression ] then    statments else    statments fi 值得说明的是如果你将 if 和 then 简洁的写在一行里面,就必须在 then 前面加上分号,如:if [ expression ]; then ... 。下面这个例子说明了如何使用 if 条件判断语句: #!/bin/bash if [ $1 -gt 90 ] then   echo "Good, $1" elif [ $1 -gt 70 ] then    echo "OK, $1" else    echo "Bad, $1" fi

exit 0 上面例子中的 $1 是指命令行的第一个参数,这个会在后面的“BASH 中的特殊保留字”中讲解。

注意:“if”和“[”之间需要空格,如果你不空格,shell会报告语法错误的

可以多个condition处理, 用 -a 表示 && and , -o 表示 || or.

conditon测试类型对照表

---Begin add in 2011-11-30---- test -s file: 是用来测试文件file的大小是0 ---End add in 2011-11-30 ----  
运算符 描述 示例
文件比较运算符
-e  filename如果  filename 存在,则为真[ -e /var/log/syslog ]
-d  filename如果  filename 为目录,则为真[ -d /tmp/mydir ]
-f  filename如果  filename 为常规文件,则为真[ -f /usr/bin/grep ]
-L  filename如果  filename 为符号链接,则为真[ -L /usr/bin/grep ]
-r  filename如果  filename 可读,则为真[ -r /var/log/syslog ]
-w  filename如果  filename 可写,则为真[ -w /var/mytmp.txt ]
-x  filename如果  filename 可执行,则为真[ -L /usr/bin/grep ]
filename1 -nt  filename2如果  filename1 比  filename2 新,则为真[ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot  filename2如果  filename1 比  filename2 旧,则为真[ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符  (请注意引号的使用,这是防止空格扰乱代码的好方法)
-z  string如果  string 长度为零,则为真[ -z "$myvar" ]
-n  string如果  string 长度非零,则为真[ -n "$myvar" ]
string1string2如果  string1 与  string2 相同,则为真[ "$myvar" = "one two three" ]
string1 !=  string2如果  string1 与  string2 不同,则为真[ "$myvar" != "one two three" ]
算术比较运算符
num1 -eq  num2等于[ 3 -eq $mynum ]
num1 -ne  num2不等于[ 3 -ne $mynum ]
num1 -lt  num2小于[ 3 -lt $mynum ]
num1 -le  num2小于或等于[ 3 -le $mynum ]
num1 -gt  num2大于[ 3 -gt $mynum ]
num1 -ge  num2大于或等于[ 3 -ge $mynum ]

 





2 for
for 循环结构与 C 语言中有所不同,在 BASH 中 for 循环的基本结构是:

for $var in [list]
do
  statments
done

其中 $var 是循环控制变量,[list] 是 $var 需要遍历的一个集合,do/done 对包含了循环体,相当于 C 语言中的一对大括号。另外如果do 和 for 被写在同一行,必须在 do 前面加上 ";"。如: for $var in [list]; do 。下面是一个运用 for 进行循环的例子:

#!/bin/bash

for day in Sun Mon Tue Wed Thu Fri Sat
do
  echo $day
done

# 如果列表被包含在一对双引号中,则被认为是一个元素
for day in "Sun Mon Tue Wed Thu Fri Sat"
do
  echo $day
done

exit 0

注意上面的例子中,在 for 所在那行的变量 day 是没有加 "$" 符号的,而在循环体内,echo 所在行变量 $day 是必须加上 "$" 符号的。另外如果写成 for day 而没有后面的 in [list] 部分,则 day 将取遍命令行的所有参数。如这个程序:

#!/bin/bash

for param
do
  echo $param
done

exit 0

上面这个程序将列出所有命令行参数。for 循环结构的循环体被包含在 do/done 对中,这也是后面的 while、until 循环所具有的特点。

3 while
while 循环的基本结构是:

while [ condition ]
do
  statments
done

这个结构请大家自己编写一个例子来验证。

4 until
until 循环的基本结构是:

until [ condition is TRUE ]
do
  statments
done

这个结构也请大家自己编写一个例子来验证。

5 case
BASH 中的 case 结构与 C 语言中的 switch 语句的功能比较类似,可以用于进行多项分支控制。其基本结构是:

case "$var" in
 condition1 )
  statments1;;
 condition2 )
  statments2;;
 ...
 * )
  default statments;;
esac

下面这个程序是运用 case 结构进行分支执行的例子:

#!/bin/bash

echo "Hit a key, then hit return."
read Keypress

case "$Keypress" in
 [a-z] ) echo "Lowercase letter";;
 [A-Z] ) echo "Uppercase letter";;
 [0-9] ) echo "Digit";;
 * ) echo "Punctuation, whitespace, or other";;
esac

exit 0

上面例子中的第四行 "read Keypress" 一句中的 read 语句表示从键盘上读取输入。这个命令将在本讲义的 BASH 的其他高级问题中讲解。

6 break/continue
熟悉 C 语言编程的都很熟悉 break 语句和 continue 语句。BASH 中同样有这两条语句,而且作用和用法也和 C 语言中相同,break 语句可以让程序流程从当前循环体中完全跳出,而 continue 语句可以跳过当次循环的剩余部分并直接进入下一次循环。

 

 函数的使用
BASH 是一个相对简单的脚本语言,不过为了方便结构化的设计,BASH 中也提供了函数定义的功能。BASH 中的函数定义很简单,只要向下面这样写就可以了:

function my_funcname {
 code block
}

或者

my_funcname() {
 code block
}

上面的第二种写法更接近于 C 语言中的写法。BASH 中要求函数的定义必须在函数使用之前,这是和 C 语言用头文件说明函数方法的不同。

更进一步的问题是如何给函数传递参数和获得返回值。BASH 中函数参数的定义并不需要在函数定义处就制定,而只需要在函数被调用时用 BASH 的保留变量 $1 $2 ... 来引用就可以了;BASH 的返回值可以用 return 语句来指定返回一个特定的整数,如果没有 return 语句显式的返回一个返回值,则返回值就是该函数最后一条语句执行的结果(一般为 0,如果执行失败返回错误码)。函数的返回值在调用该函数的程序体中通过 $? 保留字来获得。下面我们就来看一个用函数来计算整数平方的例子:

#!/bin/bash

square() {
 let "res = $1 * $1"
 return $res
}

square $1
result=$?
echo $result

exit 0

<think>首先,用户的问题是:“我想查找shell bash中逻辑值判断的相关内容 请问shell bash逻辑值判断的方法和规则”。用户在这个问题中提到了“逻辑值判断”,结合系统指令,我需要参考用户提供的引用内容。 用户提供了四个引用: - 引用[1]: 讨论了 Bash 中的 true 和 false 命令,它们设置退出码(0 表示真/success,1 表示假/failure)。 - 引用[2]: 描述了变量赋值和代换,包括文件名通配符和命令代换。 - 引用[3]: 提及了进程替换和默认值与错误处理。 - 引用[4]: 讨论了逻辑操作符 && 和 ||,用于命令的执行顺序和错误处理。 用户的问题是关于“逻辑值判断”的,这通常涉及到在 Bash 中如何评估条件是否为真或假。核心在于 Bash 中的逻辑值是基于命令的退出码(exit status)来判断的。 关键点: - 在 Bash 中,逻辑真通常对应退出码 0(成功)。 - 逻辑假对应非零退出码(通常是 1,失败)。 - 逻辑操作符如 &&(逻辑与)、||(逻辑或)基于退出码来控制命令执行。 参考提供的引用: - 引用[1] 直接相关:解释了 true 和 false 命令如何设置退出码。 - 引用[4] 直接相关:讨论了 && 和 || 的逻辑执行顺序。 - 引用[2] 和 [3] 可能相关,但较少直接涉及逻辑判断;[2] 是关于变量和代换,[3] 是关于进程替换和错误处理。 用户的上一个问题(在系统指令中提到)是关于快速排序的Python代码和问题,但当前用户的问题是新提出的,所以我应该专注于当前问题。 系统指令要求: - 回答结构清晰,逐步解决问题。 - 使用中文回答。 - 生成相关问题。 - 在引用段落末尾添加引用标识。 结构回答: 1. **简介**:解释 Bash 中逻辑值判断的基本概念。 2. **方法**:详细说明如何判断逻辑值,包括: - 退出码的作用。 - 使用 && 和 ||。 - 条件测试(如 [ ] 或 [[ ]])。 - 其他相关命令如 test, if 语句。 3. **规则**:总结规则,如退出码0为真,非零为假。 4. **示例**:提供代码示例来演示。 5. **相关问题**:在末尾生成相关问题。 确保 LaTeX 格式: - 行内数学表达式用 $...$,但这里可能不太需要,除非涉及数值比较。 - 独立公式用 $$...$$,同样可能不适用。 - 语法正确。 回答大纲: - **开头**:直接回答用户问题,解释逻辑值判断。 - **主体**: - 退出码基础(引用[1])。 - 逻辑操作符 && 和 ||(引用[4])。 - 条件测试命令(如 [ ] 或 [[ ]])。 - 在 if 语句中的应用。 - **结尾**:总结规则。 - 生成相关问题。 添加引用: - 在相关部分末尾添加 [^1], [^2], [^3], [^4]。 相关问题生成: - 基于用户查询,生成类似示例中的问题,如: 1. 如何在 if 语句中使用逻辑判断? 2. Shell 中的 true 和 false 命令有哪些用法? 3. 如何自定义命令的退出码来进行逻辑判断? 最终回答。 </think>### Shell Bash 中逻辑值判断的方法和规则 在 Shell Bash 中,逻辑值判断主要基于**命令的退出码(Exit Status)** 来实现。退出码是一个数字值(0 表示真/成功,非 0 表示假/失败),这构成了 Bash 逻辑判断的核心机制。以下是详细方法和规则的逐步解释,结合您提供的引用内容。 #### 1. **基本概念:退出码与逻辑值** - **退出码的作用**:所有命令执行后都会返回一个退出码。如果退出码为 0,表示命令成功(逻辑真);如果为非 0(通常是 1),表示失败(逻辑假)。 - 示例:`true` 命令总是返回退出码 0,`false` 命令总是返回退出码 1[^1]。 - 测试方法:使用 `$?` 获取上一条命令的退出码: ```bash true echo $? # 输出 0(真) false echo $? # 输出 1(假) ``` - **变量与逻辑值**:Shell 变量本质是字符串,但通过退出码可间接用于逻辑判断。例如,变量比较需借助测试命令(如 `[ ]`)而非直接作为布尔值[^2]。 #### 2. **逻辑操作符:`&&`(与)和 `||`(或)** - **执行规则**:这些操作符基于退出码控制命令执行顺序: - **`&&`(逻辑与)**:仅当左侧命令成功(退出码 0)时,才执行右侧命令。 - **`||`(逻辑或)**:仅当左侧命令失败(退出码非 0)时,才执行右侧命令。 - 示例:引用[4] 展示了错误处理: ```bash echo "hdakl" && ls ds # 输出 "hdakl",但 ls 失败(非 0)时跳过后续 ls das || echo "hdakl" # ls 失败(非 0)时执行 echo ``` 这里,`$?` 用于隐式判断逻辑值[^4]。 #### 3. **条件测试命令:`test`、`[ ]` 和 `[[ ]]`** - **测试表达式**:使用内置命令评估条件,返回退出码 0(真)或 1(假)。 - **基本语法**:`test expression` 或 `[ expression ]`(注意空格)。 ```bash [ -f "file.txt" ] # 检查文件存在,存在则返回 0(真) echo $? # 输出 0 或 1 ``` - **扩展测试**:`[[ ]]` 支持更复杂的逻辑(如正则匹配),且避免单词分割问题。 ```bash [[ $var == "error" ]] && echo "Found error" # 如果变量匹配,执行 echo ``` - **常见测试类型**: - **数值比较**:`-eq`(等于)、`-ne`(不等于),例如 `[ "$a" -eq 10 ]`。 - **字符串比较**:`=`(相等)、`!=`(不相等),例如 `[ "$str" = "hello" ]`。 - **文件测试**:`-e`(存在)、`-d`(是目录),例如 `[ -d "/tmp" ]`。 #### 4. **在控制结构中的应用** - **`if` 语句**:直接基于命令退出码进行分支: ```bash if grep "error" log.txt; then echo "错误存在" # grep 退出码 0(真)时执行 else echo "无错误" # grep 退出码非 0(假)时执行 fi ``` 改进版使用进程替换避免子 Shell 变量丢失(引用[3])[^3]。 - **循环与错误处理**:结合 `||` 处理默认值: ```bash value=${input:-"default"} # 如果 input 未定义,使用 "default" ``` #### 5. **核心规则总结** - **退出码规则**: - 0 = 真(成功) - 非 0 = 假(失败),通常为 1,但可自定义(如 `exit 2`)。 - **操作符优先级**: - `&&` 和 `||` 从左到右短路求值。 - 组合逻辑时使用括号分组: ```bash ( [ -f file ] && echo "存在" ) || echo "缺失" ``` - **注意事项**: - 变量引用需加双引号避免空值错误(如 `[ "$var" = "test" ]`)[^2]。 - `true`/`false` 是内置命令或外部程序,常用于强制逻辑值[^1]。 #### 示例演示 ```bash # 检查文件存在且可读 if [ -r "data.txt" ]; then echo "文件可读" # [ ] 返回 0 时执行 else echo "文件不可读" fi # 组合逻辑:创建目录失败时输出错误 mkdir new_dir || echo "创建失败,退出码=$?" # 非 0 时执行 ``` 通过以上方法,Bash 的逻辑值判断以退出码为核心,灵活支持脚本中的条件控制。如需深入,可参考 Bash 手册 `man bash` 中 "CONDITIONAL EXPRESSIONS" 章节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值