204 lines
6.6 KiB
Markdown
204 lines
6.6 KiB
Markdown
---
|
||
tags:
|
||
- shell
|
||
---
|
||
|
||
# Environmental and shell variables
|
||
|
||
## Important!
|
||
|
||
To understand the difference between environmental and shell variables know
|
||
that:
|
||
|
||
- You can spawn child shells from the parent shell that is initiated when you
|
||
first open the terminal. To do this just run `bash` or `zsh` .
|
||
- This is a self-contained new instance of the shell. This means:
|
||
- It **will have** access to environmental variables (since they belong to the
|
||
parent / are global)
|
||
- It **will not have** access to any shell variables that are defined in the
|
||
parent.
|
||
- **How do you get back to the ‘upper’ parent shell?** Type `exit` .
|
||
- Note that:
|
||
- Custom (user-created) shell variables **do not** pass down to spawned shell
|
||
instances, nor do they pass up to the parent
|
||
- Custom (user-created) environment variables do pass down to spawned shell
|
||
instances but do not pass up to the parent. They are lost on `exit` .
|
||
|
||
Q. What methods are there for keeping track of, preserving, and jumping between
|
||
spawned instances? Is this even possible or do they die on `exit` .
|
||
|
||
## Questions, research
|
||
|
||
1. If you create a variable manually I guess it won’t make it to any config
|
||
file. How would you create a persistent var that is added to the `.bashrc`
|
||
and thus which would be initialised on every session? Is this where the path
|
||
comes in?
|
||
1. What methods are there for keeping track of, preserving, and jumping between
|
||
spawned instances? Is this even possible or do they die on `exit` ?
|
||
|
||
## What is the shell environment and what are environment variables?
|
||
|
||
- Every time that you interact with the shell you do so within an
|
||
**environment**. This is the context within which you are working and it
|
||
determines your access to resources and the behaviour that is permitted.
|
||
|
||
- The environment is an area that the shell builds every time that it starts a
|
||
session. It contains variables that define system properties.
|
||
|
||
- Every time a [shell session](Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6)
|
||
spawns, a process takes place to gather and compile information that should be
|
||
available to the shell process and its child processes. It obtains the data
|
||
for these settings from a variety of different files and settings on the
|
||
system.
|
||
|
||
- The environment is represented by strings comprising key-value pairs. For
|
||
example:
|
||
|
||
```bash
|
||
KEY=value1:value2
|
||
KEY="value with spaces":"another value with spaces"
|
||
```
|
||
|
||
As the above shows, a key can have multiple related values. Each one is
|
||
demarcated with a `:` . If the value is longer than a single word, quotation
|
||
marks are used.
|
||
|
||
- The keys are **variables**. They come in two types: **environmental
|
||
variables** and **shell variables:**
|
||
|
||
- Environmental variables are much more permanent and pertain to things like
|
||
the user and his path (the overall session)
|
||
- Shell variables are more changeable for instance the current working
|
||
directory (the current program instance)
|
||
|
||
Variables can be created via config files that run on the initialisation of the
|
||
session or manually created via the command line in the current session
|
||
|
||
## What are shell variables useful for?
|
||
|
||
Some deployment mechanisms rely on environmental variables to configure
|
||
authentication information. This is useful because it does not require keeping
|
||
these in files that may be seen by outside parties.
|
||
|
||
More generally they are used for when you will need to read or alter the
|
||
environment of your system.
|
||
|
||
## Viewing shell and environmental variables
|
||
|
||
To view the settings of your current environment you can execute the `env`
|
||
command which returns a list of the key-value pairs introduced above. Here are
|
||
some of the more intelligible variables that are returned when I run this
|
||
command:
|
||
|
||
```bash
|
||
SHELL=/usr/bin/zsh
|
||
DESKTOP_SESSION=plasma
|
||
HOME=/home/thomas
|
||
USER=thomas
|
||
PWD=/home/thomas/repos/bash-scripting
|
||
PATH=/home/thomas/.nvm/versions/node/v16.8.0/bin:/home/thomas/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin
|
||
```
|
||
|
||
However if you want to target a specific viable you need to invoke `printenv`
|
||
with the relevant key, for example:
|
||
|
||
```bash
|
||
printenv SHELL
|
||
# SHELL=/usr/bin/zsh
|
||
```
|
||
|
||
Note that `env` and `printenv` do not show all the shell variables, only a
|
||
selection. To view all the shell variables along with the environmental
|
||
variables use `set` .
|
||
|
||
## Creating, exporting and deleting variable shell and environment variables
|
||
|
||
- You set shell variables using the same syntax you would within a script file:
|
||
|
||
```bash
|
||
TEST_SHELL_VAR="This is a test"
|
||
set | grep TEST_SH
|
||
TEST_SHELL_VAR='This is a test'
|
||
|
||
# We can also print it with an echo, again exactly as we would with a shell script
|
||
echo S{TEST_SHELL_VAR}
|
||
```
|
||
|
||
- We can verify that it is not an environmental variable based on the fact that
|
||
following does not return anything:
|
||
|
||
```bash
|
||
printenv | grep TEST-SH
|
||
```
|
||
|
||
- We can verify that this is a shell variable by spawning a new shell and
|
||
calling it. Nothing will be returned from the child shell.
|
||
|
||
- You can upgrade a shell variable to an environment variable with `export` :
|
||
|
||
```bash
|
||
export TEST_SHELL_VAR
|
||
# And confirm:
|
||
printenv | grep TEST_SH
|
||
TEST_SHELL_VAR='This is a test'
|
||
```
|
||
|
||
- We can use the same syntax to create new environment variables from scratch:
|
||
|
||
```bash
|
||
export NEW_ENV_VAR="A new var"
|
||
```
|
||
|
||
### Using config files to create variables
|
||
|
||
You can also add variables to config files that run on login such as your user
|
||
`.bashrc` / `.zshrc` . This is obviously best for when you want the variables to
|
||
persist and be accessible within every
|
||
[shell session](Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6).
|
||
|
||
## Important environmental and shell variables
|
||
|
||
### `PATH`
|
||
|
||
A list of directories that the system will check when looking for commands. When
|
||
a user types in a command, the system will check directories in this order for
|
||
the executable.
|
||
|
||
```bash
|
||
echo ${PATH}
|
||
# /home/thomas/.nvm/versions/node/v16.8.0/bin:/home/thomas/.local/bin:/usr/local/sbin:/usr/local/bin:
|
||
# /usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin
|
||
```
|
||
|
||
For example, if you wish to use `npm` commands globally (in any directory) you
|
||
will need to have the requisite Node executable in your path, which you can see
|
||
above.
|
||
|
||
### `SHELL`
|
||
|
||
This describes the shell that will be interpreting any commands you type in. In
|
||
most cases, this will be bash by default, but other values can be set if you
|
||
prefer other options.
|
||
|
||
```bash
|
||
echo ${SHELL}
|
||
# /usr/bin/zsh
|
||
```
|
||
|
||
### `USER`
|
||
|
||
The current logged in user.
|
||
|
||
```bash
|
||
echo ${USER}
|
||
# thomas
|
||
```
|
||
|
||
### `PWD`
|
||
|
||
The current working directory.
|
||
|
||
```bash
|
||
echo ${PWD}
|
||
# /home/thomas
|
||
```
|