Skip to content

Latest commit

 

History

History
409 lines (240 loc) · 10.2 KB

LPIC-102-500-CH9.md

File metadata and controls

409 lines (240 loc) · 10.2 KB

Writing Scripts

Shell Variables

Two types of environment variables in the Bash shell:

  • Global variables
  • Local variables

Global Environment 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:

printenv

We can display the value using echo:

echo $HOME

Local Environment variables

Those 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.

Setting Local Environment Variables

Naming covention: Lowercase for user defined variables and upercase for system environment variables.

test=test
echo $test

If we enter another shell the echo will return nothing, since we defined a local variable and not a global one.

Setting Global Environment Variables

We do that by using export before asigning a variable.

Locating System Environment Variables

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

Login Shell

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:

  1. /etc/profile
  2. $HOME/.bash_profile
  3. $HOME/.bash_login
  4. $HOME/.profile

We can also find the /etc/profile.d directory for programs to set the environment variables without modifying the main file.

Interactive Shell

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

Noninteractive Shell

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.

Using Command Aliases

We can set aliases for larger commands using the alias command

alias -p # list alias values
alias li='ls -il' #setting an alias value

This is treated as a local environment variable, to make it persistive add it to the .bashrc startup file.

The Basics of Shell Scripting

Running Multiple Commands

We can run multiple commands separating them with ;

echo test;echo test2

Redirecting Output

date > today.txt # Creates a file even if exists
date >> today.txt # Appends

To remember: File descriptors

  • STDIN (0), STDOUT (1), STDERR(2)

Piping Data

We can pip data using |.

The Shell Script Format

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.

Running the Shell script

To run the shell we need to give it exec permissions:

chmod u+x test.sh
./test.sh

Once 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.sh

Advanced Shell Scripting

Displaying Messages

We can use echo

Using Variables in Scripts

Using Global Environment Variables

We can employ the global env vars in the script employing $GLOBAL.

Defining Local Variables

Set them test=10 the datatype is automatically determined.

Command-Line Arguments

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.

Getting User Input

Basic Reading
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: " age

If 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 last

If more that two values are passed, the rest is saved on the last variable specified.

Timing Out

We can limit the time that the script waits for user input using -t option:

read -t 5 -p "Please enter your name: " name

We 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] " answer
Silent reading

We 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.

The Exit Status

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.

Writing Script Programs

Command Substitution

We can save the output of a command in a variable using $() or ``

Performing Math

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)

Logic Statements

The if Statement
if [ condition ]
then
    commands
fi

Interesting 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

The case Statement
case variable in
pattern1) commands1;;
pattern2) | pattern3) commands2;;
*) default commands;;
esac
Loops
The for Loop
for variable in series ; do
    commands
done

For a range we can employ seq.

The while Loop
while [ condition ] ; do
    commands
done
Functions

Two ways of defining functions

function name {
    commands
}

name() {
    commands
}

We cab use return to return a value.

Runnig Scripts in Background Mode

Running in the Background

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 &

Sending Signals

Interrupting a Process

Using Ctrl+C we can send a SIGINT to the current process running in the shell.

Pausing a Process

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.

Job Control

Viewing Jobs

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.

Restarting Stopped Jobs

We can restart stopped jobs using bg which runs it in the background or with fg which brings the job to the foreground.

Running Like Clockwork

To schedule jobs we can employ at command or cron table.

Scheduling a Job Using the at Command

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.

The at Command Format

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.

Retrieving Job Output

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.

Listing Pending Jobs

We can employ the atq command with no options to list pending jobs.

Removing 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.

Scheduling Regular Scripts

We can use cron to run a script or command on a regular basis like daily.

The cron Table

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.

Building the cron Table

We can list crontab using crontab -l or edit the crontab using crontab -e.