As I sometimes do, I was searching for something that I always used but didn't know what it really did.
This time is the turn of bash Special Parameters. If you are able to use this in a good way it's like you have the power of the universe in your hand!!!!
Before giving you a simple list with examples, I need to specify another argument. Do you know what Positional Parameters are?
Positional Parameters
For the ones (like me) that want just a glance to understand what I'm talking about, here's what positional parameters are:
$1, $2, $3 etc..
Understood?
Well, from bash(1) man (bash(1) man), the definition is:
A positional parameter is a parameter denoted by one or more digits, other than the single digit 0. Positional parameters are assigned from the shell's arguments when it is invoked, and may be reassigned using the set builtin command. Positional parameters may not be assigned to with assignment statements. The positional parameters are temporarily replaced when a shell function is executed (see FUNCTIONS below).
When a positional parameter consisting of more than a single digit is expanded, it must be enclosed in braces (see EXPANSION below).
In other words, when you call a command in bash and you put some text after the command itself, the program retrieves this text using $1, $2 etc, starting from one
The following will be the command for all the subsequent examples:
rjdio@rockserver:/home/rjdio# ./test.sh metal heavy
A very simple example code for this example:
#!/bin/bash
echo $2
echo $1
heavy is $2, metal is $1, so output is:
heavy
metal
I think I made it clear enough ;
Special Parameters
These listed below are instead special parameters. Each one has a special function, and for this reason you cannot assign a new value to them.
- * : this parameters contains all the positional parameters separated with the IFS (a special variable, containing a default separator - see Internal Field Separator Wiki). If in my environment IFS=';'
#!/bin/bash
echo "$*"
Output:
metal heavy
- @ : contains the array 1-based of all the positional parameters passed. In this example I use a simple for loop within an array created :
#!/bin/bash
for music in "$@"; do
echo "great $music"
done
Output:
great metal great heavy
- # : returns the number of positional parameters:
#!/bin/bash
echo "$#"
Output:
2
- ? : returns the exit code of the most recent program. Actually, returns the exit code of the last executed foreground pipeline. If the last program is in background, echo "$?" won't return its exit code, but the one of a previously foreground executed program.
#!/bin/bash
mkdir /home/rjdio/metal
if [ $? -eq 0 ]; then
echo "/home/rjdio/metal created"
Output (suppose it all went well, the exit code in case the directory is successfully created is 0):
/home/rjdio/metal created
- - : returns the entire set of the options specified at the launching of the shell (at startup or manually)
echo "$-"
Output (in most of my environments):
himBH
To find out the meaning of those command line options, simply type help set. In this case, these options mostly enables bash history.
- $ : returns the process id of the actual shell. Remember, if you are in a subshell, it returns the ID of the shell, not of the subshell.
echo "$$"
Output (it's an ID, it's different from machine to machine - or between users even)
73471
- ! : returns the process ID of the most recent background executed command; if no process was executed in background returns an empty string:
echo "$!"
Output (it's an ID, remember)
12345
- 0 : returns the name of the shell/shell-script currently executing in foreground. This parameter is set at shell initialization or when launching the program. Remember when I said that Positional Parameters starts from $1 ? Well, it's not true, because $0 it's the program name!
#!/bin/bash
echo "$2 $1 $0"
Output (remember, I'm launching this command line: ./test.sh metal heavy)
heavy metal ./test.sh
- _ : this parameter sets to the last argument of the previous command. In case I'm just after startup, it contains the absolute path of the actual shell. Why? Well, remember the point above: $0, the program path, is a positional parameter, so in some way, for our shell it's an argument!
echo "$_$"
Output (if the last command I executed it's ./test.sh metal heavy)
heavy
Conclusions
Well, in this post I briefly described with examples all of the positional parameters. They are powerful and useful functions, that it's possible to use in your code in many ways (eg. when parsing command line parameters).
Another tip: in my opinion, to better understand how these option works, you should think of bash as a program. If it's a program, it can be launched and can have parameters, for example.
References
- Man(1) Bash - simply the man page of BASH
- Stackoverflow Special Parameters question - brief but complete list of all positional parameters and their functions.Labels: bash