我读过分号用于分隔程序:
$ echo 3; ls -la
这是否意味着if
、then
和else
是这里的单独程序?
$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi
这个问题与分号无关。
答案1
分隔;
语句(宽松地说)。 (几乎)总是可以;
用换行符替换 a 。
说;
分隔两个程序,因此if
和then
必须是“程序”有点过于简单化,因为语句可能由保留字、shell 函数、内置实用程序和外部实用程序以及使用管道和布尔运算符等的组合组成。 ETC。
和if
都是then
保留字shell语法,而不是“程序”。在这里,它们被用来构建技术上所谓的复合命令。
echo
可能是 shell 中的内置实用程序(但不一定是),并且ls
可能是外部实用程序(或如您所说的“程序”)。
答案2
虽然当一个人开始学习使用 shell 的基础知识时,这是一个公平的第一个近似值,但在“这是一个人如何运行一个程序”和“这是一个人如何在一行上一个接一个地运行多个程序”的级别上,实际上并非如此。
对于初学者来说更难掌握但更正确的解释是 shell 语言是一种计算机语言。它有一个句法。该语法包括各种词汇元素包括(除其他外)换行符、运算符、单词和保留字。
if
、then
、else
、fi
都是保留字。当它们有特殊含义时解析给 shell 的输入,根据它的语法。同样,;
是一个分隔符操作员。
因此,shell 语言中的输入作为一个整体,是一个计算机程序,解释的通过另一个程序,口译员, 贝壳。它的各个语法部分不是程序。 shell 语言是一种指定 shell 运行的(其他)程序的方法。
[
不是 shell 语法中的特殊词汇元素(例如运算符)。这是一个普通的单词,其中命名了一个这样的程序[
。许多贝壳都有一个内置这个程序的版本,合并到shell程序本身的代码中,但你也可以找到一个外部的在某处使用此名称进行程序,例如/bin/[
或/usr/bin/[
,其中程序以外shell 可以调用。同样,]
也不是特殊的 shell 词汇元素。这是一个普通的词,成为[
程序的一个参数。该[
程序要求其最终参数在执行时为 ,]
然后继续忽略。
您问题中提到的另一个类似程序是echo
.同样,大多数 shell 都有该程序的内置版本。但同样,程序还有一个外部版本,例如/bin/echo
或/usr/bin/echo
,用于程序以外要调用的 shell。
您的问题中指定的第三个程序是ls
. Shell 通常没有该程序的内置版本,它是一个外部程序,可以在/bin/ls
或 之类的地方找到/usr/bin/ls
。
对于 Bourne Again shell,您可以在外壳基本功能GNU Bourne Again shell 信息文档。当然,其他 shell 有不同的语法。这单一 Unix 规范描述了所有符合 POSIX 的 shell(在其符合 POSIX 的模式下)都应该遵守的语法。
进一步阅读
答案3
if
将then
和else
视为外部程序实际上并不牵强。事实上,Thompson shell 在最初的第 1 版 Unix 中if
作为goto
外部程序实现。这是可能的,因为子进程与 shell 进程共享文件描述符,因此(转发)goto 只需读取输入,直到找到目标标签然后退出。看汤普森壳。
答案4
if
、elif
、then
和fi
都是保留关键字,用于实现 shell 中称为复合命令的结构之一,这意味着 shell 中不能存在具有任何这些名称的命令(或者更确切地说,另一个命令)。一般来说, 的目的;
不是分隔命令,而是终止命令列表。例如,以下是一个有效的if
语句:
if echo foo; echo bar; echo baz; then echo done; echo really done; fi
语句的条件if
是命令列表echo foo; echo bar; echo baz
。解析器知道条件已经结束,因为then
紧跟在分号后面的 不能是命令,因为它是保留关键字。因此,它知道什么如下 then
是身体的开始。同样,fi
是保留关键字,因此不能是语句正文中的第三个命令if
,但标记复合命令的结束。