在 bash 中,为什么 `SHELL=/bin/sh lesspipe"` 语法正确?

在 bash 中,为什么 `SHELL=/bin/sh lesspipe"` 语法正确?

在类似 Ubuntu 的 Linux 上,默认.bashrc文件包含一行:

[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

那为什么SHELL=/bin/sh lesspipe语法上是正确的呢?我可以在哪一页man bash知道​​这句话的含义?对我来说,这个陈述似乎与例如,

ls echo

,这是无效的。还,

abc=hello echo $abc

没有错误但输出 null。

man bash尽管我尝试了一些/<expression>搜索命令,但我找不到任何相关信息less。谁能告诉我该命令的解释吗?


注:我已阅读帖子“你能解释一下默认 .bashrc 中的 eval 表达式吗”但什么也没得到。

答案1

正如钢铁司机所说,SHELL=/bin/sh lesspipe简单的命令,它被定义为以下序列:

  • 可选变量赋值(此处SHELL=/bin/sh),后跟...
  • 空白的- 分隔的单词和重定向(此处lesspipe),终止于...
  • A控制操作员,其中包括换行符。

你的第一个例子:

ls echo

实际上是一个有效的命令:只有第一个字被视为要执行的命令,其余的都作为参数提供给该命令。

对于命令,如果当前目录中ls有指定的子目录,则会列出其内容;echo如果存在名为 的非目录echo,则会显示其名称²。如果两者都不成立,该命令将返回错误并显示No such file or directory错误消息。

你的第二个例子:

abc=hello echo $abc

又是一个带有变量赋值的简单命令,但它还包含变量扩展($abc )。这扩张的章节man bash定义了各种扩展及其操作顺序。

命令行被分割成单词后,shell 检查扩展:

  • 大括号扩展:不适用
  • 波形符扩展:没有适用的
  • 参数和变量扩展:此处$abc替换为名为 的 shell 或环境变量的当前值abc。但由于该命令行尚未执行,因此该行前面的变量赋值 ( abc=hello) 尚未生效。结果,将被替换为之前的任何值,如果未设置,则替换为空字符串$abcabc然后,空字符串将被完全删除,因为它没有被引用。
  • 命令替换:不适用
  • 算术扩展:不适用
  • 分词:唯一的候选者是$abc变量扩展的结果,但空字符串中没有任何内容可以分割。
  • 路径名扩展:没有任何适用的

扩展完成后,将要abc启动的实用程序的环境中的变量设置为值“hello”并echo执行命令。它只输出一个空行。


严格来说,ls也作为参数传递,作为它的argv[0].ls使用该参数来了解它是如何调用的,也在它输出的错误消息中使用它,但不将其视为要执行操作的选项或文件。

² 如果它是符号链接,但其目标无法解析,则某些ls实现将输出错误消息,就好像该文件不存在一样

相关内容