About the Shell

To get an overview of the shell, we need to take a brief look at the Linux system.

Linux system

The Linux system is divided into four parts:

  1. LinuxThe kernel
  2. GNUtool
  3. Graphical desktop environment
  4. Application software

The Linux kernel

The Linux kernel is responsible for the following four functions:

  • System memory management: physical memory and virtual memory
  • Software program management:LinuxThe operating system refers to a running program as a process. The kernel controlsLinuxHow the system manages all the processes running on the system. The kernel creates the first process (calledinitProcess) to start all other processes on the system,LinuxUse a table to manage the processes that are to be started automatically when the system starts up.LinuxOperating systeminitThe system adopts the run-level. The runlevel determinesinitProcess is running/etc/inittabFile or/etc/rcX.dCertain types of processes defined in the directory (XRepresents runlevel).LinuxThe operating system has five boot runlevels. Each startup runlevel is a startup mode.
  • Hardware device management: Another responsibility of the kernel is to manage hardware devices. anyLinuxAny device that the system needs to communicate with needs to have its driver code in the kernel code. Driver code acts as a middleman between the application and the hardware device, allowing data to be exchanged between the kernel and the device.
  • File system management: Unlike some other operating systems,LinuxThe kernel supports reading and writing data from the hard disk through different types of file systems.

GNU

Operating systems perform standard functions, such as tools to control files and programs. Linus had no system tools available when creating a Linux system kernel. GNU is a complete set of Unix tools developed by the GNU organization (GNU stands for GNU’s Not Unix), which are open source but have no kernel system to run them. The result is a complete, features-rich free operating system: GNU/Linux (also known as Linux, thanks to the GNU organization).

GNU is divided into two parts. One is the core GNU Utilities, which consists of three parts: file processing, text operation and process management. The other part is the Shell.

Introduction of the Shell

The Shell is a special kind of interactive tool. It provides users with a way to start programs, manage files in the file system, and processes running on Linux systems. That is, the Shell is responsible for interpreting the text command input in the command line and passing it to the kernel for execution. It can also be called the interpreter.

At the heart of the Shell is the command line prompt. The command-line prompt is the interactive part of the Shell that allows you to enter text commands, interpret them, and execute them in the kernel. A file in which multiple shell commands are executed as a program is called a shell script.

On Linux systems, there are usually several Linux shells available. Different shells have different features, some better for creating scripts, others better for managing processes. The default shell for all Linux distributions (complete Linux system packages) is the Bash shell.

Bash Shell was developed by the GNU organization as an alternative to the standard Unix shell, the Bourne shell(named after its creator). The bash shell’s name is a wordplay on the Bourne shell spelling, called the Bourne Again Shell. Summary: SH is the standard and bash is a replacement for sh. In addition to the bash shell, there are several different shells that are common in Linux:

  • ash: a simple lightweight that runs in memory-constrained environmentsshellBut, unlikebash shellFully compatible.
  • korn: aBourne shellCompatible programmingshell, but supports advanced programming features such as associative arrays and floating point arithmetic.
  • tcsh: a willCSome elements of the language are introduced intoshellIn the scriptshell.
  • zsh: A combinationbash,tcshandkornProvides advanced programming features, sharing history files, and thematic promptsshell.

Starting with macOS Catalina, Apple’s Mac systems will use ZSH as the default login Shell and interactive Shell. Please see the official website for details.

The environment variable

This section will develop the presentation based on the Bash shell.

The bash shell uses environment variables to store data in memory about the shell session and working environment so that programs or scripts running in the shell can access them.

There are two main types of environment variables in bash shells: global variables and local variables. To view all global variables in the system, use env or printenv. To display the values of individual environment variables, use the printenv command, but not the env command.

View individual global variables of the shell
printenv HOME
# View individual global variables of the shell: output as variables through echo
echo $HOME
Copy the code

The environment of the system is all in uppercase. When defining local variables belonging to users, use lowercase variables to avoid conflicts.

Defining local variables

The definition form is as follows:

variable=Hello
echo $variable # output: Hello
Copy the code

** Important: There are no Spaces between variable names, equals signs, and values. ** If you add a space to an assignment expression, the Bash shell treats the value as a single command, and variable values with Spaces need to be quoted.

variable="Hello word"
echo $variable # Output: Hello word
Copy the code

Defining global variables

The global environment variable is visible in all child processes created by the process that set it; Create a global environment variable by creating a local environment variable and exporting it to the global environment. A global variable defined by the parent shell. Changes to the child shell do not affect the value of the parent shell. The following is an example:

variable="global variable ~~~~"
export variable
Open the subshell
bash
# sub shell output
echo $variable #global variable ~~~~
# Subshell modification
variable="Subshell modification"
# sub shell output
echo $variable # Output: subshell modification
# export
export variable
Exit the subshell
exit
# Parent shell output
echo $variable # Child shell changes do not affect the parent shell:global variable ~~~~
Copy the code

Delete global variables

Use the following command:

# remove
unset variable
Copy the code

Note that in the subshellIs unable to delete the parentshellGlobal variable created.

Default global variable

By default, the Bash shell defines the system environment with some specific environment variables. These variables are already set on your Linux system, so feel free to use them. The Bash shell is derived from the original Unix Bourne shell, so it also retains the environment variables defined in the Unix Bourne shell. To name a few common environment variables:

  • CDPATH: colon-delimited directory list, ascdCommand search path
  • HOME: Home directory of the current user
  • PATH:shellThe list of directories to find commands, separated by colons
  • BASH: the currentshellThe full pathname of the instance
  • PWD: Current working directory

Setting the PATH variable

When we enter an external command into the shell’s command-line interface, the shell must search the system to find the corresponding program. The PATH environment variable defines the directory to use for command and program lookups:

# under the output
echo $PATH
# the results/ Users / * /. RVM/gems/ruby - 2.3.0 / bin: / Users / * /. RVM/gems/ruby - 2.3.0 @ global/bin: / Users / * /. RVM/rubieslast/ruby - 2.3.0 / bin: /Users/*/Desktop/development/flutter/bin: /usr/local/bin:
/usr/bin:
/bin:
/usr/sbin:
/sbin:
/Users/*/.rvm/bin
Copy the code

The output shows 10 paths that the shell can use to find commands and programs.PATHDirectories in are separated by colons. Each of these paths contains different commands and programs, for example/binExample:

If the command or program PATH is not included in the PATH variable, the shell cannot find the program without using an absolute PATH.

** Problem: ** Applications often place executables in directories that are not included in the PATH environment variable.

** ensures that the PATH environment variable contains all directories where the application is stored. You can add a new search directory to an existing PATH environment variable without having to define it from scratch. The directories in PATH are separated by colons, so we simply reference the original PATH value and then add a new directory to the string.

For example, the terminal enables the flutter command:

# see the path
echo $PATH
# the result does not contain: / Users / * / Desktop/development/flutter/bin:
# Enable via terminal
PATH=$PATH:~/Desktop/development/flutter/bin
# Check again
echo $PATH
# results include: / Users / * / Desktop/development/flutter/bin:
# execution flutter
flutter -v
No longer prompts that commands cannot be found.
Copy the code

It is important to note that changes to the PATH variable only last until you exit or restart the terminal system. The effect does not last forever. How do you make it last?

To solve this problem, we need to know something about locating environment variables.

When we log in to Linux to launch a bash shell, by default bash looks for commands in several files. These files are called startup files or environment files. The startup file that bash checks for depends on how you start your Bash shell. There are three ways to start bash shell:

  • As the default loginshell
  • As a non-loginshellThe interactiveshell
  • As a non-interaction to run the scriptshell

Default Login Shell

When we log on to a Linux system, the bash shell launches as the login shell. The login shell reads commands from five different startup files:

  1. /etc/profile
/etc/profile Startup file contents

# System-wide .profile for sh(1)

if [ -x /usr/libexec/path_helper ]; then
	eval `/usr/libexec/path_helper -s`
fi

if [ "${BASH-no}"! ="no" ]; then
	[ -r /etc/bashrc ] && . /etc/bashrc
fi
Copy the code
  1. $HOME/.bash_profile
  2. $HOME/.bashrc
#macOS. Bashrc startup file contents, non-logon interactive shell will use this as the startup file.
export PATH="$PATH:$HOME/.rvm/bin"
Copy the code
  1. $HOME/.bash_login
  2. $HOME/.profile

The /etc/profile file is the default bash shell’s primary startup file on your system. This startup file is executed by every user on the system when they log in. The other four startup files are for users, providing a user-specific startup file to define the environment variables used by the user. They can be customized according to personal requirements, and are all hidden files. They are located in the user’s HOME directory, so each user can edit these files and add their own environment variables, which take effect each time a Bash shell session is started. 2 and 5 are familiar from macOS.

Bash_profile =>$HOME/. Bash_login =>$HOME/. Profile note: $HOME represents the user directory just like the tild ~. Because of this rule, we sometimes just need to configure our PATH in $HOME/.profile.

Non-login interactive shell

Shells that are not launched at login are called interactive shells. For example, start when you type bash at a command prompt. When bash is started as an interactive shell, the /etc/profile file is not accessed, only the.bashrc file under the user directory $HOME is checked.

A non-interactive shell that runs the script

Non-interactive shell, used when the system executes shell scripts. The difference is that there is no command line prompt. But when we run scripts on the system, we might want to run some specific startup commands. To handle this, the bash shell provides the BASH_ENV environment variable. When the shell starts a non-interactive shell process, it checks this environment variable to see the startup file to execute.

If you run echo $BASH_ENV on macOS, the environment variable is not set. How do shell scripts get their environment variables if the BASH_ENV variable is not set?

  • The childshellYou can inherit from your fathershellEnvironment variables everywhere; But the thing to watch out for is the fathershellIs set but notexportVariables of, belonging to local variables, childrenshellIt’s not accessible. That is, when executing the script, thebashCommand openershellCan solve this problem.
  • No promotershellThe variables already exist in the scriptshellIn the.

Persistence of environment variables

On most distributions of Linux, the place to store persistent bash shell variables for individual users is the $HOME/.bashrc file. This point applies to all types of shell processes. But if the BASH_ENV variable is set, then unless BASH_ENV points to $HOME/.bashrc, you should put the user variable of the non-interactive shell somewhere else.

Profile, ~/.bash_profile, ~/.bashrc (interactive shell). Either ~/.profile or ~/.bash_profile can define our permanent bash shell variable.

# defined in the '~/.profile' file
export LOVE="Globally available environment variable love"
PEACE="Local environment variable, subshell unavailable"
# is defined in the '~/.bash_profile' file
export SHARE="Globally available environment variable Share"
QI="Local environment variable, subshell unavailable"
# terminal shell, view global variables
env
# outputLOVE= Globally available environment variable LOVE SHARE= globally available environment variable SHARE# terminal shell, view permanent local variables
echo $PEACE
echo $QI
# outputLocal environment variable, subshell not availableEnable non-login interactive shell
bash
# subshell to view available global variables
env
# outputLOVE= Globally available environment variable LOVE SHARE= globally available environment variable SHARE# child shell, view the local variables of the available parent shell
echo $PEACE
echo $QI
Output is null

Copy the code

About ~/.bashrc, as a startup file for non-login interactive shells, only for non-login interactive shells:

# configure in '~/.bashrc'
export CHILD="Subshell available"
# Open terminal again, enter
env
#or
echo $CHILD
# all output: null
 
# Enable subshell (interactive shell)
bash
View the global variables of the subshell
env 
#or
echo $CHILD
# outputCHILD= Subshell Available Subshell available# Open the subshell again
bash
# enter
env 
#or
echo $CHILD
# outputCHILD= Subshell Available Subshell available# if '~/.bashrc' file is configured
CHILD="Subshell available"
# enter
env
# output: null
# enter
echo $CHILD
# outputA subshell available# Open the subshell again and the 'CHILD' variable will no longer be in effect
Copy the code

An array variable

Array variables: Environment variables set multiple values, enclosed in parentheses, separated by Spaces.

Define array variables
ARRAY_VAR=(one two three)
Output array variables
echo $ARRAY_VAR
Only the first element of an array variable will be printed
one
Copy the code

To reference an element in an array variable, it must be indexed by a numeric value representing its position in the array. Index values are enclosed in square brackets:

echo ${ARRAY_VAR[2]}
# output
three
Display the entire array
echo ${ARRAY_VAR[*]}
Copy the code

You can use the unset command to remove a value from an array, but be careful. Such as:

# drop element with index 1
unset ARRAY_VAR[1]
Print the entire array
echo ${ARRAY_VAR[*]}
# delete succeeded
one three
Print the element with index 1 in the array
echo ${ARRAY_VAR[1]}
# result: null

Output the element with index 2
echo ${ARRAY_VAR[2]}
# the results
3
Copy the code

Linux command line and shell scripting