实际上是“ if”和“ then”程序吗


15

我读过分号用于分隔程序:

$ echo 3; ls -la

这是否意味着ifthen并且else这里是单独的程序?

$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi

这个问题与分号无关。



1
@StephenRauch不是真的重复。此外,它是该Q的合理结果,是为进一步理解而进行的尝试。
user207673

更多程序化的公式:[ $variable == abcdef ] && echo yes || echo no
哈根·冯·埃森

2
@HagenvonEitzen不是严格等效的,如果第一个分支内的语句失败,第二个分支也将执行。
摩根(Morgen)

Answers:


26

;中隔离报表(严格意义上)。(几乎)总是可以用;换行符代替。

如果说,;分隔两个方案,因此ifthen必须是“节目”是有点过于简单的语句可以由保留字,shell函数,内置的实用工具和外部公共事业,而这些使用管道的组合和布尔运算符等等

双方ifthen保留在字壳语法,而不是“程序”。在这里,它们用于构建技术上称为复合命令的对象

echo可能是外壳程序中的内置实用程序(但不是必需的),并且ls可能是外部实用程序(或您所说的“程序”)。


7

虽然这是一个不错的第一近似值,但是当人们开始学习使用shell的基本知识时,它的级别是“这是一个程序的运行方式”和“一个程序如何在一行上一个接一个地运行多个程序”。 ,实际上并非如此。

对于初学者来说,更难理解但更正确的解释是外壳语言是一种计算机语言。它具有语法。该语法包括各种词法元素,包括(其中包括)换行符,运算符,单词和保留单词。

ifthenelse,和fi都是保留字。根据语法,它们在解析给外壳的输入时具有特殊的含义。同样,是分隔符运算符;

输入在壳语言因此,作为一个整体,也就是计算机程序解释由另一个程序,一个解释器,该壳。它的个别语法部分不是程序。外壳程序语言是一种指定(其他)外壳程序运行的方式。

[不是外壳语法中的特殊词法元素,例如运算符。这是一个普通的,它命名了这样一个程序[。许多炮弹有一个内置的这个方案,组合成壳程序本身的代码的版本,但你也可以找到一个外部此名称程序的地方,如/bin/[/usr/bin/[,这节目除了弹可调用。同样,]它也不是特殊的shell词汇元素。这是一个普通的词,成为[程序的参数。该[程序要求其最后一个参数,在执行它,是],它前进到随后忽略。

您的问题中命名的另一个类似程序是echo。同样,大多数外壳程序都有此程序的内置版本。但同样,该程序还有一个外部版本,例如/bin/echo/usr/bin/echo,用于调用 Shell 以外的程序。

您的问题中命名的第三个程序是ls。Shell通常没有此程序的内置版本,它是一个外部程序,可以在/bin/ls或某个地方找到/usr/bin/ls

对于Bourne Again shell,您可以在GNU Bourne Again shell信息文档的基本Shell功能中阅读有关此内容的更多信息。自然,其他外壳有不同的语法。该单一Unix规格描述语法,所有POSIX符合的炮弹(在他们的POSIX符合的模式)都应该坚持。

进一步阅读

  • 壳语法 ”。 Shell命令语言。基本规范第7期。开放小组。IEEE 1003.1-2008。ISBN 1937218812。
  • test实用程序。基本规范第7期。开放小组。IEEE 1003.1-2008。ISBN 1937218812。
  • 壳语法 ”。 Z Shell手册。版本5.3.1。2017。

5

实际上if,将thenelse视为外部程序并不容易。实际上,Thompson shell在最初的Unix第1版中实现ifgoto作为外部程序。这是可能的,因为子进程与Shell进程共享文件描述符,因此(向前)goto只需读取输入,直到找到目标标签然后退出。见汤普森壳


或确实看到Laurent Bercot的ififelse,它们是的一部分execline。这些不是if问题所在。
JdeBP

2
“将if,then和else视为外部程序实际上并不容易”,是的,因为它们不是。
与莫妮卡(Monica)进行的轻量级比赛(

2

thenelse不是程序。其他部分是。注意,;在它们之后没有直接的',但是在命令之后它们在前面。

[ ... ] 一个命令,需要的;,如果跟其他的命令的开始。

据我所知,所有猛砸控制结构,并可能大多数* nix炮弹,都是一样的。它们是对口译员的指示。另一方面,测试或条件使用“执行”且为命令的程序/过程。因为then是导致echo命令的行的一部分,所以它必须与前一个命令用换行符分隔[ ... ]。它不需要与它控制的命令分开echo yes

从法律上讲,尽管丑陋且难以阅读,您也可以这样做。

if [ $VARIABLE == abcdef ]
then echo yes
else echo no
fi

请注意,这里的;控件之间根本不需要,即使它们不在一行上。

有趣的是,整个控制结构(if ... fi)是一个shell命令,并且整个结构必须以换行符或a结尾;。最后一行不能是,fi echo done但必须是fi; echo doneVARIABLE='abcdef'命令与分配相同。

即使整个控制结构是命令,它们仍然不是程序。


1

ifelifthen,和fi用于实现所述构建体中的一个的所有保留的关键字被称为在壳复合命令,这意味着不能有任何在壳这些名称的指令(或更确切地说,另一个命令)。通常的目的;不是分离命令,而是终止命令列表。例如,以下是有效的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语句主体中的第三个命令,而是标记复合命令的结尾。


谢谢,如果使用if program1 foo; program2 bar; program3 baz; 它,应该是哪个程序状态0,以便shell进行then?最后一个?
Maxim Koretskyi

只是program3 baz。命令列表的退出状态是该列表中最后一条命令的退出状态。其他两个可以失败而不影响条件。
chepner
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.