Two types of environment variables in the Bash shell:
- Global variables
- Local variables
Global env vars are visible from the shell session and from any child processes that the shell spawns.
We can look at the global env vars:
printenvWe can display the value using echo:
echo $HOMEThose variables can e seen only in the local process in which they are defined.
There is no command to display only local variabels.
We can use set to print all variables which includes both global and local environment variables.
Naming covention: Lowercase for user defined variables and upercase for system environment variables.
test=test
echo $testIf we enter another shell the echo will return nothing, since we defined a local variable and not a global one.
We do that by using export before asigning a variable.
When you start a bash shell by logging into the Linux system, by default Bash checks several files for commands. These files are called startup files. Depending on the method of starting the bash shell certain files are processed.
There are three ways of starting a bash shell:
- As a default login shell at login time
- As an interactive shell that is not the login shell
- As a noninteractive shell to run a script
When you login into the Linux system, the bash shell starts as a login shell.
Order in which the Bash shell processes the files is:
/etc/profile$HOME/.bash_profile$HOME/.bash_login$HOME/.profile
We can also find the /etc/profile.d directory for programs to set the environment variables without modifying the main file.
This is when you type bash at a CLI or open a GUI terminal.
Bash checks for the ~/.bashrc file. This file first checks for a common /etc/bash.bashrc file.
bashrc does two things:
- Checks for the common file
- Provides a place for the user to enter personal aliases and private script functions
This is the shell that the system starts to execute a shell script. If we want specific commands to run each time a script is started on the system we can set the BASH_ENV to point to a script.
We can set aliases for larger commands using the alias command
alias -p # list alias values
alias li='ls -il' #setting an alias valueThis is treated as a local environment variable, to make it persistive add it to the .bashrc startup file.
We can run multiple commands separating them with ;
echo test;echo test2date > today.txt # Creates a file even if exists
date >> today.txt # AppendsTo remember: File descriptors
- STDIN (0), STDOUT (1), STDERR(2)
We can pip data using |.
We can use a text file to run commands. For that we need to employ the so called shebang #! followed by the shell #!/bin/bash.
No need to end the file with .sh but its a facto standard.
To run the shell we need to give it exec permissions:
chmod u+x test.sh
./test.shOnce we execute the script we can't use the local variables in the current shell. If we want to use them we can employ exec:
exec ./test.shWe can use echo
We can employ the global env vars in the script employing $GLOBAL.
Set them test=10 the datatype is automatically determined.
We can pass arguments and reference them using $N being 1 the first argument and so on. If we try to reference a non-existent argument we won't get an error.
echo -n "Enter your name: " # -n supreses the newline char
read name # Reads the input and asigns it to name var
echo "Hello my name is $name"We can also employ the -p option of read:
read -p "Please enter your age: " ageIf we want to pass more than one input and asign it to diferent variables we can do that by specifying more variables:
read -p "Complete name": first lastIf more that two values are passed, the rest is saved on the last variable specified.
We can limit the time that the script waits for user input using -t option:
read -t 5 -p "Please enter your name: " nameWe can also limit the number of characters with the -nN option being N the number of chars.
read -n1 -p "Do you want to continue [Y/N] " answerWe can avoid displaying what the user writes on the input using -s option. What happens is that read command sets the char color the same as the backgrond.
We can check the exit status of the last command executed using $?.
To specify an exit code we can employ exit. If no number is given it exits with 0.
A 0 indicates success while a positive integer indicates error.
We can save the output of a command in a variable using $() or ``
We can perform math using $[ 25 * 5] but this does not support floats.
Instead we can employ bc and save the return value into a variable.
To get the desired number of decimal places we need to use scale and set it to the number of decimals.
We can then use echo with the options and finally the expression variable=$(echo "options; expression" | bc)
if [ condition ]
then
commands
fiInteresting options
-n STR: greater than 0 -z STR: its length is 0 -e file: checks if file exists -s file: checks if file exists and is not empty
case variable in
pattern1) commands1;;
pattern2) | pattern3) commands2;;
*) default commands;;
esacfor variable in series ; do
commands
doneFor a range we can employ seq.
while [ condition ] ; do
commands
doneTwo ways of defining functions
function name {
commands
}
name() {
commands
}We cab use return to return a value.
Using & we can run scripts in background mode and a jobid and PID are asigned to the script.
While the background process is still running, it still uses your terminal monitor for output messages.
When the job is finished a Done message is displayed
We can do that more than once and have several jobs active.
To run the process in background even if the session is closed we can use nohup that tells the process to ignore any SIGHUP signal. The process is dettached from the current terminal monitor and redirects all output generated by the process to nohup.out file.
nohup ./test.sh &Using Ctrl+C we can send a SIGINT to the current process running in the shell.
We can stop the process using Ctrl+Z. This sends SIGTSTP. The program is still on memory and we can continue running it from where it left off.
We can check the stopped job using ps au
we can then kill the process kill -9 PID which sends a SIGKILL.
The PID asigned to the script can be used with $$
We can control jobs using jobs.
Options:
- -l List the PID along with job number
- -n List only jobs that have changed their status since the last notification from the shell
- -p List only the PIDs of the jobs
- -r List only the running jobs
- -s List only stopped jobs
The + sign in the job status indicates that this is the default job. The default job is the one used by jobs command if no jobid is specified. The - sign indicates that after the default job finishes, this will become the default job.
We can restart stopped jobs using bg which runs it in the background or with fg which brings the job to the foreground.
To schedule jobs we can employ at command or cron table.
The atd command runs in the background and checks the job queue for jobs to run. Most Linux distros start this at boot time.
atd checks a special directory on the system, usually /var/spool/at for jobs submited using the at command. It checks the dir every 60 seconds by default.
Format: at [-f filename] time
time can be specified in diferent formats:
- HH:MM, HH:MMPM/AM, a name such as now, noon, midnight or teatime(4PM)
If the hour is past, then is executed the next day at the specified hour.
For date:
- MMDDYY or MM/DD/YY or DD.MM.YY, text date such Jul 4 with or without the year, time increment Now + 25 minutes or 10:15PM tomorrow or 10:15 + 7 days.
There are 26 job queues from a to z. a being the highest priority. By default jobs are sent to the a queue.
We can use the -q to specify a queue.
When a scheduled job is executed any output destined to STDOUT or STDERR is mailed to the user via the mail system.
If no output is generated by the job then no mail is sent. We can still send the mail using -m option.
We can employ the atq command with no options to list pending jobs.
We can employ the atrm command to remove jobs.
For systemd init systems we can employ systemd-run to run a job at a specific time.
We can use cron to run a script or command on a regular basis like daily.
An entry format is: min hour dayofmonth month dayofweek command
the month can be specified as a three-character text value like mon.
15 10 6 * * echo "hi": this will execute at 10:15 the 6th day of every month.
We can list crontab using crontab -l or edit the crontab using crontab -e.