实现本地功能

kar*_*fai 14 bash shell sh

我想要实现的是在函数内创建一个本地函数.同时,本地函数不会覆盖外部函数.下面是一个简单函数和带有参数的嵌套函数的示例,用于说明我的问题.

#!/bin/bash
usage() #<------------------------------- same function name
{
    echo "Overall Usage"
}

function_A()
{
    usage() #<--------------------------- same function name
    {
        echo "function_A Usage"
    }

    for i in "$@"; do
        case $i in
            --help)
                usage
                shift
                ;;
            *)
                echo "flag provided but not defined: ${i%%=*}"
                echo "See '$0 --help'."
                exit 0
            ;;
        esac
    done
}

function_A --help
usage
Run Code Online (Sandbox Code Playgroud)

这是输出.

function_A Usage
function_A Usage
Run Code Online (Sandbox Code Playgroud)

但我想要的是

function_A Usage
Overall Usage
Run Code Online (Sandbox Code Playgroud)

是否可以在不改变其(功能)名称和顺序的情况下实现?请?

注意:我尝试了local usage()但似乎不适用于功能.

tha*_*guy 17

Bash不支持本地函数,但根据您的特定脚本和体系结构,您可以通过子shell控制函数名称的范围.

通过在定义中替换{..} with (..),您将获得所需的输出.新定义usage将仅限于函数,但对变量的任何更改都将如此:

#!/bin/bash
usage() 
{
    echo "Overall Usage"
}

function_A()
(                  # <-- Use subshell
    usage()
    {
        echo "function_A Usage"
    }

    for i in "$@"; do
        case $i in
            --help)
                usage
                shift
                ;;
            *)
                echo "flag provided but not defined: ${i%%=*}"
                echo "See '$0 --help'."
                exit 0
            ;;
        esac
    done
)

function_A --help
usage
Run Code Online (Sandbox Code Playgroud)

  • 你可以通过添加一些解释什么是`(..)`(例如man subshel​​l)以及什么时候必须使用它的链接来改进这个答案?谢谢. (4认同)
  • @4wk_ 函数的主体可以是任何[复合命令](https://www.gnu.org/software/bash/manual/html_node/Compound-Commands.html)。这通常是大括号“{...}”[分组命令](https://www.gnu.org/software/bash/manual/html_node/Command-Grouping.html),但也可以是“ (...)` 分组命令也是如此。`{...}` 和 `(...)` 之间的区别在于 `(...)` 在*子 shell* 中运行命令。[此 stackoverflow 答案](/sf/answers/1946145771/) 进一步解释了此语法。 (3认同)

小智 5

man bash

复合命令

复合命令是以下命令之一:

(list) list 在子 shell 环境中执行(请参阅下面的命令执行环境)。影响 shell 环境的变量分配和内置命令在命令完成后不再有效。返回状态是list的退出状态。...

  1. 假设我们有 test.sh:
#!/usr/bin/sh

topFunction1() {
    # start subshell
    (


        innerFunction1() {
            echo "innerFunction1"
        }

        echo "topFunction1 can call $(innerFunction1) from within the subshell"


    )
    # end subshell


    innerFunction2() {
        echo "innerFunction2"
    }
}

topFunction2() {
    echo "topFunction2"
}
Run Code Online (Sandbox Code Playgroud)
  1. 现在让我们开始吧source test.sh

以下命令成功:

topFunction2

以下命令失败:

innerFunction1

innerFunction2

  1. 现在,如果我们这样做,topFunction1我们将得到一个包含输出的innerFunction1输出:

    topFunction1 可以从子shell 内调用innerFunction1

此时以下命令均成功:

topFunction1

topFunction2

innerFunction2

人们可以注意到,现在innerFunction2在调用 后它在全局范围内可见topFunction1。然而,innerFunction1对于子 shell 之外的调用,它仍然是“隐藏的”,这就是您可能想要的。

再次调用innerFunction1将会失败。