文章目錄
  1. 1. Shell 在线环境
  2. 2. 几种常见的Shell
  3. 3. 不使用Shell的情况
  4. 4. Shell脚本
    1. 4.1. 变量
    2. 4.2. Shell替换
    3. 4.3. 注释
    4. 4.4. 字符串
    5. 4.5. 数组
    6. 4.6. printf命令
    7. 4.7. case … esac
    8. 4.8. 运算符
    9. 4.9. break命令
    10. 4.10. 函数
    11. 4.11. 输入输出重定向
    12. 4.12. 文件包含

以前多多少少接触过一些shell命令,用的不多,现在打算好好了解一下。看了Linux Shell脚本教程,这里做点笔记:

Shell 在线环境

tutorialspoint

几种常见的Shell

  • bash: Linux标准默认的shell,内部命令一共有40个。
  • sh: Unix 标准默认的shell。

bash完全兼容sh,也就是说,用sh写的脚本可以不加修改的在bash中执行。

不使用Shell的情况

  1. 资源密集型的任务,尤其在需要考虑效率时(比如,排序,hash等等)。
  2. 需要处理大任务的数学操作,尤其是浮点运算,精确运算,或者复杂的算术运算(这种情况一般使用C++或FORTRAN 来处理)。
  3. 有跨平台(操作系统)移植需求(一般使用C 或Java)。
  4. 复杂的应用,在必须使用结构化编程的时候(需要变量的类型检查,函数原型,等等)。
  5. 对于影响系统全局性的关键任务应用。
  6. 对于安全有很高要求的任务,比如你需要一个健壮的系统来防止入侵、破解、恶意破坏等等。
  7. 项目由连串的依赖的各个部分组成。
  8. 需要大规模的文件操作。
  9. 需要多维数组的支持。
  10. 需要数据结构的支持,比如链表或数等数据结构。
  11. 需要产生或操作图形化界面 GUI。
  12. 需要直接操作系统硬件。
  13. 需要 I/O 或socket 接口。
  14. 需要使用库或者遗留下来的老代码的接口。
  15. 私人的、闭源的应用(shell 脚本把代码就放在文本文件中,全世界都能看到)

Shell脚本

  • “#!” 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。
  • 变量

    • 变量名和等号之间不能有空格。
    • 定义变量时,变量名不加美元符号($);使用一个定义过的变量,只要在变量名前面加美元符号($)即可。
    • 变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界。建议使用时在所有变量外加花括号。
    • 使用readonly命令可以将变量定义为只读变量,只读变量的值不能被改变。
    • 使用unset命令可以删除变量。
    • 变量类型:
      1. 局部变量:在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
      2. 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
      3. shell变量:由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。
    • 特殊变量:
      1. $0 当前脚本的文件名
      2. $n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
      3. $# 传递给脚本或函数的参数个数。
      4. $* 传递给脚本或函数的所有参数。
      5. $@ 传递给脚本或函数的所有参数。被双引号(“ “)包含时,与 $* 稍有不同,下面将会讲到。
      6. $? 上个命令的退出状态,或函数的返回值。
      7. $$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
    • $*$@ 的区别

      $ 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(“ “)包含时,都以”$1” “$2” … “$n” 的形式输出所有参数。但是当它们被双引号(“ “)包含时,”$“ 会将所有的参数作为一个整体,以”$1 $2 … $n”的形式输出所有参数;”$@” 会将各个参数分开,以”$1” “$2” … “$n” 的形式输出所有参数.

  • Shell替换

    • echo命令的 -e 表示对转义字符进行替换,-E 选项禁止转义,默认也是不转义的;使用 -n 选项可以禁止插入换行符。
    • 变量替换
      1. ${var} 变量本来的值
      2. ${var:-word} 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。
      3. ${var:=word} 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。
      4. ${var:?message} 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。
        若此替换出现在Shell脚本中,那么脚本将停止运行。
      5. ${var:+word} 如果变量 var 被定义,那么返回 word,但不改变 var 的值。
  • 注释

    • 只有单行注释,用#
    • 如果在开发过程中,遇到大段的代码需要临时注释起来,可以把这一段要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行。
  • 字符串

    • 单引号:单引号字符串中的变量是无效的;单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
    • 双引号:双引号里可以有变量,双引号里可以出现转义字符。
    • 获取字符串长度:
      ${#string} #输出 4```
      1
      - 提取子字符串:
      ```echo ${string:1:4} #输出liba
  • 数组

    • 用括号表示
    • 使用@ * 可以作下标获取数组中的所有元素
  • printf命令

    与C语言中的printf的不同:

    • 不用加括号
    • 参数的分隔用空格,不是逗号
    • 格式字符串能重用,可以将所有参数都转换
  • case … esac

    • 类似于C中的switch ...case...语句
    • 取值后面必须为关键字 in,每一模式必须以右括号结束
    • ;; 与其他语言中的 break 类似
    • * 类似于default,捕捉其他情况
  • 运算符

    • expr

      1. 注意表达式和运算符之间要有空格;
      2. 乘号(*)前边必须加反斜杠()才能实现乘法运算。
    • 关系运算符:只支持数字,不支持字符串,除非字符串的值是数字。

    • 布尔运算符:
      1. ! 非运算
      2. -o 或运算
      3. -a 与运算
    • 字符串运算符:

      1. = 检测两个字符串是否相等;算数运算符的相等比较用==
      2. != 检测两个字符串是否相等
      3. -z 检测字符串长度是否为0
      4. -n 检测字符串长度是否为0
      5. str 检测字符串是否不为空
    • 文件测试运算符:

      1. -b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
      2. -c file 检测文件是否是字符设备文件。
      3. -d file 检测文件是否是目录。
      4. -f file 检测文件是否是普通文件(既不是目录,也不是设备文件)。
      5. -g file 检测文件是否设置了 SGID 位。
      6. -k file 检测文件是否设置了粘着位(Sticky Bit)。
      7. -p file 检测文件是否是具名管道。
      8. -u file 检测文件是否设置了 SUID 位。
      9. -r file 检测文件是否可。
      10. -w file 检测文件是否可写。
      11. -x file 检测文件是否可执行。
      12. -s file 检测文件是否不为空(文件大小是否大于0)。
      13. -e file 检测文件(包括目录)是否存在。
  • break命令

    • 跳出循环,不跳出case
    • 在嵌套循环中,break 命令后面还可以跟一个整数,表示跳出第几层循环
  • 函数

    • 定义函数时,函数名前加上关键字 function 可有可无
    • 可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值
    • 调用函数只需要给出函数名,不需要加括号
    • 删除函数也可以使用 unset 命令,不过要加上 .f 选项
    • 将函数定义在主目录下的 .profile 文件,这样每次登录后,在命令提示符后面输入函数名字就可以立即调用
  • 输入输出重定向

    1. command > file 将输出重定向到 file。
    2. command < file 将输入重定向到 file。
    3. command >> file 将输出以追加的方式重定向到 file。
    4. n > file 将文件描述符为 n 的文件重定向到 file。
    5. n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
    6. n >& m 将输出文件 m 和 n 合并。
    7. n <& m 将输入文件 m 和 n 合并。
    8. << tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。

      /dev/null 文件是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到.

  • 文件包含

    • Shell 中包含脚本可以使用:. filenamesource filename
    • 被包含脚本不需要有执行权限
文章目錄
  1. 1. Shell 在线环境
  2. 2. 几种常见的Shell
  3. 3. 不使用Shell的情况
  4. 4. Shell脚本
    1. 4.1. 变量
    2. 4.2. Shell替换
    3. 4.3. 注释
    4. 4.4. 字符串
    5. 4.5. 数组
    6. 4.6. printf命令
    7. 4.7. case … esac
    8. 4.8. 运算符
    9. 4.9. break命令
    10. 4.10. 函数
    11. 4.11. 输入输出重定向
    12. 4.12. 文件包含