test -v 对位置参数有效吗?

Tim*_*Tim 2 bash

来自 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)

谢谢。

ilk*_*chu 6

在 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)

无论如何,变量参数之间存在着一些令人吹毛求疵的差异。

Bash 的参考手册对它们的定义如下:

参数是存储值的实体它可以是name、数字或下面列出的特殊字符之一。变量是由 a 表示的参数name

aname 定义

Aword仅由字母、数字和下划线组成,并且以字母或下划线开头。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。