Skip to main content
2 of 5
added 151 characters in body
Sergiy Kolodyazhnyy
  • 16.9k
  • 12
  • 58
  • 111

No, they're not environment variables, they're called positional parameters and there's reason for the difference: there's environment in which command can operate (i.e. certain conditions and restrictions) and that should be available to all programs; then there's what user must provide. That's why they're not on the set list - $1 and $2 are specific to each instance of non-interactive shell you run ( notice the "non-interactive" part, which means you can use $1 in shell scripts and sh -c 'command 1; command 2 type of things ). Of course there are ways to set them other wise, as well as change the list of those parameters via shift command, but the environment and positional variables as I've explained already have somewhat different purpose.

Take for instance C programming language. The main function typically looks like

int main(int argc, char **argv)

, where argc is number of command-line arguments and argv is effectively array of command-line parameters, and then there's environ function ( on Linux that's man -e 7 environ ) to access things like user's home directory path, list of directories in PATH where we can look for executables, etc. Shell scripts are also modeled in the similar way. In shell terminology, we have positional parameters $1, $2 and so forth, while $# is number of positional parameters. What about $0 ? That's the name of the executable itself, which is again also modeled from C programming language - argv[0] would be name of your C "executable". And this is fairly true for most programming and scripting languages.

In conclusion, purpose of these two is different, and they exist for a reason.

Answer is under construction and will be edited, please be patient:)

Sergiy Kolodyazhnyy
  • 16.9k
  • 12
  • 58
  • 111