为了简单起见,参考以下代码
#!/bin/bash
number=7
function doSomething() {
number=8
}
doSomething
echo "$number"
它打印8
.
但与:
#!/bin/bash
number=7
function doSomething() {
number=8
}
$(doSomething)
echo "$number"
它打印7
.
我有以下问题:
- 什么是技术名称对于每一个?,我的意思是
functioncall
和$(functioncall)
- 每种方法如何发挥作用?似乎前者考虑(影响)函数本身之外的变量,后者则不考虑
- 何时强制使用一种方法而不是另一种方法(主要是关于性能问题 - 当然 - 如果有的话),如果有其他原因,欢迎他们。
答案1
您正在体验命令替换的微妙之处。
电话
doSomething
是一个简单的函数调用。它执行该函数,就像您将该函数的命令复制并粘贴到调用它的位置一样。因此,它number
用新值覆盖变量8
。
电话
$(doSomething)
另一方面是命令替换。它的目的是执行该函数并且返回函数打印到的任何内容 stdout
。它通常不“独立”使用,而是在变量赋值中使用,例如,
os_type=$(uname)
这将执行命令uname
,在 Linux 系统上该命令将打印Linux
到控制台,并将其结果存储到 shell 变量中os_type
。因此,使用不输出任何内容的命令或函数(例如您的doSomething
.事实上,由于替换$(doSomething)
基本上是 的输出的占位符doSomething
,因此您没有收到脚本错误的唯一原因是您的函数不输出任何内容。你是否说过,例如,
$(uname)
代替
$(doSomething)
你的 shell 会尝试执行该命令Linux
并生成一个
Linux: No such file or directory
错误(1)。
了解您观察到的效果的关键点是在命令替换中,该命令在子 shell 中执行,即对变量所做的任何更改都不会反向传播到执行主脚本的 shell。因此,虽然它在内部运行 的命令doSomething
并将变量设置number
为8
,但它是在自己的 shell 进程中执行此操作,该进程与运行脚本的 shell 进程无关(除了stdout
正在检索脚本的事实之外),因此无法修改number
您在主脚本中使用的变量。
如需进一步阅读,您可能需要查看
在这个网站上,或者
了解更多概述。
(1)另一方面,这意味着您可以使用命令替换来执行在编写脚本时不知道其名称的命令,但您可以通过执行另一个您知道的命令来查明该命令的名称。