如何在不影响调用它的环境的情况下更改 bash 函数的环境?
How can I change the environment of my bash function without affecting the environment it was called from?
我正在编写一个 bash 脚本,该脚本需要对多个目录进行操作。在每个目录中,它需要为该目录提供一个唯一的安装脚本,然后 运行 一些命令。我需要在获取该脚本时设置环境以仅在函数内部持久存在,就好像它已作为外部脚本被调用,对调用脚本没有持久影响。
作为一个简化的例子,如果我有这个脚本,sourced.sh:
export foo=old
我把这个作为我的 driver.sh:
export foo=young
echo $foo
source_and_run(){
source ./sourced.sh
echo $foo
}
source_and_run
echo $foo
我想知道如何在驱动程序中更改 source_and_run 的调用以便打印:
young
old
young
我还需要能够从函数中收集 return 值。我很确定有一种简单的方法可以实现这一点,但到目前为止我还没有找到它。
正在创建另一个脚本 external.sh:
source ./sourced.sh; echo $foo
并定义 source_and_run 如
source_and_run(){ ./external.sh; return $? }
会起作用,但似乎没有必要管理额外的脚本层。
你说
Creating another script like external.sh:
source ./sourced.sh; echo $foo
and defining source_and_run like
source_and_run(){ ./external.sh; return $? }
would work but managing that extra layer of scripts seems like it shouldn't be necessary.
您可以通过使用子 shell 获得相同的行为。注意 ()
而不是 {}
.
但请注意,return $?
在您的情况下不是必需的。默认情况下,函数 returns 是其最后一个命令的退出状态。在您的例子中,该命令是 echo
。因此,return 值将始终为 0
。
source_and_run() (
source ./sourced.sh
echo "$foo"
)
顺便说一句:更好的解决方案是重写 sourced.sh
,使其打印 $foo
。这样您就可以直接调用脚本,而不必获取它然后使用 echo $foo
.
bash函数的真正目的是它与调用程序在同一进程中运行。
由于环境是可访问的(例如,使用命令printenv
),您可以在函数的入口处保存环境并在最后恢复它。然而,更简单和更自然的方法是根本不使用函数,而是将其作为一个单独的 shell 脚本,在自己的进程中执行,因此有自己的环境,这不会影响不再来电了。
我正在编写一个 bash 脚本,该脚本需要对多个目录进行操作。在每个目录中,它需要为该目录提供一个唯一的安装脚本,然后 运行 一些命令。我需要在获取该脚本时设置环境以仅在函数内部持久存在,就好像它已作为外部脚本被调用,对调用脚本没有持久影响。
作为一个简化的例子,如果我有这个脚本,sourced.sh:
export foo=old
我把这个作为我的 driver.sh:
export foo=young
echo $foo
source_and_run(){
source ./sourced.sh
echo $foo
}
source_and_run
echo $foo
我想知道如何在驱动程序中更改 source_and_run 的调用以便打印:
young
old
young
我还需要能够从函数中收集 return 值。我很确定有一种简单的方法可以实现这一点,但到目前为止我还没有找到它。
正在创建另一个脚本 external.sh:
source ./sourced.sh; echo $foo
并定义 source_and_run 如
source_and_run(){ ./external.sh; return $? }
会起作用,但似乎没有必要管理额外的脚本层。
你说
Creating another script like external.sh:
source ./sourced.sh; echo $foo
and defining source_and_run like
source_and_run(){ ./external.sh; return $? }
would work but managing that extra layer of scripts seems like it shouldn't be necessary.
您可以通过使用子 shell 获得相同的行为。注意 ()
而不是 {}
.
但请注意,return $?
在您的情况下不是必需的。默认情况下,函数 returns 是其最后一个命令的退出状态。在您的例子中,该命令是 echo
。因此,return 值将始终为 0
。
source_and_run() (
source ./sourced.sh
echo "$foo"
)
顺便说一句:更好的解决方案是重写 sourced.sh
,使其打印 $foo
。这样您就可以直接调用脚本,而不必获取它然后使用 echo $foo
.
bash函数的真正目的是它与调用程序在同一进程中运行。
由于环境是可访问的(例如,使用命令printenv
),您可以在函数的入口处保存环境并在最后恢复它。然而,更简单和更自然的方法是根本不使用函数,而是将其作为一个单独的 shell 脚本,在自己的进程中执行,因此有自己的环境,这不会影响不再来电了。