在复合命令中使用“;”

在复合命令中使用“;”

该命令的语法for是:

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

该命令的语法case是:

case word in [ [(] pattern [| pattern]...) command-list ;;]... esac

select结构是 Bash 对 POSIX 的扩展。它允许轻松生成菜单。它的语法与 for 命令几乎相同:

select name [in words ...]; do commands; done

该命令的语法{...}是:

{ list; }

问题:

  1. 为什么命令中的子句case用 分隔;;,而不是;其他命令中使用的分隔?

  2. forand命令中case,当in部分被忽略时,为什么下面的;;;也被忽略而不是剩余?

    相比之下,在select命令中,;当该部分被忽略时, 不会被忽略in

    case请注意,命令中的in以下部分不会被忽略,而在for命令中则会被忽略。它们是任意不一致的 POSIX shell 设计吗?

  3. 复合命令中使用了;哪些类型的标记?;;

    在命令列表中(与复合命令相反),;是一个控制操作符。

  4. 复合命令中为什么和之间{ list; }必须有一个?算子句,也是子句吗?复合命令中的子句必须用换行符分隔吗?进一步阅读;list}}{ list;对我之前的问题和荷马的答复,我问“为什么我们需要分号而不是空格来分隔单词?”,因为“分号和空格都是 shell 元字符”,

笔记:

我还想列出whileuntil和命令的语法,但我认为就 的使用而言,if它们的行为与命令类似。for;

答案1

;;要回答有关与;in语句的部分,请考虑如果终止特定分支,则case不可能编写一个单行命令,该命令将在 case 语句的单个分支中运行多个命令。;

您仍然可以使用多行命令来完成此操作,但是以这种方式设计 shell 语法会要求多行,并且在 shell 语法中没有其他地方无法避免多行(换行符)。;;在 shell 设计中使用case 开关可以在编写代码时提供更大的灵活性。


casefor、和相比while,所有这些命令在每个用例中都遵循特定的保留字。 ( ,,,,,,, )​​​​untiliflistthenelifelsefidodone

case另一方面遵循一个带有“模式”的列表,它可以是任何事物——所需的模式也可能是有效命令的名称。

答案2

最基本的构建块是“简单命令”(LESS=+/'简单命令' man bash)

简单命令 简单命令是...,并由控制操作员终止。

通常,逗号 (;) 是终止简单命令的控制运算符。

在从手册中复制的大多数行中,(;) 用作终止控制字符。例如,在:

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

两者in words;commands;都可以是由 终止的“简单命令” ;。在这个简单的例子中:

for w in $(echo "a b c"); do echo $w; done

echo "a b c"都是echo $w简单的命令。由 生成的列表echo "a b c"以 a 终止;(以检测列表的末尾)。
这不是必须的,效果是一样的:

for   w in    $(echo "a b c")
do    echo $w
done

在 for 循环中整体[ [in [words ...] ] ; ]是可选的唯一原因是因为在这种情况下,元素列表是“位置参数”列表(可以使用 进行设置set):

$ set -- *
$ # for name [ [in [words ...] ] ; ] do commands; done
$   for f                            do echo $f; done

如果您应用“简单命令”的相同概念来构建“复合命令”,那么您的大多数问题都是必要的。

  1. 为什么 case 命令中的子句用 分隔,;;而不是;其他命令中使用的?

为了能够检测到结束一些简单的命令以简单的字符结尾;

    case b in ([a-d]) echo "yes"; cp filea fileb; rm filed; ;; esac

或者为了可读性而重写:

    case b in
        ([a-d])
                echo "yes";
                cp filea fileb;
                rm filed;
        ;;
    esac
  1. forand命令中case,当in部分被忽略时,为什么下面的;;;也被忽略而不是剩余?

在 case 子句中 in 的使用不是可选的。

2.2.相比之下,在select命令中,;当 in 部分被忽略时,不会被忽略。

当单词列表由命令 (ls *) 的输出提供时,该部分[in words ...]以 a 终止;,与命令中使用的方式完全相同for

2.3.请注意,case命令中的in以下部分不会被忽略,而在for命令中则会被忽略。它们是任意不一致的 POSIX shell 设计吗?

不,除了由于对命令的不完全理解而产生的不一致之外,没有任何不一致。

  1. 复合命令中使用了;哪些类型的标记?;;

“控制运算符”用于终止一个或多个“简单命令”。

复合命令中为什么和之间{ list; }必须有一个?;list}

不,没有“必须”,这是一个正确的列表:

[ 2 -lt 4 ] &&
{ echo "yes"
  echo "it is smaller"
}

“看,马!!不(;)”但是需要使用某种元字符(换行符)来使}自己独立。

是的:[ 2 -lt 4 ] && { echo "yes"; echo "it is smaller"; }看起来不一样。
但是是完全相同的命令。

忽略有关从句的部分(一个有自己的详细信息列表的新词)。
我没有数,但是有超过 10 个关于time、builtin、words、token 等的问题。你会在这里遇到类似的问题吗?

您终于知道什么是或不是“简单命令”了吗?
然后你可能会考虑“复合命令”,然后(经过认真思考)一些其他问题。

相关内容