gpt4 book ai didi

bash - 如果函数位于子 shell 内,其行为会如何变化?

转载 作者:行者123 更新时间:2023-12-02 18:10:23 25 4
gpt4 key购买 nike

当在 bash 脚本中创建函数时,人们似乎经常让该函数在子 shell 中运行,即

function(){(

)}

而不是

function(){

}

使用 {()} 而不仅仅是 {} 有何优点/缺点(如果有)?

最佳答案

括号使函数在子 shell 中运行,子 shell 是与父 shell 隔离的子进程。当您想要进行进程范围的环境更改而不影响函数外部代码的行为时,它们非常有用。

示例包括:

  • 使用 cd 更改当前目录不会影响父 shell。在子 shell 中运行 cdpushdpopd 的更简洁的替代方案。

  • 变量赋值与子 shell 隔离。您可以临时更改 $PATH$IFS 等全局设置,而无需在前后仔细保存和恢复它们的值。

  • 使用 setshopt更改的
  • Shell选项将在子shell退出时自动恢复。例如,我通常编写 (set -x; some-commands) 来临时启用命令日志记录。

  • trap一起安装的
  • 信号处理程序仅在子shell中有效。您可以在函数运行期间安装自定义 INT (Ctrl-C) 处理程序,或者安装自定义 EXIT 处理程序以在以下情况下运行清理代码:函数返回。

    func() {(
    echo 'entering func' >&2
    trap 'echo exiting func >&2' EXIT

    ...
    )}
  • 如果调用exit,它不会导致整个脚本退出。如果您想从调用堆栈中的多个函数中调用 exit 作为一种穷人的“异常”,这非常有用。

    或者,如果您想获取可能退出的脚本,将其包装在子 shell 中将防止它杀死您的脚本。

    (
    . ./script-that-might-exit
    echo "script set \$foo to $foo"
    echo "script changed dir to $PWD"
    )


有趣的事实:函数不必用花括号分隔。省略大括号并使用圆括号作为分隔符是合法的:

func() (
# runs in a subshell
)

关于bash - 如果函数位于子 shell 内,其行为会如何变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72463757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com