在研究有关 Bash 子 shell 的更深入信息时,我遇到了一个有趣的执行,我想了解它的工作原理。执行涉及将字符串分配给变量,然后在以下情况下使用该变量:man
调用时使用该变量,链接到原始示例。我已经读过为什么LESS
在该示例中使用特定变量(在许多发行版中man
作为less
默认分页器),我不明白的是命令执行后的变量赋值如何在没有任何类型的分隔元字符的情况下工作。
LESS=+/'OPTIONS' man man
man
直接在该部分下打开命令的手册页OPTIONS
。它适用于直接使用less
太打开的文件(这使我相信该LESS
变量的使用方式与在“会话”less
中进行正则表达式搜索相同less
)。该LESS
变量不会被导出,它永远不会保存在当前的 shell 环境中(执行echo $LESS
不会返回任何内容),那么如何less
捕获该值呢?
为什么这有效,但不是类似的东西foo='hello' echo $foo
?仅当;
变量赋值和命令执行之间包含命令分隔符 ( ) 时,这种情况才有效。我什至尝试过foo=+'hello' echo $foo
以防万一=+
在 Bash 中做了一些我不知道的事情,但输出没有变化。
欢迎任何解释或阅读材料!
答案1
这是一个标准功能。您可以在启动命令时设置该变量,然后将为该命令设置该变量。它也适用于您展示的示例foo='hello' echo $foo
。问题是你测试的方式不对。当你运行这个时:
foo='hello' echo $foo
shell 将扩展变量前运行命令。由于foo
启动时并未实际设置,因此变为echo
(无回显)。您可以通过以下方式查看set -x
:
$ set -x
$ foo='hello' echo $foo
+ foo=hello
+ echo
现在,将其与使用一个小脚本以使 shell 看不到该变量时发生的情况进行比较:
$ cat ~/scripts/foo.sh
+ cat /home/terdon/scripts/foo.sh
#!/bin/bash
echo "The value of foo is:$foo"
用它来回显变量,你会得到:
$ foo='hello' ~/scripts/foo.sh
+ foo=hello
+ /home/terdon/scripts/foo.sh
The value of foo is:hello
bash -c
如果您调用并将给定的命令用单引号括起来,则可以执行相同的操作,这样该变量将受到保护,并且在调用之前不会被当前 shell 扩展bash -c
:
$ foo='hello' bash -c 'echo $foo'
hello
虽然这会失败,因为双引号意味着在看到它$foo
之前就已经被扩展了bash -c
:
$ foo='hello' bash -c "echo $foo"
$
该行为记录man bash
在“环境”部分中:
The environment for any simple command or function may be augmented
temporarily by prefixing it with parameter assignments, as described
above in PARAMETERS. These assignment statements affect only the envi‐
ronment seen by that command.
手册中也有详细描述:3.7.1 简单命令扩展