Linux bash scripts. Writing scripts in Bash

Everyone probably knows that the Bash shell has built-in commands that are not found in the /bin or /usr/bin folders. They are built into the shell and executed as functions. In one of the previous articles we looked at. We discussed almost everything there, how scripts should look like, the use of conditions, loops, variables, but did not stop at functions.

In today's article we will correct this shortcoming. Like any programming language, Bash has functions that can be very useful to use. We'll look at using bash functions, how to write them, and even how to create libraries from these functions.

First we need to understand what a function is in our context. A function is a set of commands, united by one name, that perform a specific task. A function is called by its name, can accept parameters and return the result of its work. In short, Bash functions work the same way as in other programming languages.

The syntax for creating a function is very simple:

function_name () ( command_list )

The function name must not coincide with any existing commands or functions, and all commands in the function body are written on a new line.

Simple function

Let's write a small function that will print a string to the screen:

$vi function.sh

#!/bin/bash
printstr())(
echo "hello world"
}
printstr

Calling a bash function is done by specifying its name, just like any other command. Run our script for execution, do not forget that before doing this you need to give it execution rights:

chmod u+x function.sh

Everything works, now let’s complicate the task, let’s try to pass arguments to the function.

Function Arguments

Function arguments must be passed when called, and they are read in exactly the same way as script arguments. Syntax for calling a function with bash parameters such:

function_name argument1 argument2 ... argumentN

As you can see, everything is quite simple. Parameters are separated by a space. Now let's improve our function so that it outputs the string we specified:

!/bin/bash
printstr())(
echo $1
}
printstr "Hello world"

You can have several parameters:

!/bin/bash
printstr())(
echo $1
echo $2
echo $3
echo $5
}
printstr "arg1" "arg2" "arg3" "arg4" "arg5"

There is another way to retrieve arguments, like in C, using the stack. We pop the first argument, then advance the argument stack pointer by one, and pop the first argument again. And so on:

!/bin/bash
printstr())(
echo $1
shift
echo $1
shift
echo $1
shift
echo $1
}
printstr "arg1" "arg2" "arg3" "arg4"

Returning the result of a function

You can not only use functions with bash parameters, but also get the result of the work from it. The return command is used for this. It terminates the function and returns a numeric return code. It can be from 0 to 255:

!/bin/bash
printstr())(
return 134;
}
printstr
echo $?

If you need to apply the return value of a bash function rather than the status code, use echo. The string is not immediately printed to the terminal, but is returned as the result of the function and can be written to a variable and then used:

!/bin/bash
printstr())(
echo "test"
}
VAR=$(printstr)
echo $VAR

Export functions

You can make a function available outside of a script using the declare command:

!/bin/bash
printstr())(
echo "hello world"
}
declare -x -f printstr

Then run the script using the source command:

source function.sh
$printstr

Recursion

You can call a function from within itself to do recursion:

!/bin/bash
printstr())(
echo "hello world"
printstr
}
printstr

You can experiment with using recursion, which can be useful in many cases, just remember to make the first call to a Bash function.

Local variables in a function

If you declare a regular variable in a function, it will be available throughout the script, this is convenient for returning the value of the function, but sometimes you may need to make it a local variable. There is a local command for this:

!/bin/bash
printstr())(
local VAR=$1
echo $(VAR)
}
printstr "Hello World"

Function libraries

We can take some bash functions and combine them into one library so that we can import these functions with one command. This is done in a similar way to exporting functions. First, let's create a library file:

test1())(
echo "Hello World from 1";
}
test2())(
echo "Hello World from 2";
}
test3())(
echo "Hello World from 3";
}

Now let's create a script that will use our functions. You can import the library using the source command or simply by specifying the script name:

!/bin/bash
source lib.sh
test1
test2
test3

conclusions

In this article, we looked at bash functions, how to write them, use them, and combine them into libraries. If you often write scripts in Bash, then this information will be useful to you. You can create your own set of functions to use in each script and thereby make your work easier.

Writing scripts in Linux (learning with examples)

———————————————————————————-

1. Introduction

What you need to write scripts
Tool Proficiency command line and their necessary options.
Basic knowledge in English level primary school will not interfere.

Why are scripts needed?
Firstly, administering a Linux server to one degree or another comes down to systematically executing the same commands. Moreover, it is not necessary that these commands be carried out by a person. They can be programmed to be executed by a machine.
Secondly, even just performing a regular task, which (suddenly) amounts to 20-1000... monotonous operations is MUCH easier to implement in a script.

What is a script
A script is a set of instructions that must be in a certain order and in certain time execute computer. Instructions can be either internal shell commands (cycles, conditions, processing text information, working with environment variables etc.), as well as any program we execute in the console with the necessary parameters.

How to write a script
In our case, the script will be a text file with execution attributes. If a script file begins with the sequence #!, which in the UNIX world is called sha-bang, then this tells the system which interpreter to use to execute the script. If this is difficult to understand, then just remember that we will start writing all scripts with the line #!/bin/bash or #!/bin/sh, and then the commands and comments for them will follow.

Parting words
I sincerely advise you to write as many comments as possible on almost every line in the script. Time will pass and you will need to change or modernize the script you once wrote. If you don’t remember or don’t understand what is written in the script, then it becomes difficult to change it; it’s easier to write from scratch.

What scripts might we need:

    setting firewall rules when the system boots.
    performing backup of settings and data.
    launching at a certain time (preferably every night) a program that scans the proxy server logs and produces a convenient web report on the amount of downloaded traffic.
    sending us information by email that someone has accessed our server via ssh, connection time and client address.

About the method of writing scripts
We create a text file, edit it, set execution rights, run it, look for errors, correct it, run it, look for errors...
When everything is polished and working correctly, we put it in autoload or in the scheduler for a certain time.

———————————————————————————-

2. Learning to write scripts in the internal BASH language
original: https://www.linuxconfig.org/Bash_scripting_Tutorial

This tutorial assumes no prior knowledge of how to write scripts using internal language Bash. With the help of this guide, you will soon discover that writing scripts is a very simple task. Let's start our tutorial with a simple script that prints the string "Hello World!" (translated from English - Hello everyone!)

1. Scenario “Hello everyone”
Here's your first bash script example:

#!/bin/bash
echo "Hello World"

Let's go to the directory containing our hello_world.sh file and make it executable:

Code: Select all $ chmod +x hello_world.sh

Running the script for execution

Code: Select all $ ./hello_world.sh

2. Simple archiving bash script

#!/bin/bash
tar -czf myhome_directory.tar.gz /home/user

Code: Select all $ ./backup.sh

$ du -sh myhome_directory.tar.gz
41M myhome_directory.tar.gz

3. Working with variables
IN in this example we declare a simple variable and display it on the screen using the echo command

#!/bin/bash
STRING=”HELLO WORLD!!!”
echo $STRING

Code: Select all $ ./hello_world.sh
HELLO WORLD!!!

Our archiving script with variables:

#!/bin/bash
OF=myhome_directory_$(date +%Y%m%d).tar.gz
IF=/home/user
tar -czf $OF $IF

Code: Select all $ ./backup.sh
tar: Removing leading "\" from member names
$ du -sh *tar.gz
41M myhome_directory_20100123.tar.gz

3.1 Global and local variables

#!/bin/bash
# Declare a global variable
# Such a variable can be used anywhere in this script
VAR="global variable"
function bash(
# Declare a local variable
# Such a variable is only valid for the function in which it was declared
local VAR=”local variable”
echo $VAR
}
echo $VAR
bash
# Note that the global variable has not changed
echo $VAR

Code: Select all $ ./variables.sh
global variable
local variable
global variable

4. Pass arguments to the script

#!/bin/bash
# Use predefined variables to access arguments
# Print arguments to screen
echo $1 $2 $3 ‘ -> echo $1 $2 $3’

#We can also access arguments through a special array args=("$@")
# Print arguments to screen
echo $(args) $(args) $(args) ‘ -> args=(“$@”); echo $(args) $(args) $(args)’

# Use $@ to print all arguments at once
echo $@ ‘ -> echo $@’

Use the $# variable to display the number of arguments passed to the script
echo Number of arguments passed: $# ‘ -> echo Number of arguments passed: $#’

Code: Select all $ ./arguments.sh Bash Scripting Tutorial
Bash Scripting Tutorial -> echo $1 $2 $3
Bash Scripting Tutorial -> args=("$@"); echo $(args) $(args) $(args)
Bash Scripting Tutorial -> echo $@
Number of arguments passed: 3 -> echo Number of arguments passed: $#

5. Executing shell commands in a script

#!/bin/bash
# use backquotes " ` ` " to execute a shell command
echo `uname -o`
# now let's try without quotes
echo uname -o

Code: Select all $ uname -o
GNU/Linux
$ ./bash_backtricks.sh
GNU/Linux
uname -o

As you can see, in the second case the command itself was displayed, and not the result of its execution

6. Reading user input (interactivity)

#!/bin/bash
echo -e "Hi, please type the word: \c "
read word
echo "The word you entered is: $word"
echo -e “Can you please enter two words? »
read word1 word2
echo "Here is your input: \"$word1\" \"$word2\""
echo -e “How do you feel about bash scripting? »
# read command now stores a reply into the default build-in variable $REPLY
read
echo “You said $REPLY, I’m glad to hear that! »
echo -e “What are your favorite colors? »
# -a makes read command to read into an array
read -a colors
echo “My favorite colors are also $(colours), $(colours) and $(colours):-)”

Code: Select all $ ./read.sh
Hi, please type the word: something
The word you entered is: something
Can you please enter two words?
Debian Linux
Here is your input: "Debian" "Linux"
How do you feel about bash scripting?
good
You said good, I"m glad to hear that!
What are your favorite colors?
blue green black
My favorite colors are also blue, green and black:-)

7. Using a trap

#!/bin/bash
# declare a trap
trap bashtrap INT
# clear the screen
clear;
# The hook function is executed when the user presses CTRL-C:
# The screen will display => Executing bash trap subrutine !
# but the script will continue to run
bashtrap()
{
echo "CTRL+C Detected !…executing bash trap !"
}
# the script will count up to 10
for a in `seq 1 10`; do
echo "$a/10 to Exit."
sleep 1;
done
echo "Exit Bash Trap Example!!!"

Code: Select all $ ./trap.sh
1/10
2/10
3/10
4/10
5/10
6/10

7/10
8/10
9/10
CTRL+C Detected !...executing bash trap !
10/10
Exit Bash Trap Example!!!

As you can see, the Ctrl-C key combination did not stop the execution of the script.

8. Arrays
8.1 Declaring a simple array

#!/bin/bash
# Declare a simple array with 4 elements
ARRAY=('Debian Linux' 'Redhat Linux' Ubuntu Linux)
# Get the number of elements in the array
ELEMENTS=$(#ARRAY[@])

# loop through each element of the array
for ((i=0;i<$ELEMENTS;i++)); do
echo $(ARRAY[$(i)])
done

Code: Select all $./arrays.sh
Debian Linux
Redhat Linux
Ubuntu
Linux

8.2 Filling the array with values ​​from the file

#!/bin/bash
# Declare an array
declare -a ARRAY
# exec command # stdin (usually the keyboard) will be derived from this file. This makes it possible to read
# the contents of the file, line by line, and parse each line entered using sed and/or awk.
exec 10 let count=0

while read LINE<&10; do

ARRAY[$count]=$LINE
((count++))
done

echo Number of elements: $(#ARRAY[@])
# Print array values
echo $(ARRAY[@])
# close the file
exec 10>&-

Code: Select all $ cat bash.txt
Debian Linux
Redhat Linux
Ubuntu
Linux
$ ./arrays.sh
Number of elements: 4
Debian Linux Redhat Linux Ubuntu Linux

9. If-then-else conditions
9.1. Simple use of "if-else" conditions
Pay attention to the spaces in the square brackets, without which the condition will not work.

#!/bin/bash
directory="./BashScripting"

# check for directory presence
if [ -d $directory ]; then
echo "Directory exists"
else
echo "Directory does not exist"
fi

Code: Select all $ ./if_else.sh
Directory does not exist
$ mkdir BashScripting
$ ./if_else.sh
Directory exists

9.2 Nested if-else conditions

#!/bin/bash
# Declare a variable with the value 4
choice=4
# Display
echo "1. Bash"
echo "2. Scripting"
echo "3. Tutorial"

# Execute while the variable is equal to four
# Looping
while [ $choice -eq 4 ]; do

# read user input
read choice
# nested if-else condition
if [ $choice -eq 1 ] ; then

echo "You have chosen word: Bash"

if [ $choice -eq 2 ] ; then
echo “You have chosen word: Scripting”
else

if [ $choice -eq 3 ] ; then
echo “You have chosen word: Tutorial”
else
echo "Please make a choice between 1-3 !"
echo "1. Bash"
echo "2. Scripting"
echo "3. Tutorial"
echo -n “Please choose a word? »
choice=4
fi
fi
fi
done

Code: Select all $ ./nested.sh
1. Bash
2. Scripting
3. Tutorial

5

1. Bash
2. Scripting
3. Tutorial
Please choose a word?
4
Please make a choice between 1-3 !
1. Bash
2. Scripting
3. Tutorial
Please choose a word?
3
You have chosen word: Tutorial

Thus, the body of the “while” loop is executed first, because the choice variable is initially equal to four. Then we read the user input into it, and if the input is not equal to 1,2 or 3, then we make our variable equal to 4 again, and therefore the body of the loop is repeated (you must enter 1,2 or 3 again).

10. Comparisons
10.1 Arithmetic comparisons

Lt<
-gt>
-le<=
-ge >=
-eq ==
-ne !=

#!/bin/bash

NUM1=2
NUM2=2
if [ $NUM1 -eq $NUM2 ]; then
echo "Both Values ​​are equal"
else
echo "Values ​​are NOT equal"
fi

Code: Select all $ ./equals.sh
Both Values ​​are equal

#!/bin/bash
# Declare variables with integer values
NUM1=2
NUM2=3
if [ $NUM1 -eq $NUM2 ]; then
echo "Both Values ​​are equal"
else
echo "Values ​​are NOT equal"
fi

Code: Select all $ ./equals.sh
Values ​​are NOT equal

#!/bin/bash
# Declare variables with integer values
NUM1=2
NUM2=1
if [ $NUM1 -eq $NUM2 ]; then
echo "Both Values ​​are equal"
elif [ $NUM1 -gt $NUM2 ]; then
echo "$NUM1 is greater then $NUM2"
else
echo "$NUM2 is greater then $NUM1"
fi

Code: Select all $ ./equals.sh
2 is greater then 1

10.2 Character-text comparisons

The same
!= not the same
< меньще чем
> more than
-n s1 variable s1 is not empty
-z s1 variable s1 is empty

#!/bin/bash

S1="Bash"

S2="Scripting"
if [ $S1 = $S2 ]; then

else
echo "Strings are NOT equal"
fi

Code: Select all $ ./statement.sh
Strings are NOT equal

#!/bin/bash
# Declare the character variable S1
S1="Bash"
# Declare the character variable S2
S2=”Bash”
if [ $S1 = $S2 ]; then
echo "Both Strings are equal"
else
echo "Strings are NOT equal"
fi

Code: Select all $ ./statement.sh
Both Strings are equal

11. Checking files

B filename Block special file
-c filename Special character file
-d directoryname Check for directory existence
-e filename Check for file existence
-f filename Check for regular file existence not a directory
-G filename Check if file exists and is owned by effective group ID.
-g filename true if file exists and is set-group-id.
-k filename Sticky bit
-L filename Symbolic link
-O filename True if file exists and is owned by the effective user id.
-r filename Check if file is a readable
-S filename Check if file is socket
-s filename Check if file is nonzero size
-u filename Check if file set-ser-id bit is set
-w filename Check if file is writable
-x filename Check if file is executable

#!/bin/bash
file="./file"
if [ -e $file ]; then
echo "File exists"
else
echo "File does not exist"
fi

Code: Select all $ ls
file.sh
$ ./file.sh
File does not exist
$ touch file
$ls
file file.sh
$ ./file.sh
File exists

Similarly, for example, we can use "while" loops to check if the file does not exist. This script will sleep until the file exists. Note the Bash negator "!" which negates (inverts) the -e option.

12. Cycles
12.1. For loop

#!/bin/bash
# for loop
for f in $(ls /var/); do
echo $f
done

Running a for loop from the bash command line:

Code: Select all $ for f in $(ls /var/); do echo $f; done Code: Select all $ for f in $(ls /var/); do echo $f; done
backups
cache
crash
games
lib
local
lock
log
mail
opt
run
spool
tmp
www

12.2. While loop

#!/bin/bash
COUNT=6
# while loop
while [ $COUNT -gt 0 ]; do

let COUNT=COUNT-1
done

Code: Select all $ ./while_loop.sh
Value of count is: 6
Value of count is: 5
Value of count is: 4
Value of count is: 3
Value of count is: 2
Value of count is: 1

12.3. Until loop

#!/bin/bash
COUNT=0
# until loop
until [ $COUNT -gt 5 ]; do
echo Value of count is: $COUNT
let COUNT=COUNT+1
done

Code: Select all $ ./until_loop.sh
Value of count is: 0
Value of count is: 1
Value of count is: 2
Value of count is: 3
Value of count is: 4
Value of count is: 5

12.4. Loops with Implicit Conditions
In the following example, the while loop condition is the presence of standard input.
The body of the loop will be executed as long as there is something to redirect from standard output to the read command.

#!/bin/bash
# This script will search for and remove spaces
# in files, replacing them with underscores
DIR="
Controlling a loop with the read command by redirecting output within the loop.
find $DIR -type f | while read file; do
# use the POSIX [:space:] class to find spaces in filenames
if [[ "$file" = *[[:space:]]* ]]; then
# replace spaces with underscores
mv "$file" `echo $file | tr ‘ ‘ ‘_’`
fi;
done

Code: Select all $ ls -1
script.sh
$ touch "file with spaces"
$ls -1
file with spaces
script.sh
$ ./script.sh
$ls -1
file_with_spaces
script.sh

13. Functions

#!/bin/bash
# Functions can be declared in any order
function function_B(
echo Function B.
}
function function_A (
echo $1
}
function function_D(
echo Function D.
}
function function_C(
echo $1
}
# Call functions
# pass the parameter to the function function A
function_A "Function A."
function_B
# pass the parameter to the function function C
function_C "Function C."
function_D

Code: Select all $ ./functions.sh
Function A.
Function B.
Function C.
Function D.

14. Selection operator - Select

#!/bin/bash
PS3=’Choose one word: ‘
#select
select word in "linux" "bash" "scripting" "tutorial"
do
echo "The word you have selected is: $word"
# Abort, otherwise the loop will be endless.
break
done
exit 0

Code: Select all $ ./select.sh
1) linux
2) bash
3) scripting
4) tutorial
Choose one word: 4
The word you have selected is: tutorial

15. Selection operator - Case

#!/bin/bash
echo "What is your preferred programming / scripting language"
echo "1) bash"
echo "2)perl"
echo "3) phyton"
echo "4) c++"
echo “5) I don’t know!”
read case;
# simple case-selection structure
# note that in this example $case is just a variable
# and doesn't have to be called that. This is just an example
case $case in
1) echo “You selected bash”;;
2) echo “You selected perl”;;
3) echo “You selected phyton”;;
4) echo “You selected c++”;;
5) exit
esac

Code: Select all $ ./case.sh
What is your preferred programming / scripting language
1) bash
2) perl
3)phyton
4) c++
5) I don't know!
4
You selected c++

———————————————————————————-

More detailed information can be obtained from various sources, for example here
original: https://www.linuxconfig.org/Bash_scripting_Tutorial
https://ruslandh.narod.ru/howto_ru/Bash-Prog-Intro/
https://bug.cf1.ru/2005-03-17/programmin … -book.html

https://ubuntologia.ru/forum/viewtopic.php?f=109&t=2296

No matter how simple the graphical interface in Linux is and no matter how many functions there are, there are still tasks that are more convenient to solve through the terminal. Firstly, because it is faster, and secondly, not all machines have a graphical interface, for example, on servers all actions are performed through the terminal in order to save computing resources.

If you are already a more experienced user, you probably often perform various tasks through the terminal. There are often tasks for which you need to run several commands in turn, for example, to update the system, you must first update the repositories, and only then download new versions of packages. This is just an example and there are a lot of such actions, even taking backup and uploading copied files to a remote server. Therefore, in order not to type the same commands several times, you can use scripts. In this article we will look at writing scripts in Bash, look at the basic operators, as well as how they work, so to speak, Bash scripts from scratch.

A script, or as it is also called, a script, is a sequence of commands that are read and executed in turn by an interpreter program, in our case it is a command line program - bash.

A script is a regular text file that lists the usual commands that we are used to entering manually, as well as the program that will execute them. The loader that will execute the script does not know how to work with environment variables, so it needs to be passed the exact path to the program that needs to be launched. And then it will transfer your script to this program and execution will begin.

A simple example of a Bash shell script:

!/bin/bash
echo "Hello world"

The echo utility displays the string passed to it as a parameter to the screen. The first line is special, it specifies the program that will execute the commands. Generally speaking, we can create a script in any other programming language and specify the desired interpreter, for example, in python:

!/usr/bin/env python
print("Hello world")

Or in PHP:

!/usr/bin/env php
echo "Hello world";

In the first case, we directly pointed to the program that will execute the commands; in the next two, we do not know the exact address of the program, so we ask the env utility to find it by name and run it. This approach is used in many scripts. But that is not all. On a Linux system, in order for the system to execute a script, you need to set the executable flag on the file with it.

This flag does not change anything in the file itself, it only tells the system that this is not just a text file, but a program and it needs to be executed, open the file, recognize the interpreter and execute it. If no interpreter is specified, the user's interpreter will be used by default. But since not everyone uses bash, you need to specify this explicitly.

To do:

chmod ugo+x script_file

Now let's run our little first program:

./script_file

Everything is working. You already know how to write a small script, say for updating. As you can see, the scripts contain the same commands that are executed in the terminal, and they are very easy to write. But now we'll complicate things a little. Since a script is a program, it needs to make some decisions on its own, store the results of command execution, and execute loops. The Bash shell allows you to do all this. True, everything is much more complicated here. Let's start with something simple.

Variables in scripts

Writing scripts in Bash is rarely complete without saving temporary data, which means creating variables. Not a single programming language can do without variables, including our primitive command shell language.

You may have come across environment variables before. So, these are the same variables and they work in the same way.

For example, let's declare a string variable:

string="Hello world"

The value of our string is in quotes. But in reality, quotation marks are not always necessary. The main principle of bash is preserved here - a space is a special character, a delimiter, so if you do not use quotes, world will already be considered a separate command, for the same reason we do not put spaces before and after the equal sign.

The $ symbol is used to display the value of a variable. For example:

Let's modify our script:

!/bin/bash
string1="hello"
string2=world
string=$string1$string2
echo $string

And we check:

Bash doesn't distinguish between variable types in the same way that high-level languages ​​like C++ do; you can assign either a number or a string to a variable. Equally, all this will be considered a string. The shell only supports string merging; to do this, simply write the variable names in a row:

!/bin/bash
string1="hello"
string2=world
string=$string1$string2\ and\ me
string3=$string1$string2" and me"
echo $string3

We check:

Please note that as I said, quotes are optional if there are no special characters in the string. Take a closer look at both methods of merging strings, they also demonstrate the role of quotes. If you need more complex string processing or arithmetic operations, this is not included in the shell's capabilities; regular utilities are used for this.

Variables and Command Output

Variables wouldn't be so useful if they couldn't store the results of running utilities. The following syntax is used for this:

$(team )

With this design, the output of the command will be redirected directly to where it was called from, rather than to the screen. For example, the date utility returns the current date. These commands are equivalent:

Do you understand? Let's write a script that displays hello world and the date:

string1="hello world"
string2=$(date)

string=$string1$string2

Now you know enough about variables that you're ready to create a bash script, but there's more to come. Next we will look at parameters and control structures. Let me remind you that these are all regular bash commands, and you don’t have to save them in a file; you can execute them right away on the fly.

Script parameters

It is not always possible to create a bash script that does not depend on user input. In most cases, you need to ask the user what action to take or what file to use. When calling a script, we can pass parameters to it. All these parameters are available as variables named as numbers.

A variable named 1 contains the value of the first parameter, variable 2 contains the value of the second, and so on. This bash script will print the value of the first parameter:

!/bin/bash
echo $1

Control constructs in scripts

Creating a bash script would not be as useful without the ability to analyze certain factors and perform the necessary actions in response to them. This is quite a complex topic, but it is very important in order to create a bash script.

In Bash, there is a command to check conditions. Its syntax is as follows:

if command_condition
then
team
else
team
fi

This command checks the exit code of the condition command, and if 0 (success) then executes the command or several commands after the word then, if the exit code is 1, the else block is executed, fi means the end of the command block.

But since we are most often interested not in the return code of a command, but in the comparison of strings and numbers, the [[ command was introduced, which allows you to perform various comparisons and issue a return code depending on the result of the comparison. Its syntax is:

[[ parameter1 operator parameter2 ]]

For comparison, we use the operators already familiar to us<,>,=,!= etc. If the expression is true, the command will return 0, if not - 1. You can test its behavior a little in the terminal. The return code of the last command is stored in the $? variable:

Now, combining all this, we get a script with a conditional expression:

!/bin/bash
if [[ $1 > 2 ]]
then
echo $1" is greater than 2"
else
echo $1" is less than 2 or 2"
fi

Of course, this design has more powerful capabilities, but it is too complex to cover them in this article. Perhaps I'll write about this later. For now, let's move on to cycles.

Loops in scripts

The advantage of the programs is that we can indicate in a few lines what actions need to be performed several times. For example, it is possible to write bash scripts that consist of only a few lines, but run for hours, analyzing parameters and performing the necessary actions.

Let's look at the for loop first. Here is its syntax:

for variable in list
do
team
done

Iterates through the entire list and assigns a value from the list to a variable one by one, after each assignment it executes the commands located between do and done.

For example, let's look at five numbers:

for index in 1 2 3 4 5
do
echo $index
done

Or you can list all files from the current directory:

for file in $(ls -l); do echo "$file"; done

As you understand, you can not only display names, but also perform the necessary actions, this is very useful when creating a bash script.

The second loop we'll look at is the while loop, which runs until the condition command returns code 0, success. Let's look at the syntax:

while command condition
do
team
done

Let's look at an example:

!/bin/bash
index=1
while [[ $index< 5 ]]
do
echo $index
let "index=index+1"
done

As you can see, everything is done, the let command simply performs the specified mathematical operation, in our case increasing the value of the variable by one.

I would like to point out one more thing. Constructs such as while, for, if are designed to be written on several lines, and if you try to write them on one line, you will get an error. But nevertheless, this is possible; to do this, put a semicolon ";" where there should be a line break. For example, the previous loop could be executed as a single line:

index=1; while [[ $index< 5 ]]; do echo $index; let "index=index+1"; done;

Everything is very simple, I tried not to complicate the article with additional terms and capabilities of bash, just the most basic things. In some cases, you may need to make a gui for a bash script, then you can use programs such as zenity or kdialog, with the help of them it is very convenient to display messages to the user and even request information from him.

conclusions

Now you understand the basics of creating a script in Linux and can write the script you need, for example, for backup. I tried to review bash scripts from scratch. Therefore, not all aspects have been considered. Perhaps we will return to this topic in one of the following articles.

Of course, all those who communicate with the Linux OS have at least once dealt (at least they have heard for sure) with the BASH command shell. But BASH is not only a command shell, it is also an excellent scripting programming language.
The purpose of this article is to introduce users better to bash, to talk about the syntax, basic techniques and features of the language, so that even an ordinary user can quickly write a simple script to perform daily (weekly, monthly) routine work or, say, “on the knee” »Create a script for backing up a directory.

Introduction

BASH - Bourne-Again SHell (which can be translated as “she reborn”, or “Bourne walked again (creator of sh)”), the most popular command interpreter on Unix-like systems, especially on GNU/Linux. Below are a number of built-in commands that we will use to create our scripts.

Break exits a for, while or until loop
continue executes the next iteration of the for, while, or until loop
echo print space-separated arguments to standard output
exit exiting the shell
export marks arguments as variables to be passed to child processes in the environment
hash remembers the full path names of commands specified as arguments so as not to look for them the next time it is accessed
kill sends a termination signal to a process
pwd prints the current working directory
read reads a string from shell input and uses it to assign values ​​to specified variables.\
return causes the shell function to exit with the specified value
shift moves positional parameters to the left
test evaluates a conditional expression
times displays the username and system time used by the shell and its children
trap specifies commands to be executed when the shell receives a signal
unset causes shell variables to be destroyed
wait waits for the child process to exit and reports the exit status.

And of course, in addition to the built-in commands, we will use a whole bunch of external, separate command programs, which we will become familiar with in the process

What you need to know from the very beginning

1. Any bash script must start with the line:

#!/bin/bash
in this line after #! the path to the bash interpreter is indicated, so if you have it installed in another place (where you can find out by typing whereis bash) change it to your path.
2. Comments begin with the # symbol (except for the first line).
3. In bash, variables do not have a type (we will discuss them below)

Variables and Script Parameters

Let me give you a small example that we will look at:

#!/bin/bash
#specify where the bash interpreter is stored
parametr1=$1 #assign variable parametr1 the value of the first parameter of the script
script_name=$0 #assign the script_name variable to the value of the script name
echo "You have launched a script with the name $script_name and the parameter $parametr1" # the echo command displays a specific line, variables are accessed through $variable_name.
echo "You ran a script with the name $script_name and the parameter $parametr1" # here we see different quotes, the difference is that in single quotes there is no variable substitution.
exit 0 #Exit with code 0 (successful completion of the script)

Ite@ite-desktop:~$ ./test.sh qwerty
You ran a script with the name ./test.sh and the qwerty parameter
You ran a script with the name $script_name and the parameter $parametr1

Now that we've learned how to use variables and pass parameters to a script, it's time to get acquainted with reserved variables:

$DIRSTACK - contents of the top of the directory stack
$EDITOR - default text editor
$EUID - Effective UID. If you used the su program to execute commands from another user, then this variable contains that user's UID, while...
$UID - ...contains the real identifier, which is set only during login.
$FUNCNAME - name of the current function in the script.
$GROUPS - an array of groups to which the current user belongs
$HOME - user's home directory
$HOSTNAME - your hostname
$HOSTTYPE - machine architecture.
$LC_CTYPE - internal variable that determines the character encoding
$OLDPWD - old working directory
$OSTYPE - OS type
$PATH - program search path
$PPID - parent process identifier
$SECONDS - script running time (in seconds)
$# - total number of parameters passed to the script
$* - all arguments are not passed to the script (output to a line)
$@ - the same as the previous one, but the parameters are displayed in a column
$! - PID of the last process running in the background
$$ - PID of the script itself

Conditions

Conditional operators, I think, are familiar to almost everyone who has ever tried to write programs on something. In bash the conditions are written as follows. way (as usual with the example):
#!/bin/bash
source=$1 #put the first parameter of the script into the source variable
dest=$2 #put the second parameter of the script into the dest variable

If [[ "$source" -eq "$dest" ]] # in quotes we indicate the names of the variables for comparison. -eq - logical comparison denoting "equal"
then # if they are really equal, then
echo "User $dest and source $source are the same file!" #display an error message, because $source and $dest are equal for us
exit 1 # exit with an error (1 - error code)
else # if they are not equal
cp $source $dest # then execute the cp command: copy the source to the destination
echo "Successful copying!"
fi #denotes the end of the condition.

Result of script execution:
ite@ite-desktop:~$ ./primer2.sh 1 1
Application 1 and source 1 are the same file!
ite@ite-desktop:~$ ./primer2.sh 1 2
Happy copying!

The if-then-else structure is used as follows:
if<команда или набор команд возвращающих код возврата(0 или 1)>
then
<если выражение после if истино, то выполняется этот блок>
else
<если выражение после if ложно, тот этот>
The structures [[ , [ , test, (()) or any other (or several) Linux commands can be used as commands returning a return code.
test - used for logical comparison. after the expression, a closing parenthesis "]" is required
[ is a synonym for the test command
[[ - extended version of "[" (since version 2.02) (as in the example), within which || can be used. (or), & (and). Must have a closing parenthesis "]]"
(()) - mathematical comparison.
to build multi-level conditions of the form:
if...
then....
else
if....
then....
else....

For brevity and readability of the code, you can use the structure:
if ..
then...
elif...
then...
elif...

Conditions. Multiple Choice

If you need to compare one variable with a large number of parameters, then it is more appropriate to use the case operator.
#!/bin/bash
echo "Select editor to launch:"
echo "1 Run nano"
echo "2 Run vi program"
echo "3 Start emacs"
echo "4 Exit"
read doing #here we read into the $doing variable from standard input

Case $doing in
1)
/usr/bin/nano # if $doing contains 1, then run nano
;;
2)
/usr/bin/vi # if $doing contains 2, then run vi
;;
3)
/usr/bin/emacs # if $doing contains 3, then run emacs
;;
4)
exit 0
;;
*) #if something is entered from the keyboard that is not described in case, do the following:
echo "Invalid action entered"

Esac #end of case statement.

Result:
ite@ite-desktop:~$ ./menu2.sh
Select editor to launch:
1 Launch nano program
2 Run vi program
3 Launch emacs
4 Exit

After selecting a number and pressing Enter, the editor that you have chosen will launch (if, of course, all the paths are specified correctly and you have these editors installed :))
I will give a list of logical operators that are used for the if-then-else-fi construction:
-z # line is empty
-n # string is not empty
=, (==) # strings are equal
!= # strings are unequal
-eq # equals
-ne # not equal
-lt,(<) # меньше
-le,(<=) # меньше или равно
-gt,(>) #more
-ge,(>=) #greater than or equal
! #negation of a logical expression
-a,(&&) #logical “AND”
-o,(||) # logical "OR"

We have dealt with the basics of the language and conditions, so as not to overload the article, I will divide it into several parts (let’s say 3). In the second part we will analyze loop operators and performing mathematical operations.

UPD: Fixed some bugs
UPD: Updated the part about if-then-else conditions

Computer