我想编写一个以变量名作为输入的函数(我们称之为 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
}
请注意,对于类型变量大批或者关联数组,在bash
或ksh
(POSIXsh
没有数组,但"$@"
你不能在这里使用,因为这将是函数本身的参数superEcho
)只打印索引元素的值0
,而在zsh
,这将输出价值观的第一个字符$IFS
(以及 中的 SPC 字符yash
)。
在ksh
、zsh
、bash
或yash
(带有数组支持的 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