What Values can the Zeroth Argument Have? (in the Command-Line)

Share

Some shell scripts have used to zeroth argument to derive the filepath of the script file itself, which doesn't seem to be a good idea because the zeroth argument can be anything. I don't know what the alternative is in Bash, but I'd recommend just using Python instead.

Absolute Filepath

For example, let's say you have a program called /usr/bin/date. If you do this from the terminal:

/usr/bin/date

Then the zeroth argument that the program gets is /usr/bin/date.

Program Name

However, because this program is in /usr/bin, you can just do this:

date

And in this case, the zeroth argument that the date program gets in its argv variable will be just date. That is, from the perspective inside the date program, the zeroth argument they get from the shell may be either /usr/bin/date or date.

Path Relative to Current Working Directory

Additionally, if you have a script in your current working directory and you do this:

./script.sh

The zeroth argument will be ./script.sh.

The Filename of the Script

However, if you do this:

bash script.sh

The zeroth argument will be script.sh.

Literally "bash"

And if you do this:

bash < script.sh

The zeroth argument will be bash!

Literally ANYTHING

It's also possible to arbitrarily set the zeroth argument in some cases, e.g. in Bash, exec -l just places a dash (-) in it, and exec -a lets you pick whatever you want.

Options:
    -a name	pass NAME as the zeroth argument to COMMAND
    -l		place a dash in the zeroth argument to COMMAND
exec --help of Bash, version 5.2.21(1)-release, Linux Mint

Avoid Relying on the Zeroth Argument If You Can

There was an example of a shell script deleting all user files due to these peculiarities exactly.

Essentially, what has happened was that they wrote rm -rf "${0%/*}/*" to delete all files in the directory where a program was installed. If $0 was /folder/program, then "${0%/*}" would evaluate to /folder. However, if $0 was just program, then "${0%/*}" would be an empty string "" , which means rm -rf "${0%/*}/*" evaluates to rm -rf /* and that deletes all your files.

Written by Noel Santos.

About the Author

I'm a self-taught Brazilian programmer graduated in IT from a FATEC. In a world of increasingly complex and essential computers, I decided to use my technical expertise in hardware, desktop applications, and web technologies to create an informative resource to make PC's easier to understand.

View Comments