为什么忽略函数中的赋值?

Why is the assignment in a function ignored?

考虑以下代码:

zzz=2

function f()
{
    zzz=4
}

$(f)
echo $zzz

为什么赋值 (zzz=4) 被忽略了?我以为我知道 $( ) 的作用——它将所有写入标准输出的内容逐字粘贴到使用它的地方。但为什么这会影响对全局变量的赋值?

因为$(...)在子shell中运行。子 shell 的更改在父 shell.

中不可见

来自bash manual

Bash performs the expansion by executing command in a subshell environment ...

和子shell创建一个单独的进程,它有一个单独的command execution environment

等于:

( 
   f
)

( .. ) 也创建一个子shell,但不捕获标准输出。

其他答案正确指出 $() 将创建一个子 shell 并且您将拥有独立于父 shell 的执行环境。

zzz=2

function f()
{
   echo zzz=4
}

eval $(f)
echo $zzz

您可以使用 eval 来解决这个问题。首先在函数内打印所需的赋值语句,然后在调用者代码中评估该语句。

注意:请注意,eval 有一些注意事项,应避免使用,除非您确定代码的行为。

你为什么要在子 shell 中调用它?

zzz=2
f() { zzz=4; }
$(f)            # assigns COPY of zzz, then goes POOF
echo $zzz
f               # assigns to zzz
echo $zzz

通过 运行 它在子 shell 中创建一个子环境,该环境获取分配的变量,然后消失。

去掉f.

周围的subshell

假设您真的没有用子 shell,代码应该类似于:

zzz=2

function f()
{
    zzz=4
}

f
echo $zzz

你告诉它函数 f 需要在不同的 shell 中执行,所以它不会改变变量。