这个单词命令在Linux中指的是两个不同的概念:
- 一个可执行程序,例如grep(或者内置的 shell,例如光盘)。用法示例:“这是您应该学习的 10 个最重要的 Linux 命令。”
- 发送到 shell 执行的完整文本字符串,例如grep com /etc/hosts。用法示例:“键入 Linux 命令并按 Enter 键。”
在撰写有关 Linux 命令的散文时,有人有避免这种歧义的最佳实践吗?以下是我已经拒绝的一些尝试:
- 使用这个词程序或者可执行文件对于意义#1。对于 shell 内置函数来说这是不准确的。
- 使用短语命令行对于意义#2。这很令人困惑,因为“命令行”也是“shell”的同义词。
- 使用短语命令串对于意义#2。它不精确,因为 #1 和 #2 都是字符串。
任何建议表示赞赏。
答案1
POSIX指的是类似grep
和cd
作为的事物“公用事业”, 和储备”命令“获取说明。如果使用一致,这些术语是明确的。
依次处理您的案件
“可执行程序,例如 grep(或内置 shell,例如 cd)”是一个公用事业:
公用事业一个程序,不包括特殊的内置实用程序作为 Shell 命令语言的一部分提供,可以从 shell 中按名称调用以执行特定任务或相关任务集。
这是进一步澄清:
系统可以将某些实用程序实现为 shell 函数或内置实用程序
需要明确的是,这包含了普通的实用程序,例如
true
通常作为 shell 内置程序找到的实用程序。正式地,“特殊的内置实用程序" 与未进一步指定的实用程序分开;这些是诸如
break
、.
、eval
、set
和 之类的东西trap
,它们会影响 shell 的内部状态,但它们不要includecd
,这是一个常规的内置函数。除了规范的细微差别需求(某些变量赋值行为不同并且它们不可用于execvp
)之外,“实用程序”足以涵盖用户级别的这两个类别。像if
和这样的 shell 语法文章while
根本不是实用程序。“发送到 shell 执行的完整文本字符串,例如
grep com /etc/hosts
”是一个命令:命令指示 shell 执行特定任务的指令。
命令确实包括简单命令(例如
grep com /etc/hosts
、管道)和复合命令(例如if
使用 构造和分组命令)( ... )
,但“命令”一词从来不指实用程序本身。在一个命令中,一个命令名称可能会出现标识实用程序或函数:grep com /etc/hosts
is中的命令名称grep
,指的是grep 实用程序。
用“命令”表示实用程序或功能的白话用法可以通过上下文消除歧义,但正式含义只是指令。如果需要完全避免歧义,您可以一致地使用“实用程序”和“命令”对于这两个角色。
不过,您可能无法指望用户自己做出这种区分,因此搜索引擎优化的“十大 Linux 命令”文章可能会为他们的激励做出正确的选择。
答案2
概括
您在这里提到的感知的歧义类型最好通过使用诸如程序, 一个可执行文件,或者只是一个可执行文件对于有/是一条路径的,与外壳命令甚至命令行 当你想引用你输入的所有内容时命令解释器。
历史背景
早期印刷品索引C 编程语言(“K&R”,Prentice-Hall)仅提及该词一次命令,并不是专门针对这个词,而是针对命令行参数。这个意义的小核心提供了发芽并衍生出所有后来用途的关键种子。摘自 1978 年印刷的第 111 页:
5.11 命令行参数
在支持 C 的环境中,有一种方法可以在程序开始执行时将命令行参数或参数传递给程序。
也就是说,这个词命令在 shell 上下文中唯一使用(因为 shell 根据定义是一个命令解释器),无论是交互式使用还是脚本编程。作者继续这个例子:
必要的声明和使用的最简单说明是程序
echo
,它只是在一行上回显其命令行参数,并用空格分隔。也就是说,如果命令echo hello, world
给定,输出为
hello, world
请注意 K&R 是如何谈论程序和命令行的。换句话说,这就是 IEEE 的POSIX 1003.2都是关于不是什么POSIX 1003.1是。一般来说,Dot-1 涵盖 C 编程,而 Dot-2 涵盖 shell 编程。
您在这里真正讨论的是 shell 编程而不是 C 编程。这就是为什么介绍Unix 程序员手册第 1 部分提到命令而不是函数调用:
姓名
intro — 通用命令介绍(工具和实用程序)
描述
第 1 节中的手册页包含构成 BSD 用户环境的大部分命令。第 1 节中包含的一些命令包括文本编辑器、命令 shell 解释器、搜索和排序工具、文件操作命令、系统状态命令、远程文件复制命令、邮件命令、编译器和编译器工具、格式化输出工具以及行式打印机命令。
所有命令在退出时都会设置一个状态值,可以测试该状态值以查看命令是否正常完成。退出值及其含义在各个手册中进行了解释。传统上,值 0 表示命令成功完成。
如果您使用 1003.1 术语,您可以将其称为字符串参数这系统C 库中的函数。这是因为它本身不是系统调用,而是一个在底层使用各种系统调用的库函数,其中之一是
execve
。该系统调用采用一个常量
char *
参数作为其第一个参数,它是文件系统中可执行文件的路径。
已发布的解决方案
一项已发布的解决方案始终使用以下定义:
可执行文件
A文件是专门标记来告诉操作系统可以将此文件作为程序运行。通常缩写为“可执行”。
命令
在壳编程,程序名称及其参数的语法组合。更宽松地说,您在 shell(命令解释器)中键入的任何内容都会启动它执行某些操作。 [...]
命令行参数
当您告诉 a 时您提供的值以及程序名称 壳执行一个命令。 [...]
命令名称
的名称程序当前正在执行,如在命令行。 [...]
摘自第四版Perl编程(O'Reilly),此处使用已获得该书作者的许可。 :)。
如果幸运的话,您可以自己找到所有这些内容,甚至更多,只需在 shell 中输入这个简单的命令行即可运行男人为您提供的可执行文件/程序:
man perlglossary
但如果你没那么幸运的话你也可以在这里找到它们。
外壳命令
这可能是一个 shell 命令:
exec 2>errs.out
请注意,那里什么也没有exec
;我们刚刚重新排列了文件描述符。
这里同上:
exec 5<&0 # save old stdin
exec 0<&3 # read some_var
exec 0<&4 # read another_var
exec 0<&5 # restore it
execve
因此,脚本中的每一行都是一个“命令”,即使在这里(我将完整运行时产生的实际系统调用数作为练习留给读者):
#!/bin/sh
device=/dev/rmt8
dd_noise='^[0-9]+\+[0-9]+ records (in|out)$'
exec 3>&1
status=`((dd if=$device ibs=64k 2>&1 1>&3 3>&- 4>&-; echo $? >&4) | egrep -v "$dd_noise" 1>&2 3>&- 4>&-) 4>&1`
exit $status
取自可敬的杰里米亚德Csh 编程被认为是有害的,经善意许可再次在这里使用等等等等。 :)
答案3
一个相当简单的解决方案(以及标准的哲学和语言回避)是为了区分使用这个单词命令, 和提及这个单词命令。例如,某些单词执行动作,即使在普通英语中也是如此,它们的使用就是它们执行动作的方式。例如,如果你在适当的情况下说“我愿意”,你可能会结婚。但如果你引用别人可能说的话就不行了。引用的任何内容都是提及,而不是使用。
所以第一个命令列表不是命令的使用;而是命令的使用。他们提到了命令。
第二个例子,就像我最喜欢的
$ rev wordlist | sort | rev > speculum
(生成 的逆字母顺序副本wordlist
)
实际上会做某事,所以它们肯定是用途。
答案4
我会考虑没有必要作为答案,因为所描述的歧义无论如何不会造成任何伤害。
在我见过的所有上下文中,当“命令”一词指代可执行程序时,最终用户总是会在 shell 中键入命令以使其运行。我从未见过这样的表达“命令init
“ 或者 ”命令ld-linux.so
”。
当“命令”指的是命令行程序时,它实际上总是指“以该程序开头的命令系列”。例如,当你说“命令grep
”,你谈论的是你可以用程序做的所有事情grep
,它形成了“一系列命令”。这也适用于部分命令,就像俗话“该apt install
命令用于安装软件包" 当完整命令apt install
通常没有任何作用时。