mirror of
https://github.com/ellysh/bash-programming-from-scratch.git
synced 2026-01-26 07:43:42 +00:00
Review the "Variables and Parameters" section
This commit is contained in:
@ -329,28 +329,28 @@ The internal variables are divided into three groups depending on the allowed ac
|
||||
|
||||
Bash declares special parameters and assigns values to them. It handles them the same way as shell variables.
|
||||
|
||||
Special parameters pass information from a shell to a launching application and vice versa. We have already considered positional parameters. All of them are special parameters.
|
||||
Special parameters pass information from the shell to the launched application and vice versa. A positional parameter is an example of this kind of Bash variable.
|
||||
|
||||
Table 3-6 shows frequently used special parameters.
|
||||
|
||||
{caption: "Table 3-6. Bash Special Parameters", width: "100%"}
|
||||
| Name | Value |
|
||||
| --- | --- |
|
||||
| `$*` | It contains all positional parameters passed to the script. Parameters start with the `$1` variable but not with `$0`. If you skip double-quotes (`$*`), Bash inserts each positional parameter as a separate word. With double-quotes ("$*"), Bash handles it as a single quoted string. The string contains all the parameters separated by the first character of the internal variable `IFS`. |
|
||||
| `$*` | It contains all positional parameters passed to the script. Parameters start with the `$1` variable but not with `$0`. If you skip the double quotes (`$*`), Bash inserts each positional parameter as a separate word. With double quotes ("$*"), Bash handles it as a single-quoted string. The string contains all the parameters separated by the first character of the internal variable `IFS`. |
|
||||
| | |
|
||||
| `$@` | The array that contains all positional parameters passed to the script. Parameters start with the `$1` variable. If you skip double-quotes (`$@`), Bash handles each array's element as an unquoted string. Word splitting happens in this case. With double-quotes ("$@"), Bash handles each element as a quoted string without word splitting. |
|
||||
| `$@` | The array that contains all positional parameters passed to the script. Parameters start with the `$1` variable. If you skip double quotes (`$@`), Bash handles each array's element as an unquoted string. Word splitting happens in this case. With double quotes ("$@"), Bash handles each element as a quoted string without word splitting. |
|
||||
| | |
|
||||
| `$#` | The number of positional parameters passed to the script. |
|
||||
| | |
|
||||
| `$1`, `$2`... | It contains the value of the corresponding positional parameter. `$1` matches the first parameter. `$2` matches the second one, etc. The numbers are given in the decimal system. |
|
||||
| `$1`, `$2`... | They contain the value of the corresponding positional parameter. `$1` matches the first parameter. `$2` matches the second one, etc. These numbers are given in the decimal system. |
|
||||
| | |
|
||||
| `$?` | The exit status of the last executed command in the foreground mode. If a pipeline was executed, the parameter stores the exit status of the last command in the pipeline. |
|
||||
| `$?` | The exit status of the last executed command in the foreground mode. If you have executed a pipeline, the parameter stores the exit status of the last command in this pipeline. |
|
||||
| | |
|
||||
| `$-` | It contains options for the current interpreter instance. |
|
||||
| | |
|
||||
| `$$` | The process ID of the current interpreter instance. If you use it in the subshell, Bash inserts the PID of the parent process. |
|
||||
| `$$` | The process ID of the current interpreter instance. If you read it in the subshell, Bash returns the PID of the parent process. |
|
||||
| | |
|
||||
| `$!` | The process ID of the last command that was launched in the background mode. |
|
||||
| `$!` | The process ID of the last command launched in the background mode. |
|
||||
| | |
|
||||
| `$0` | The name of the shell or script that is currently running. |
|
||||
| | |
|
||||
@ -361,43 +361,43 @@ You cannot change special Bash parameters directly. For example, the following r
|
||||
1="new value"
|
||||
```
|
||||
|
||||
If you want to redeclare positional parameters, use the `set` command. It redeclares all parameters at once. There is no option to change a single parameter only. Here is the form of the `set` call:
|
||||
If you want to change positional parameters, use the `set` command. It redeclares all parameters at once. There is no option to change a single positional parameter only. Here is the general form of the `set` call:
|
||||
{line-numbers: false, format: Bash}
|
||||
```
|
||||
set -- NEW_VALUE_OF_$1 NEW_VALUE_OF_$2 NEW_VALUE_OF_$3...
|
||||
```
|
||||
|
||||
What to do if you need to change a single positional parameter? Suppose you call the script with four parameters. For example, like this:
|
||||
What to do if you need to change a single positional parameter? Here is an example. Suppose you call the script with four parameters like this:
|
||||
{line-numbers: false, format: Bash}
|
||||
```
|
||||
./my_script.sh arg1 arg2 arg3 arg4
|
||||
```
|
||||
|
||||
You want to replace the third parameter `arg3` with the `new_arg3` value. Here is the `set` call for that:
|
||||
You want to replace the third parameter `arg3` with the `new_arg3` value. The following `set` call does that:
|
||||
{line-numbers: false, format: Bash}
|
||||
```
|
||||
set -- "${@:1:2}" "new_arg3" "${@:4}"
|
||||
```
|
||||
|
||||
Let's consider this call in detail. Bash replaces the first argument "${@:1:2}" by the first two elements of the `$@` array. It leads that `$1` and `$2` parameters get their previous values. Then there is the new value for the parameter `$3`. Now it equals "new_arg3". Then there is the "${@:4}" value. Here Bash inserts all elements of the `$@` array starting from `$4`. It means that all these parameters get their previous values.
|
||||
Let's consider this command in detail. Bash replaces the first argument "${@:1:2}" with the first two elements of the `$@` array. It leads that `$1` and `$2` parameters get their previous values. Then there is the new value for the parameter `$3`. Now it equals "new_arg3". The "${@:4}" value comes at the end. Here Bash inserts all elements of the `$@` array starting from `$4`. It means that all these parameters get their previous values.
|
||||
|
||||
All special parameters from Table 3-6 are available in the POSIX-compatible mode.
|
||||
All special parameters from Table 3-6 are available in the POSIX-compatible mode of Bash.
|
||||
|
||||
### Scope
|
||||
|
||||
#### Environment Variables
|
||||
|
||||
Variables are divided into **scopes** (scope) in any software system. A scope is a part of a program or system where the variable name remains associated with its value. In other words, you can convert the variable name into its address in the scope of that variable only. Outside the scope, the same name can point to another variable.
|
||||
Any software system has **scopes** those group variables. A scope is a part of a program or system where the variable name remains associated with its value. There you can convert the variable name into its address. Outside the scope, the same name can point to another variable.
|
||||
|
||||
A scope is called **global** if it spreads to the whole system. For example, the variable called `filename` is in the global scope. Then you can access it by its name from any part of the system.
|
||||
A scope is called **global** if it spreads to the whole system. Here is an example. Suppose that the variable called `filename` is in the global scope. Then you can access it by its name from any part of the system.
|
||||
|
||||
Bash keeps all its internal variables in the global scope. They are called **environment variables**. It means that all internal variables are environment variables. The user can declare his variable in the global scope too. Then it becomes an environment variable.
|
||||
Bash keeps all its internal variables in the global scope. They are called **environment variables**. It means that all internal variables are environment variables. You can declare your variable in the global scope too. Then it becomes a new environment variable.
|
||||
|
||||
Why does Bash store variables in the global scope? It happens because Unix has a special set of settings. They affect the behavior of the applications the user runs. An example is locale settings. According to them, each running application adapts its interface. Applications share such kinds of settings through environment variables.
|
||||
Why does Bash store variables in the global scope? It happens because Unix has a special set of settings. They affect the behavior of the applications that you run. An example is locale settings. They dictate how each application should adapt its interface. Applications receive Unix settings through environment variables.
|
||||
|
||||
Suppose one process spawns a child process. The child process inherits all environment variables of the parent. Thus, all utilities and applications launched from the shell inherit its environment variables. This way, global Unix settings are spread to all user programs.
|
||||
Suppose one process spawns a child process. The child process inherits all environment variables of the parent. This way, all utilities and applications launched from the shell inherit its environment variables. This mechanism allows all programs to receive global Unix settings.
|
||||
|
||||
The child process can change its environment variables. Then it spawns another process. This new process inherits the changed variables. However, when the child changes its environment variables, it does not affect the corresponding variables of the parent process.
|
||||
The child process can change its environment variables. When it spawns another process, it inherits the changed variables. However, when the child changes its environment variables, it does not affect the corresponding variables of the parent process.
|
||||
|
||||
The `export` built-in command declares an environment variable. Here is an example of doing that:
|
||||
{line-numbers: false, format: Bash}
|
||||
@ -405,36 +405,36 @@ The `export` built-in command declares an environment variable. Here is an examp
|
||||
export BROWSER_PATH="/opt/firefox/bin"
|
||||
```
|
||||
|
||||
You can declare the variable and then add it to the global scope. Call the `export` command in this way:
|
||||
You can declare the variable and then add it to the global scope. Call the `export` command this way:
|
||||
{line-numbers: true, format: Bash}
|
||||
```
|
||||
BROWSER_PATH="/opt/firefox/bin"
|
||||
export BROWSER_PATH
|
||||
```
|
||||
|
||||
Sometimes you want to declare the environment variables for the specific application only. Then list the variables and their values before the application call. Here is an example:
|
||||
Sometimes you need to declare the environment variables for the specific application only. List the variables and their values before the application call in this case. Here is an example:
|
||||
{line-numbers: false, format: Bash}
|
||||
```
|
||||
MOZ_WEBRENDER=1 LANG="en_US.UTF-8" /opt/firefox/bin/firefox
|
||||
```
|
||||
|
||||
Here the Firefox browser receives the specified `MOZ_WEBRENDER` and `LANG` variables. They can differ from the system-wide settings.
|
||||
This command launches the Firefox browser and passes it the `MOZ_WEBRENDER` and `LANG` variables. They can differ from the global Unix settings.
|
||||
|
||||
Suppose that you use another interpreter as the shell. An example is Bourne Shell. Then you should apply the `env` utility. It declares environment variables for the launching application. Here is an example:
|
||||
The last example works well in Bash. If you use another shell, you need another approach. Suppose that you use Bourne Shell. Then you can pass variables to the application using the `env` utility. Here is an example for doing that:
|
||||
{line-numbers: false, format: Bash}
|
||||
```
|
||||
env MOZ_WEBRENDER=1 LANG="en_US.UTF-8" /opt/firefox/bin/firefox
|
||||
```
|
||||
|
||||
If you call the `env` utility without parameters, it prints all declared environment variables for the current interpreter process. Try to get this output in your terminal:
|
||||
If you call the `env` utility without parameters, it prints all declared environment variables for the current interpreter process. Call it in your terminal this way:
|
||||
{line-numbers: false, format: Bash}
|
||||
```
|
||||
env
|
||||
```
|
||||
|
||||
The `export` command and the `env` utility print the same thing if called without parameters. Prefer to use `export` instead of `env`. There are two reasons for that. First, the `export` output is sorted. Second, all variable values are enclosed in double-quotes. They prevent you from making a mistake if there is a line break in some value.
|
||||
The `export` Bash built-in and the `env` utility print the same thing when called without parameters. Use `export` instead of `env`. There are two reasons for that. First, the `export` sorts its output. Second, it adds double quotes to the values of all variables. They prevent you from making a mistake if some values have line breaks.
|
||||
|
||||
Environment variable names have uppercase letters only. Therefore, it is considered good practice to name local variables in lower case. It prevents you from accidentally using one variable instead of another.
|
||||
All names of environment variables contain uppercase letters only. Therefore, it is a good practice to name local variables in lower case. It prevents you from accidentally using one variable instead of another.
|
||||
|
||||
#### Local Variables
|
||||
|
||||
|
||||
Reference in New Issue
Block a user