当使用不同的术语代表不同的概念时,可以促进清晰的思维和清晰的沟通。
当两个概念非常相似但又不同时,这特别有用。
我们倾向于使用术语“命令”来表示两个非常相似但不同的概念。
概念 1:在命令行界面上输入的单个程序。
选项可能会传递给程序,但仍然只有 1 个程序正在使用。
例子):
$ ls
$ ls -alF
这个概念被称为“命令”。
概念 2:在按 Enter 键指示 shell 处理之前在命令行界面上输入的任何内容。
例子):
$ ls -alF | head > output.txt; cat output.txt
这个概念也称为“命令”。
即使根据前面的定义它包含 3 个不同的“命令”,情况也是如此。
对于那些希望使用不同术语来表示不同概念以便更精确地思考和交流想法的人来说,使用什么术语来表示这两个不同的概念最好?
答案1
好吧,我想您可以阅读 Shell 命令语言规范,尤其是。2.9 Shell命令。
本节介绍 shell 命令的基本结构。下面的命令描述各自描述了命令的格式,仅用于帮助读者识别命令类型,并不正式表示语法。 [...] 每个描述都讨论了命令的语义;有关命令语言的正式定义,请参阅外壳语法。
命令是以下之一:[简单命令、管道、列表、复合命令、函数定义]
下面这个是一个简单的命令,ls
这是“命令名称”:
ls -alF
下面这个是一个管道其中有两个简单的命令:
ls -alF | head > output.txt
下面这个是一个顺序列表(或者只是一个列表)的管道和一个简单的命令:
ls -alF | head > output.txt; cat output.txt
(话又说回来,您也可以将此处的第一个示例视为(退化)管道。)
下面是一个带有 AND 列表的列表,其中包含复合命令和简单命令的管道,列表中的下一个是另一个简单命令。
for x in a b c; do echo "$x"; done | cat -n && echo ok; echo end.
(如果我正确地阅读了列表中的部分,如果您用换行符而不是 分隔命令;
,那么它将是一个复合列表,但这已经是挑剔了。)
我真的不希望其他文档(或本网站上的帖子)仔细遵守(正确)使用这些确切的短语,因此尝试精确地使用它们进行交流可能会很困难。拥抱混乱。
答案2
我认为存在(至少)4 个不同的概念,通常称为“命令”。按照复杂性递增的顺序:
命令名称:可执行程序或脚本的名称(或路径)。例如,
ls
、cat
、/usr/libexec/bootpd
等。命令名称和参数列表。例如,
ls
、-l
和/etc
。这对应于参数execl()
(除了命令名称将被传递两次),并且是您可以与find .. -exec
或sudo
大多数其他运行命令的上下文一起运行的内容不让它们穿过外壳。请注意,在这种形式中,参数根本没有语法,它们只是字符串,由命令可执行文件决定它们的含义。(请注意,当您运行
find ... -exec
或 时sudo
,整个命令都会由 shell 解析,但这是find
/命令,而不是或将要运行的sudo
命令。这就是为什么您不能在或运行的内容中包含重定向之类的内容。 )find
sudo
find
sudo
这个通常不被认识到,但在我看来,理解它对于理解命令由 shell 以外的其他东西运行的情况至关重要。
一个简单的 shell 命令。这是一个单个字符串(与上一个字符串不同,后者是一个单独字符串的列表),通常由命令名称和参数(用空格分隔)组成,可能还包括一些其他内容,例如重定向和/或环境变量分配。它可以包含各种 shell 语法,如引号、变量替换等。例如:
ls -l /etc >"$outdir/etcfiles.list"
。这还包括一些与前两种意义上的命令不对应的内容,例如变量赋值 (
var=something
)、shell 内置命令、函数、别名以及(取决于 shell)[[ ]]
条件表达式和(( ))
算术表达式等内容。任何可以放在 shell 中的一行中的内容。从技术上讲,这可以分为管道、列表、复合命令等。正如 ilkkachu 所说,请阅读Shell 命令语言规范,第 2.9 节 Shell 命令了解详情。
我也同意 ilkkachu 的观点,即尝试开发或使用完全一致的术语是没有意义的。即使你可以,大多数使用这些术语的人也不会完全理解它们之间的区别,并且他们最终会在短时间内混淆在一起(考虑将所有 shell 称为“bash”的人数)。你只需要从上下文中找出答案即可。
另外,事情可能会变得有点奇怪,例如ls -l $(echo "$PATH" | tr : " ")
包含管道的简单命令。
答案3
这个问题感觉应该作为“意见”问题结束,但无论如何我都会尝试回答。
首先,我通常将第二个概念中的事物类型称为“一行”,尽管我会同样轻松地使用术语“命令”。这提出了我的第一个观点:您对第二个概念的定义是有缺陷的,因为您可以在按“Enter”之前输入多个命令。您的示例中的;
分隔两个不同的命令。我不认为该示例是一个命令,我认为它是两个命令。管道符号将两个命令统一为一个“命令管道”,我仍然将其视为单个命令。
我还认为“命令”可以是简单命令,例如ls
,也可以是复合命令,例如管道。因此,术语“命令”在这两种情况下都是有效的。
总之,我认为您发布的概念没有足够的差异来真正保证不同的术语。