请禁用了javascript更改本地运作(Make shopt change local to fu

2019-06-27 12:40发布

我试着写一个使用bash函数nocasematch不改变选项的呼叫者设置。 该函数的定义是:

is_hello_world() {
  shopt -s nocasematch
  [[ "$1" =~ "hello world" ]] 
}

之前,我把它叫做:

$ shopt nocasematch
nocasematch     off

叫它:

$ is_hello_world 'hello world' && echo Yes
Yes
$ is_hello_world 'Hello World' && echo Yes
Yes

正如预期的那样,但现在nocasematch呼叫者的改变:

$ shopt nocasematch
nocasematch     on

有没有简单的方法,使选项更改本地的功能?

我知道我可以检查返回值, shopt -q但仍然表示该功能应该记住这一点,并在退出之前重置。

Answer 1:

函数体可以是任何化合物命令,不只是一组指令( {} 使用一个子shell:

is_hello_world() (
  shopt -s nocasematch
  [[ "$1" =~ "hello world" ]] 
)


Answer 2:

我知道,从2012年这个职位日期,但你也可以做以下(Git中的Bash 1.8.4在Windows上运行,所以它应该工作在Linux上):

function foobar() {
    local old=$(shopt -p extglob)
    shopt -s extglob

    ... your stuff here ...
    eval "$old"
}

-p选项,只打印shopt -s extglob如果extglob是对的,否则shopt -u extglob

shopt -p打印选项的完整列表。



Answer 3:

使用RETURN陷阱

一个壳函数之后才执行恢复...返回与RETURN陷阱指定命令被执行...

-p选项[到禁用了javascript]导致可重用为输入的形式显示输出。

- https://www.gnu.org/software/bash/manual/bash.html

foobar() {
    trap "$(shopt -p extglob)" RETURN
    shopt -s extglob

    # ... your stuff here ...

}

对于测试

foobar() {
    trap "$(shopt -p extglob)" RETURN
    shopt -s extglob

    echo "inside foobar"
    shopt extglob # Display current setting for errexit option
}

main() {
    echo "inside main"
    shopt extglob # Display current setting for errexit option
    foobar
    echo "back inside main"
    shopt extglob # Display current setting for errexit option
}

测试

$ main
inside main
extglob         off
inside foobar
extglob         on
back inside main
extglob         off

变化:要重置所有禁用了javascript选项,改变陷阱声明:

trap "$(shopt -p)" RETURN

变化:要重置所有设置选项,修改陷阱声明:

trap "$(set +o)" RETURN

注意:使用bash 4.4开始,有一个更好的办法: 让$ -地方 。

变化:要重置所有设置所有禁用了javascript选项,改变陷阱声明:

trap "$(set +o)$(shopt -p)" RETURN

注意: set +o相当于shopt -p -o

+ O写当前选项设置到标准输出的格式,其适用于再输入到所述壳为达到相同的选项的设置的命令。

- 公开组基本规范第7期2018版>集



文章来源: Make shopt change local to function
标签: bash shopt