参数扩展

参数扩展

我一直在玩参数扩展。以下是我的代码。

a="one"
sh -c 'echo $a'

b="two"
sh -c "echo $b"

c="three" sh -c 'echo $c'
echo $c

这是我执行此脚本时的输出:

$sh test.sh

two
three

$

对于 $a,如果单引号会抑制替换。它不应该只打印 echo $a 吗?它正在打印一个新行,这是否意味着 $a 的值为空?对于 $c,“echo $c”不起作用,不会打印新行,但下一行中的 echo $c 按预期工作。我有点困惑这是如何工作的。

答案1

sh -c 'echo $a'就像打开一个新的外壳并echo $a在其中输入一样。由于子 shell 中没有变量a(您没有export在父 shell 中设置变量),因此它将打印一个空行。

b="two"
sh -c "echo $b"

,该"echo $b"字符串由当前 shell 展开,并将展开后的值作为参数字符串传递给子 shell。就好像您打开了一个新 shell 并输入了echo two

var=val command暂时设置 和exports var=val,只是为了调用command.

c="three" sh -c 'echo $c'

几乎(子壳并不真正存在)就像

( export c="three"; sh -c 'echo $c' )

父 shell 中的 c 变量不受影响。

答案2

如果您想查看子流程中的变量,则必须查看export它们。像这样:

   $ export a=7
   $ sh -c 'echo $a'
   7

在您的情况下,子进程( forab)看不到来自父 shell 的变量。

当您使用单引号创建字符串时,所有替换都不起作用。您不能替换变量或类似的东西\n。它将恰好是$a\n。因此,第一种情况下的字符串正是“echo $a”。sh -c 'echo $a'将创造新的进程,并且该进程不会有父进程$a,它将有自己的 uninitialized $a,即空字符串。它只会执行'echo $a'

在第二种情况下,您使用双引号。替换有效,字符串变成"echo two" 执行子进程。所以,这只是执行sh -c 'echo two'

在第三种情况下,$c成为导出变量。这是一种特殊的语法,意味着“仅为此命令导出变量”。因此,您准确执行sh -c 'echo $c',但新的 shell 将包含$c作为环境变量。就像$PATH$HOME当你启动 shell 时一样。

相关内容