Bash函数:输出变量名及其值
不写成如下:
echo "variable: $variable"
在调试时,我想把这一切都用一个函数来完成,比如说:
print "$variable"
到目前为止,我已经让它工作到这一步:
t=https://www.google.com
echo "$(echo ${!t@} | awk '{print $1}'): $t"
问题在于函数接收的是值,而不是变量名。
这可能吗?我是否忽略了避免重复的另一种方式?
我已经阅读了:
不能工作的尝试(进入函数后,函数名就会消失):
function print { t=$1; echo "$(echo ${!t@} | awk '{print $1}'): $t"; }
var=https://www.google.com
print "$var"
解决方案
bash 有一种语法可以实现这个。
$: showme() { for v in "$@"; do echo "$v: ${!v}"; done; }
$: a=1; b=2; c=3;
$ showme a b c
a: 1
b: 2
c: 3
$: printf '%s\n' a b c | while read -r x; do showme $x; done
a: 1
b: 2
c: 3
不过你需要传入变量的 名称,让它自己去查找值。
这当然是一个简化的例子,正如 [pjh] 在其 [commented] 中正确指出的那样,如果所请求的变量名是 v,就会失败。
你可以通过编号参数来修复大部分问题。
showme() { while(($#)); do echo "$1: ${!1}"; shift; done; }
这也会带来一些怪异的副作用 -
$: showme foo b 1 \#
foo:
b: 2
1: 1
#: 1
你也可以使用一个不那么无害的变量,并对它进行显式检查。虽然这样做可以正常工作,但也有它自己的怪癖副作用。
$: declare -f showme
showme ()
{
local -I __showme_temp;
if [[ -n "$__showme_temp" ]]; then
echo "__showme_temp is already used." 1>&2;
return 1;
fi;
for __showme_temp in "$@";
do
echo "$__showme_temp: ${!__showme_temp}";
done
}
$: showme foo b 1 \#
foo:
b: 2
1: foo
#: 4
在我本地的git bash上,如果传入的变量名与nameref相同,nameref方案确实能正确报告,但要经过若干关于循环引用的错误信息后才行。
如果把上述对一组有意设置为隐藏的局部变量进行的预检查结合起来,它就会达到我认为的更“标准”的行为——在愚蠢的输入下它会抛出错误,然后 continue 让它不会打印出无意义的内容。
$: declare -f showme
showme ()
{
local -I __showme_temp1 __showme_temp2;
if [[ -n "$__showme_temp1" ]]; then
echo "__showme_temp1 is already used." 1>&2;
return 1;
fi;
if [[ -n "$__showme_temp2" ]]; then
echo "__showme_temp2 is already used." 1>&2;
return 1;
fi;
for __showme_temp1 in "$@";
do
local -n __showme_temp2="$__showme_temp1" || continue;
echo "$__showme_temp1: ${__showme_temp2}";
done
}
$: showme foo b 1 \#
foo:
b: 2
bash: local: `1': invalid variable name for name reference
bash: local: `#': invalid variable name for name reference
不过这对我来说有点儿临时拼凑的感觉。
正如 [Léa Gris] 在她的 [回答] 中所说,declare 确实是最好的选择。如果它对你的日志来说太嘈杂,你可能就想太多了。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。