Skip to content
SRE运维进阶之路SRE运维进阶之路
github icon
    • 第一部分 初见shell

      • 第一章 为什么使用shell编程
        • 第二章 和Sha-Bang(#!)一起出发

          • 2.1 调用一个脚本
            • 2.2 牛刀小试
          • 第二部分 shell基础

            • 第三章 特殊字符
              • 第四章 变量与参数

                • 4.1 变量替换
                  • 4.2 变量赋值
                    • 4.3 Bash变量是弱类型的
                      • /code/shell/part2/04_4_special_variable_types
                      • 第五章 引用

                        • 5.1 引用变量
                          • 5.2 转义
                          • 第六章 退出与退出状态
                            • 第七章 测试

                              • 7.1 测试结构
                                • 7.2 文件测试操作
                                  • 7.3 其他比较操作
                                    • 7.4 嵌套 if/then 条件测试
                                      • 7.5 牛刀小试
                                      • 第八章 运算符相关话题

                                        • 8.1 运算符
                                          • 8.2 数字常量
                                            • 8.3 双圆括号结构
                                              • 8.4 运算符优先级
                                            • 第三部分 shell进阶

                                              • 第九章 换个角度看变量

                                                • 9.1 内部变量
                                                  • 9.2 变量类型标注:declare 与 typeset
                                                    • 9.2.1 declare 的另类用法
                                                      • 9.3 $RANDOM:生成随机数
                                                      • 第十章 变量处理

                                                        • 10.1 字符串处理
                                                          • 10.1.1 使用 awk 处理字符串
                                                            • 10.1.2 参考资料
                                                              • 10.2 参数替换
                                                              • 第十一章 循环与分支

                                                                • 11.1 循环
                                                                  • 11.2 嵌套循环
                                                                    • 11.3 循环控制
                                                                      • 11.4 测试与分支
                                                                      • 第十二章 命令替换
                                                                        • 第十三章 算术扩展
                                                                        • 第四部分 命令
                                                                          • 第五部分 高级话题

                                                                            • 18 正则表达式

                                                                              • 18.1 正则表达式简介
                                                                                • 18.2文件名替换
                                                                                  • 18.3 正则表达式对照表
                                                                                  • 19 嵌入文档
                                                                                    • 20 I/O 重定向

                                                                                      • 20.1 使用 exec
                                                                                        • 20.2 重定向代码块
                                                                                          • 20.3 应用程序
                                                                                          • 第二十一章 子shell
                                                                                            • 第二十二章. 限制模式的Shell
                                                                                              • 第二十三章. 进程替换
                                                                                                • 24 函数

                                                                                                  • 24.1 复杂函数和函数复杂性
                                                                                                    • 24.2 局部变量
                                                                                                      • 24.3 不使用局部变量的递归
                                                                                                      • 25. 别名
                                                                                                        • 26. 列表结构
                                                                                                          • 27 数组
                                                                                                            • 30 网络编程
                                                                                                              • 33 选项
                                                                                                                • 第34章 陷阱
                                                                                                                  • 第36章 杂项
                                                                                                                    • echo命令
                                                                                                                    • 第六部分 Google Shell 风格指南
                                                                                                                    • 前端学习笔记

                                                                                                                      第六章 退出与退出状态

                                                                                                                      author iconLinuxStorycalendar icon2021年5月11日category icon
                                                                                                                      • Linux
                                                                                                                      tag icon
                                                                                                                      • Bash
                                                                                                                      timer icon大约 3 分钟

                                                                                                                      # 第六章 退出与退出状态

                                                                                                                      Bourne shell里存在不明确之处,但人们也会使用它们。

                                                                                                                      —— Chat Ramey

                                                                                                                      跟C程序类似,exit 命令被用来结束脚本。同时,它也会返回一个值,返回值可以被交给父进程。

                                                                                                                      每个命令都会返回一个退出状态(exit status),有时也叫做返回状态(return status)或退出码(exit code)。命令执行成功返回0,如果返回一个非0值,通常情况下会被认为是一个错误代码。一个运行状态良好的UNIX命令、程序和工具在正常执行退出后都会返回一个0的退出码,当然也有例外。

                                                                                                                      同样地,脚本中的函数和脚本本身也会返回一个退出状态。在脚本或者脚本函数中执行的最后的命令会决定它们的退出状态。在脚本中,exit nnn 命令将会把nnn退出状态码传递给shell(nnn 必须是 0-255 之间的整型数)。

                                                                                                                      note 当一个脚本以不带参数的 exit 来结束时,脚本的退出状态由脚本最后执行命令决定(exit 命令之前)。

                                                                                                                      #!/bin/bash
                                                                                                                      
                                                                                                                      COMMAND_1
                                                                                                                      
                                                                                                                      ...
                                                                                                                      
                                                                                                                      COMMAND_LAST
                                                                                                                      
                                                                                                                      # 将以最后的命令来决定退出状态
                                                                                                                      
                                                                                                                      exit
                                                                                                                      
                                                                                                                      1
                                                                                                                      2
                                                                                                                      3
                                                                                                                      4
                                                                                                                      5
                                                                                                                      6
                                                                                                                      7
                                                                                                                      8
                                                                                                                      9
                                                                                                                      10
                                                                                                                      11

                                                                                                                      exit,exit $? 以及省略 exit 效果等同。

                                                                                                                      #!/bin/bash 
                                                                                                                      
                                                                                                                      COMMAND_1
                                                                                                                      
                                                                                                                      ...
                                                                                                                      
                                                                                                                      COMMAND_LAST
                                                                                                                      
                                                                                                                      #将以最后的命令来决定退出状态
                                                                                                                      
                                                                                                                      exit $?
                                                                                                                      
                                                                                                                      1
                                                                                                                      2
                                                                                                                      3
                                                                                                                      4
                                                                                                                      5
                                                                                                                      6
                                                                                                                      7
                                                                                                                      8
                                                                                                                      9
                                                                                                                      10
                                                                                                                      11
                                                                                                                      #!/bin/bash
                                                                                                                      
                                                                                                                      COMMAND_1
                                                                                                                      
                                                                                                                      ...
                                                                                                                      
                                                                                                                      COMMAND_LAST
                                                                                                                      
                                                                                                                      #将以最后的命令来决定退出状态
                                                                                                                      
                                                                                                                      1
                                                                                                                      2
                                                                                                                      3
                                                                                                                      4
                                                                                                                      5
                                                                                                                      6
                                                                                                                      7
                                                                                                                      8
                                                                                                                      9

                                                                                                                      $? 读取上一个执行命令的退出状态。在一个函数返回后,$? 给出函数最后执行的那条命令的退出状态。这就是Bash函数的"返回值"。[1]

                                                                                                                      在管道open in new window执行后,$? 给出最后执行的那条命令的退出状态。

                                                                                                                      在脚本终止后,命令行下键入$?会给出脚本的退出状态,即在脚本中最后一条命令执行后的退出状态。一般情况下,0为成功,1-255为失败。

                                                                                                                      样例 6-1. 退出与退出状态

                                                                                                                      #!/bin/bash
                                                                                                                      
                                                                                                                      echo hello
                                                                                                                      echo $?    # 返回值为0,因为执行成功。
                                                                                                                      
                                                                                                                      lskdf      # 不认识的命令。
                                                                                                                      echo $?    # 返回非0值,因为失败了。
                                                                                                                      
                                                                                                                      echo
                                                                                                                      
                                                                                                                      exit 113   # 将返回113给shell
                                                                                                                                 # 为了验证这些,在脚本结束的地方使用“echo $?”
                                                                                                                      
                                                                                                                      #  按照惯例,'exit 0' 意味着执行成功,
                                                                                                                      #+ 非0意味着错误或者异常情况。
                                                                                                                      #  查看附录章节“退出码的特殊含义”
                                                                                                                      
                                                                                                                      1
                                                                                                                      2
                                                                                                                      3
                                                                                                                      4
                                                                                                                      5
                                                                                                                      6
                                                                                                                      7
                                                                                                                      8
                                                                                                                      9
                                                                                                                      10
                                                                                                                      11
                                                                                                                      12
                                                                                                                      13
                                                                                                                      14
                                                                                                                      15
                                                                                                                      16

                                                                                                                      $? 对于测试脚本中的命令的执行结果特别有用(查看样例 16-35和样例 16-20)。

                                                                                                                      note 逻辑非操作符 !open in new window 将会反转测试或命令的结果,并且这将会影响退出状态。

                                                                                                                      样例 6-2. 否定一个条件使用!

                                                                                                                      true    # true 是 shell 内建命令。
                                                                                                                      echo "exit status of \"true\" = $?"     # 0
                                                                                                                      
                                                                                                                      ! true
                                                                                                                      echo "exit status of \"! true\" = $?"   # 1
                                                                                                                      # 注意在命令之间的 "!" 需要一个空格。
                                                                                                                      # !true 将导致一个"command not found"错误。
                                                                                                                      #
                                                                                                                      # 如果一个命令以'!'开头,那么将调用 Bash 的历史机制,显示这个命令被使用的历史。
                                                                                                                      
                                                                                                                      true
                                                                                                                      !true
                                                                                                                      # 这次就没有错误了,但是同样也没有反转。
                                                                                                                      # 它不过是重复之前的命令(true)。
                                                                                                                      
                                                                                                                      
                                                                                                                      # ============================================================ #
                                                                                                                      # 在 _pipe_ 前使用 ! 将改变返回的退出状态。
                                                                                                                      ls | bogus_command      #bash: bogus_command: command not found
                                                                                                                      echo $?                 #127
                                                                                                                      >
                                                                                                                      ! ls | bogus_command    #bash: bogus_command:command not found
                                                                                                                      echo $?                 #0
                                                                                                                      # 注意 ! 不会改变管道的执行。
                                                                                                                      # 只改变退出状态。
                                                                                                                      #============================================================  #
                                                                                                                      >
                                                                                                                      # 感谢 Stéphane Chazelas 和 Kristopher Newsome。
                                                                                                                      
                                                                                                                      1
                                                                                                                      2
                                                                                                                      3
                                                                                                                      4
                                                                                                                      5
                                                                                                                      6
                                                                                                                      7
                                                                                                                      8
                                                                                                                      9
                                                                                                                      10
                                                                                                                      11
                                                                                                                      12
                                                                                                                      13
                                                                                                                      14
                                                                                                                      15
                                                                                                                      16
                                                                                                                      17
                                                                                                                      18
                                                                                                                      19
                                                                                                                      20
                                                                                                                      21
                                                                                                                      22
                                                                                                                      23
                                                                                                                      24
                                                                                                                      25
                                                                                                                      26
                                                                                                                      27
                                                                                                                      28

                                                                                                                      caution 某些特定的退出码具有一些特定的保留含义open in new window,用户不应该在自己的脚本中重新定义它们。


                                                                                                                      1. 在函数没有用returnopen in new window来结束这个函数的情况下。 ↩︎

                                                                                                                      edit icon编辑此页open in new window
                                                                                                                      上次编辑于: 2022/4/27 15:33:00
                                                                                                                      贡献者: clay-wangzhi
                                                                                                                      上一页
                                                                                                                      第五章 引用
                                                                                                                      下一页
                                                                                                                      第七章 测试
                                                                                                                      备案号:冀ICP备2021007336号
                                                                                                                      Copyright © 2023 LinuxStory