3.基本shell功能

3.2 shell命令

3.2.4 复合命令

3.2.4.1 循环结构

note:不论;出现在命令语法的何处,都可能会被一行或多行代替。 - until - while - for

for name [ [in [words …] ] ; ] do commands; done

展开words,并对结果中的每个成员执行一次命令。如果in words没有填写,为每个位置参数执行一次命令,就像$@被指定了 see Special Parameters

另外一种格式:???

for (( expr1 ; expr2 ; expr3 )) ; do commands ; done

3.2.4.2 条件结构

  • if
    if test-commands; then
      consequent-commands;
    [elif more-test-commands; then
      more-consequents;]
    [else alternate-consequents;]
    fi
  • case
case word in [ [(] pattern [| pattern]…) command-list ;;]… esac

执行pattern匹配到word的命令组。patterns与相关的command-list一起被称作clause。 每个clause必须以三种符号结束:;;,;&,;;&。例:

    echo -n "Enter the name of an animal: "
    read ANIMAL
    echo -n "The $ANIMAL has "
    case $ANIMAL in
      horse | dog | cat) echo -n "four";;
      man | kangaroo ) echo -n "two";;
      *) echo -n "an unknown number of";;
    esac
    echo " legs."

如果使用;;结束,那么匹配到第一个clause后即停止,不会向后继续匹配。使用;;&可达到相反的效果。使用;&则会导致继续执行下一个clause。如果没有匹配则返回0,否则返回执行命令的退出状态。 - select - ((...)) - [[...]]

3.2.4.3 组命令

Bash提供了两种方式来将一组命令作为一个整体来执行。当命令被组所包括时,重定向可能会应用到整个命令列表中。

  • ():(list),以小括号的方式包围命令会创建一个子shell环境,每个命令会在子shell中执行。
  • {}:{list},以花括号的方式包围命令会在当前shell的上下文中执行listlist中的命令需要以换行或者分号隔开。

3.3 shell 函数

语法:

name () compound-command [ redirections ]

or

function name [()] compound-command [ redirections ]

函数体compound-command,参见Compound Commands

例:

as_fn_append () { eval $[1]=\$$[1]\$[2]; }

3.4

3.4.2 特殊参数

不允许赋值。使用$引用。

  • *:从第一个开始展开成位置参数。
  • @:从第一个开始展开成位置参数。
  • #:参数数量。
  • ?:最近的管道执行的退出状态。
  • -:调用时指定的当前选项标志。
  • $:shell进程ID。在一个()子shell中,扩展为调用shell,而不是子shell。
  • !:最近别放在后台运行的job的ID,不论是异步命令或者使用的bg
  • 0:shell的名字或者shell脚本的名字。
  • _:在shell开始的时候,被设置为绝对路径用于:当被传递给环境或者参数列表中时,调用正在被执行的shell或shell脚本。

3.5 shell扩展

3.5.2 shell参数扩展

特殊情况:如果parameter的第一个字符是!,那么它不是nameref,而是变量级别的指令。该变量的值由其余参数组成。称作indirect expansion

parameter:变量名。*@会作用到每个成员上面。正则表达式参考see Filename Expansion

包括冒号则会测试参数的存在且值非空,省略冒号只测试参数是否存在。

  • ${parameter:-word} - 如果parameter未设置或为null,替换word的扩展。否则替换参数的值。
  • ${parameter:=word} - 如果parameter未设置或为null,word的扩展被分配给参数。然后parameter的值被替换。位置参数与特殊参数不能使用这种形式。
  • ${parameter:?word} - 如果parameter未设置或为null,word的扩展(或者是word不存在发出的信息)被写入标准错误和shell中,如果不是交互式的shell,则退出。否则替换参数的值。
  • ${parameter:+word} - 如果parameter未设置或为null,没有东西被替换。否则word的扩展被替换。
  ${with_fontconfig:-no}
  • ${#parameter} - parameter的长度。如果是数组:下标为数字时,长度为1;下标是* or @时,长度是元素的数量。
  • ${parameter#word} word是一个正则表达式。匹配的是parameter的头部,匹配到的字符串从parameter中删除。最短匹配规则。
  • ${parameter##word} - 最长匹配规则。
  • ${parameter%word} - 匹配的是parameter的尾部,匹配到的字符串从parameter中删除。最短匹配规则。
  • ${parameter%%word} - 最长匹配规则。
  • ${parameter/pattern/string} - 将pattern匹配到的字符串用string代替。最长匹配规则。
    • 如果pattern/开始,所有的匹配都会被替换;正常情况下只有第一个会被替换。
    • #开始,匹配头部
    • %开始,匹配尾部
    • 如果string是空的,匹配到的会被删掉
    [root@dev home]# echo ${str}
    abcdefgaabdd
    [root@dev home]# echo ${str/a/ss}
    ssbcdefgaabdd
    [root@dev home]# echo ${str//a/ss}
    ssbcdefgssssbdd
    [root@dev home]# echo ${str//a/}
    bcdefgbdd
  • ${parameter^pattern} - 匹配字母字符,pattern应该只匹配一个字符。如果pattern为空,匹配所有的字符。小写转大写,匹配第一个字符。
  • ${parameter^^pattern} - 匹配所有的字符。
  • ${parameter,pattern} - 大写转小写,匹配第一个字符。
  • ${parameter,,pattern} - 匹配所有的字符。
  [root@dev home]# echo ${str}
  abcdefgaabdd
  [root@dev home]# echo ${str^a}
  Abcdefgaabdd
  [root@dev home]# echo ${str^^}
  ABCDEFGAABDD

3.5.8 文件名扩展

3.5.8.1 正则匹配

反斜杠用于转义下面这些特殊字符,来使他们变成字面上的意思。

  • * - 匹配任何字符串,包括空串。shell选项globstar可用时,*在一个文件名扩展内容中使用,**作为一个单一的正则会匹配所有的文件和文件夹及其子文件夹。如果后跟/**只匹配文件夹和子文件夹。
  • ? - 匹配任何单个字符。
  • [...] - 匹配任何封装的字符串。以!^开头时,表示不匹配。-表示范围表达式。
  • ?(pattern-list) - 0次或1次匹配。
  • *(pattern-list) - 0次或多次匹配。
  • +(pattern-list) - 1次或多次匹配。
  • @(pattern-list) - 1次匹配。
  • !(pattern-list) - 不匹配。