From the bash manual

-v varname

True if the shell variable varname is set (has been assigned a value).

I test if positional parameter 1 is set by -v 1 in a bash script, but it doesn't let the test pass when I provide a command line argument. I wonder why?

#! /bin/bash

if [ -v 1 ]; then
    echo "1 exists"



You're right, it doesn't seem to work:

$ bash -c 'set -- aa bb; [ -v 1 ] && echo y || echo n'

It might a bit of a hair-splitting difference between variables and parameters.

Bash's reference manual defines them like this:

A parameter is an entity that stores values. It can be a name, a number, or one of the special characters listed below. A variable is a parameter denoted by a name.

And a name is defined as

A word consisting solely of letters, numbers, and underscores, and beginning with a letter or underscore. Names are used as shell variable and function names. Also referred to as an identifier.

So all variables are parameters, but not all parameters are variables. And test -vvarname returns

True if the shell variable varname is set

1 isn't a name, and $1 isn't a variable, so test -v doesn't work for it. But we can use parameter expansion and [ ${1+x} ] or such for $1 and any other parameter (including any variables.)

$ bash -c 'set -- aa bb; [ ${1+x} ] && echo y || echo n'
  • Thanks. Does [ $x ] test fail to pass when either the parameter is not set or its value is ""?
    – Tim
    Jan 27 '18 at 17:07
  • 1
    @Tim, [ ${param+x} ] tests for a set parameter, [ ${param:+x} ] tests for a set parameter with a nonempty value (but that's not nearly as useful, since you could just use [ -n "$param" ] in that case). Bash's manual mentions that a bit in passing, but the standard has a nice table of all those.
    – ilkkachu
    Jan 27 '18 at 17:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.