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