【问题标题】:Why is the assignment in a function ignored?为什么忽略函数中的赋值?
【发布时间】:2019-10-14 04:21:42
【问题描述】:

考虑以下代码:

zzz=2

function f()
{
    zzz=4
}

$(f)
echo $zzz

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

【问题讨论】:

  • f 向标准输出写入任何内容;命令替换在这里没有用。

标签: bash function scope variable-assignment


【解决方案1】:

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

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

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

【讨论】:

  • 另外,$(f) 尝试将f 的输出作为命令运行,但没有。
【解决方案2】:

因为$(...) 在子shell 中运行。来自子 shell 的更改在父 shell 中不可见。

来自bash manual

Bash 通过在 subshel​​l 环境中执行命令来执行扩展 ...

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

同理:

( 
   f
)

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

【讨论】:

  • 除了打印到stdout之外,还有什么方法可以将$( )内部的一些信息传递给外界(不使用文件)?
  • 我认为不,不是真的。您可以打印到以前打开的文件描述符,但这实际上是一个文件,即使打开以处理替换也是如此。只需使用一个临时文件,这就是 bash 的工作原理。
【解决方案3】:

正确指出其他答案$() 将创建一个子shell,您将拥有与父shell 分开的执行环境。

zzz=2

function f()
{
   echo zzz=4
}

eval $(f)
echo $zzz

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

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

【讨论】:

  • 你为什么要在一个从一开始就不需要命令替换的情况下增加 更多 开销?
  • 这是在需要命令替换时作为一般答案添加的。正如 OP 在这里使用的那样。
  • 我认为 OP 不知道他们为什么要使用命令替换。没有任何迹象表明它是必需的。
  • 同意先生,正如我所说,这与这种情况无关,但一般情况下需要“何时”命令替换。我已经添加了一条说明不是首选解决方案的说明。
  • 老实说,有时从 SO 那里获得帮助比自己解决问题更难。要在这里提出问题,必须提供一个最小的可行示例,因为太多不必要的代码会使其他人更难理解问题的要点......但是因为这里的许多人 总是假设 OP 不知道什么他们这样做 有时最好放一些不必要的代码,否则会被指责询问其他问题。 @PS。谢谢你不是所说的人之一。 chepner,命令替换是我的问题的要点,但示例不需要使用它。
【解决方案4】:

移除 f 周围的子shell。

假设你真的没有使用 subshel​​l,代码应该如下所示:

zzz=2

function f()
{
    zzz=4
}

f
echo $zzz

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

【讨论】:

  • $( ) 是我的问题的要点 - 没有它,分配是微不足道的,工作没有问题。但是,我提供的示例并不需要实际使用$( ) 的结果来展示具体问题。
猜你喜欢
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 2013-10-16
  • 2015-08-18
相关资源
最近更新 更多