来自 bash 手册
-v varname
如果设置了 shell 变量 varname(已分配值),则为 True。
我测试位置参数是否在 bash 脚本中1
设置-v 1
,但当我提供命令行参数时,它不会让测试通过。我想知道为什么?
#! /bin/bash
if [ -v 1 ]; then
echo "1 exists"
fi
谢谢。
答案1
在 Bash 中,它从 Bash 5.1 开始就可以工作,但在早期版本中它只是默默地失败。 (它也适用于 zsh。)
$ ./bash-5.1/bash -c 'set -- aa bb; for i in 1 2 3;
do [ -v $i ] && echo y || echo n; done'
y
y
n
源代码中的 CHANGES 文件提到了 5.1-alpha 的这一更改:
3. New Features in Bash
...
x. `test -v N' can now test whether or not positional parameter N is set.
无论如何,两者之间存在着一些令人毛骨悚然的差异变量和参数。
Bash 的参考手册定义了它们像这样:
A范围是一个存储值的实体。它可以是
name
、数字或下面列出的特殊字符之一。 A多变的是由 a 表示的参数name
。
还有一个name
被定义为作为
A
word
仅由字母、数字和下划线组成,并且以字母或下划线开头。Names
用作 shell 变量和函数名称。也称为identifier
.
所以所有变量都是参数,但并非所有参数都是变量。并返回test -vvarname
如果 shell 变量为 True变量名已设置
因此,从技术上讲,它甚至没有记录到除了实数变量之外的任何东西。即使它现在也适用于位置参数,文档似乎仍然只提到变量。
在任何情况下,我们都可以使用“替代值”参数扩展${1+x}
并测试空字符串$1
和任何其他范围(包括任何变量.)如果设置了参数(即使已设置但为空),则${par+value}
扩展为给定字符串,否则扩展为空字符串。value
$ bash -c 'set -- aa bb; [ ${1+x} ] && echo y || echo n'
y
这应该适用于所有版本的 Bash 以及任何标准 shell。