制作一个显示变量名称及其值的函数

制作一个显示变量名称及其值的函数

我想编写一个以变量名作为输入的函数(我们称之为 superEcho)。该函数应该打印该变量的名称及其值

function superEcho
{
     echo "$1: ?????"
}

var=100

superEcho var

我希望这个脚本返回

var: 100

但我不知道我应该用什么来代替“???”在 superEcho 函数中。

答案1

POSIXly:

superEcho() {
  eval 'printf "%s\n" "$1: ${'"$1"'}"'
}

bash-spec一样${!var},它期望$1已被清理并包含有效的变量名称。否则,这相当于任意命令注入漏洞。

您可以在函数中进行清理:

superEcho() {
  case $1 in
    ("" | *[!_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]* | [0123456789]*)
      printf >&2 'Invalid variable name: "%s"\n' "$1"
      return 1;;
    (*) eval 'printf "%s\n" "$1: ${'"$1"'}"'
  esac
}

请注意,对于类型变量大批或者关联数组,在bashksh(POSIXsh没有数组,但"$@"你不能在这里使用,因为这将是函数本身的参数superEcho)只打印索引元素的值0,而在zsh,这将输出价值观的第一个字符$IFS(以及 中的 SPC 字符yash)。

kshzshbashyash(带有数组支持的 4 个类似 Bourne 的 shell)中。另请参阅typeset -p var打印变量的定义和属性。

答案2

使用${!variablename}

function superEcho
{
    printf '%s: %s\n' "$1" "${!1}"
}

答案3

我用另一种方式来做。我经常想对电子邮件、日志或标志(写入磁盘)使用变量名称,以便属于一台设备的所有内容都以相同的方式命名 - 使用变量名称作为基础。

RPiZero=10

ReadRPiTemp ()
{
    eval ReadSegment='$'$1
    echo "variable content: $ReadSegment"
    echo "variable name: $1"
}

ReadRPiTemp RPiZero
# NOT ReadRPiTemp "$RPiZero"

以上将在 sh 和 bash 中工作。由于我在工作中需要与 sh 兼容,因此我忽略了在 Bash 中执行相同操作的正确方法。

RPiZero=10

ReadRPiTemp ()
{
    declare -n ReadSegment=$1
    echo "variable content: $ReadSegment"
    echo "variable name: $1"
}

ReadRPiTemp RPiZero
# NOT ReadRPiTemp "$RPiZero"

上面两者都会打印出相同的结果:

variable content: 10
variable name: RPiZero

相关内容