如何使用`local -`将shell选项限制为函数?

Ins*_*are 6 bash

BASH 手册页local

local [option] [name[=value] ... | - ]
    […] If name is ‘-’, the set of shell options is made local to the 
    function in which local is invoked: shell options changed using the
    set builtin inside the function are restored to their original
    values when the function returns.
Run Code Online (Sandbox Code Playgroud)

因此,根据这些信息,使用local -,我应该能够set -x在函数内部使用来启用跟踪输出。当函数结束时,跟踪输出将被禁用。

#!/bin/bash
foo() {
  local -
  set -x
  ... # this code is shown in trace output
}

# trace output is disabled
foo
# trace output should be disabled here
Run Code Online (Sandbox Code Playgroud)

这不起作用。运行脚本时,我收到错误消息

line 3: local: '-': not a valid identifier

在 foo 函数返回后,仍为脚本的其余部分启用跟踪输出。

我已经在 OSX 和 Ubuntu 上的 BASH 4.4 和 SLES 上的 BASH 3.2 下尝试过这个。

Tra*_*rke 5

根据 Bash 发布日志,这是Bash 4.4 的local -一个新功能。我怀疑您的计算机上可能安装了 Bash 4.4,但尚未将其设置为登录shell 和/或它不位于/bin/bash您在 shebang 中指定的路径。

您可以通过以下方式验证这一点:

$ echo "$BASH_VERSION" 

4.4.12(1)-release
Run Code Online (Sandbox Code Playgroud)

根据 Bash 4.4 的安装位置,您可以通过以下方式升级和使用此功能:

##########################################
# OSX: Bash 4.4 installed via HomeBrew
##########################################

# Add the new shell to the list of allowed shells
echo /usr/local/bin/bash | sudo tee -a /etc/shells

# Change to the new shell
chsh -s /usr/local/bin/bash  
Run Code Online (Sandbox Code Playgroud)

您还需要使用正确的 shebang 路径。好消息是,如果您已经将 Bash 4.4 设置为登录shell(见上文),那么您可以简单地使用:

#!/usr/bin/env bash
Run Code Online (Sandbox Code Playgroud)

如果您发现尚未安装 Bash 4.4,这里有一个在 OSX 上升级到 Bash 4.4 的简单指南。

即使是新的 2017 MacBook Pro 型号也配备了旧的 Bash 3.2。除非您手动升级了用户 bash 登录 shell,否则您不会拥有 Bash 4.4,也不会拥有该local -功能。