在类似 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
) 尚未生效。结果,将被替换为之前的任何值,如果未设置,则替换为空字符串$abc
。abc
然后,空字符串将被完全删除,因为它没有被引用。 - 命令替换:不适用
- 算术扩展:不适用
- 分词:唯一的候选者是
$abc
变量扩展的结果,但空字符串中没有任何内容可以分割。 - 路径名扩展:没有任何适用的
扩展完成后,将要abc
启动的实用程序的环境中的变量设置为值“hello”并echo
执行命令。它只输出一个空行。
严格来说,ls
也作为参数传递,作为它的argv[0]
.ls
使用该参数来了解它是如何调用的,也在它输出的错误消息中使用它,但不将其视为要执行操作的选项或文件。
² 如果它是符号链接,但其目标无法解析,则某些ls
实现将输出错误消息,就好像该文件不存在一样