如何更改bash函数的环境而不影响调用它的环境?

如何更改bash函数的环境而不影响调用它的环境?,bash,function,environment,script,Bash,Function,Environment,Script,我正在编写一个bash脚本,它需要在多个目录上运行。在每个目录中,它需要为该目录生成一个唯一的安装脚本,然后运行一些命令。我需要在该脚本源代码时设置环境,使其仅在函数内部持久化,就像它作为外部脚本被调用一样,对调用脚本没有持久性影响 作为一个简化的示例,如果我有这个脚本,sourceed.sh: export foo=old 我有这个作为我的司机。sh: export foo=young echo $foo source_and_run(){ source ./sourced.sh

我正在编写一个bash脚本,它需要在多个目录上运行。在每个目录中,它需要为该目录生成一个唯一的安装脚本,然后运行一些命令。我需要在该脚本源代码时设置环境,使其仅在函数内部持久化,就像它作为外部脚本被调用一样,对调用脚本没有持久性影响

作为一个简化的示例,如果我有这个脚本,sourceed.sh:

export foo=old
我有这个作为我的司机。sh:

export foo=young
echo $foo
source_and_run(){ 
    source ./sourced.sh 
    echo $foo 
}
source_and_run
echo $foo
我想知道如何更改source_和_run-in驱动程序的调用,以便打印:

young
old
young
我还需要能够从函数中收集返回值。我很确定有一个简单的方法可以实现这一点,但到目前为止我还没有找到它

创建另一个脚本(如external.sh):

source ./sourced.sh; echo $foo
source ./sourced.sh; echo $foo
定义源和运行方式

source_and_run(){ ./external.sh; return $? }
source_and_run(){ ./external.sh; return $? }
可以,但管理额外的脚本层似乎没有必要

创建另一个脚本(如external.sh):

source ./sourced.sh; echo $foo
source ./sourced.sh; echo $foo
定义源和运行方式

source_and_run(){ ./external.sh; return $? }
source_and_run(){ ./external.sh; return $? }
可以,但管理额外的脚本层似乎不必要

您可以通过使用子shell获得相同的行为。注意
()
而不是
{}

但是请注意,
return$?
在您的情况下不是必需的。默认情况下,函数返回其最后一个命令的退出状态。在您的情况下,该命令是
echo
。因此,返回值将始终为
0

source_and_run() (
    source ./sourced.sh
    echo "$foo"
)
顺便说一下:更好的解决方案是重写
sourceed.sh
,这样它就可以打印
$foo
。这样,您就可以直接调用脚本,而不必使用您所说的
echo$foo

创建另一个脚本(如external.sh):

source ./sourced.sh; echo $foo
source ./sourced.sh; echo $foo
定义源和运行方式

source_and_run(){ ./external.sh; return $? }
source_and_run(){ ./external.sh; return $? }
可以,但管理额外的脚本层似乎不必要

您可以通过使用子shell获得相同的行为。注意
()
而不是
{}

但是请注意,
return$?
在您的情况下不是必需的。默认情况下,函数返回其最后一个命令的退出状态。在您的情况下,该命令是
echo
。因此,返回值将始终为
0

source_and_run() (
    source ./sourced.sh
    echo "$foo"
)

顺便说一下:更好的解决方案是重写
sourceed.sh
,这样它就可以打印
$foo
。通过这种方式,您可以直接调用脚本,而不必先获取脚本的源代码,然后再使用
echo$foo

bash函数的真正目的是它与调用程序在同一进程中运行


由于环境是可访问的(例如,使用命令
printenv
),您可以在函数输入时保存环境,并在结束时恢复它。但是,更简单、更自然的方法是完全不使用函数,而是将其作为单独的shell脚本,在其自己的进程中执行,因此具有自己的环境,不再影响调用方的环境。

bash函数的真正目的是它与调用方在同一进程中运行


由于环境是可访问的(例如,使用命令
printenv
),您可以在函数输入时保存环境,并在结束时恢复它。但是,更简单、更自然的方法是完全不使用函数,而是将其作为单独的shell脚本,在自己的进程中执行,因此有自己的环境,它不再影响调用方的环境。

函数末尾的return$?是冗余的。
return$?
函数末尾的是冗余的。在这个简单的示例中,返回值无关紧要,“sourceed”中的活动很小,但我的实际应用程序根据不同的情况有不同的返回代码根据不同操作的结果,“真实”源代码脚本非常复杂,需要将其分开。但是次壳是正确的答案,谢谢!返回值无关紧要,“源代码”中的活动在这个简单的示例中并不重要,但我的实际应用程序根据不同操作的结果具有不同的返回代码,“真实”源代码脚本非常复杂,需要将其分开。但是次壳是正确的答案,谢谢!