Bash 函数:有没有办法检查变量是否在本地定义?

Fra*_*ona 6 bash

假设您有一个带有很多选项的函数,并且您决定动态存储它们的值:

#!/bin/bash
fun() {
    local OPTIND __option

    while getopts ":$(printf '%s:' {a..z} {A..Z})" __option
    do
        case $__option in
        [[:alpha:]])
            # ... 
            local "__$__option=$OPTARG"
        esac
    done

    # here you might get a conflict with external variables:
    [[ ${__a:+1} ]] && echo "option a is set"
    [[ ${__b:+1} ]] && echo "option b is set"
    # etc...
    [[ ${__Z:+1} ]] && echo "option Z is set"
}
Run Code Online (Sandbox Code Playgroud)

有没有办法检查变量是否在本地定义?

Léa*_*ris 10

您绝对可以检测到变量是本地变量(如果它已使用 Bash 的declare, local,语句之一typeset声明)。

这是一个例子:

#!/usr/bin/env bash

a=3
b=2

fn() {
  declare a=1
  b=7
  if local -p a >/dev/null 2>&1; then
    printf 'a is local with value %s\n' "$a"
  else
    printf 'a is not local with value %s\n' "$a"
  fi
  if local -p b >/dev/null 2>&1; then
    printf 'b is local with value %s\n' "$b"
  else
    printf 'b is not local with value %s\n' "$b"
  fi
}


fn
Run Code Online (Sandbox Code Playgroud)

输出是:

a is local with value 1
b is not local with value 7
Run Code Online (Sandbox Code Playgroud)

  • 我刚刚测试了 3.2.7 和 4.4 版本,他们再次说 b 是本地的。仅版本 5.1.4/MacOS 表示“b 不是本地值 7”。所以我想说这是 5.1 的一个错误(或“新功能”)。 (4认同)
  • 看起来 `local -p` 是 Bash>5.0。不幸的是 local 也不是 var 属性,因此检查 Bash<=5.0 的唯一方法是在本地声明之前执行此操作,或者解析普通“local”调用的输出。 (2认同)