Today we will talk about bash scripts. This - command line scripts, written for the bash shell. There are other shells, such as zsh, tcsh, ksh, but we will focus on bash. This material is intended for everyone, the only condition is the ability to work in command line Linux.
Command line scripts are sets of the same commands that can be entered from the keyboard, collected in files and united by some common purpose. At the same time, the results of the teams' work can either be of independent value or serve as input for other teams. Scripts are a powerful way to automate frequently performed actions.
So, if we talk about the command line, it allows you to execute several commands at once, entering them with a semicolon:
pwd ; whoami
In fact, if you've tried this in your terminal, your first bash script that uses two commands has already been written. It works like this. Team first pwd displays information about the current working directory, then the command whoamishows information about the user you are logged in as.
Using this approach, you can combine as many commands as you want on one line, the limit is only the maximum number of arguments that can be passed to the program. You can define this limit with the following command:
getconf ARG_MAX
The command line is a great tool, but you have to enter commands into it every time you need them. What if we write a set of commands to a file and simply call that file to execute them? In fact, the file we are talking about is called the command line script.
How bash scripts work
Create an empty file using the command touch. In its first line, you need to specify which shell we are going to use. We are interested in bash, so the first line of the file would be:
#!/bin/bash
Elsewhere in this file, the hash symbol is used to indicate comments that the shell does not process. However, the first line is a special case, it is a pound sign followed by an exclamation point (this sequence is called shebang) and the path to bash, indicate to the system that the script was created specifically for bash.
Shell commands are separated by a line feed, comments are separated by a pound sign. Here's what it looks like:
#!/bin/bash
# This is a comment
pwd
whoami
Here, just like on the command line, you can write commands on one line, separating them with a semicolon. However, if you write commands on different lines, the file is easier to read. In any case, the shell will process them.
Setting Permissions on a Script File
Save the file by giving it a name myscript, and the bash script is almost done. Now it remains only to make this file executable, otherwise, when you try to run it, you will encounter an error Permission denied.
Attempting to run a script file with incorrectly configured permissions
Let's make the file executable:
chmod +x ./myscript
Now let's try to execute it:
./myscript
After setting the permissions, everything works as it should.
Successfully run bash script
Message output
To print text to the Linux console, use the command echo. Let's use the knowledge of this fact and edit our script, adding explanations to the data that output the commands already in it:
#!/bin/bash
# our comment is here
echo "The current directory is:"
pwd
echo "The user logged in is:"
whoami
Here's what happens after running the updated script.
Outputting messages from a script
Now we can display explanatory labels using the command echo. If you don't know how to edit a file using Linux tools, or if you haven't seen the command before echo, take a look at this material.
Using Variables
Variables allow you to store information in a script file, such as the results of commands, for use by other commands.
There is nothing wrong with executing individual commands without storing the results of their work, but the possibilities of this approach are very limited.
There are two types of variables that can be used in bash scripts:
Environment Variables
User variables
Environment Variables
Sometimes shell commands need to work with some system data. For example, here's how to display the current user's home directory:
#!/bin/bash
# display user home
echo "Home for the current user is: $HOME"
Please note that we can use the system variable $HOME in double quotes, this will not prevent the system from recognizing it. Here's what happens if you run the above script.
Using an Environment Variable in a Script
But what if you want to display a dollar sign? Let's try this:
echo "I have $1 in my pocket"
The system will detect a dollar sign in a string delimited by quotes and assume that we have referenced a variable. The script will try to display the value of an undefined variable. $1. This is not what we need. What to do?
In a situation like this, using the backslash control character before the dollar sign helps:
echo "I have $1 in my pocket"
The script will now output exactly what is expected.
Using an Escape Sequence to Output a Dollar Sign
User variables
In addition to environment variables, bash scripts allow you to set and use your own variables in the script. Such variables hold a value until the script ends.
As with system variables, user variables can be accessed using the dollar sign:
TNW-CUS-FMP - promo code for a 10% discount on our services, available for activation within 7 days
#!/bin/bash
# testing variables
grade=5
person="Adam"
echo "$person is a good boy, he is in grade $grade"
Here is what happens after running such a script.
Custom Variables in Script
Command substitution
One of the most useful features of bash scripts is the ability to extract information from the output of commands and assign it to variables, which allows you to use this information anywhere in the script file.
This can be done in two ways.
With the backtick character "`"
With the help of construction $()
When using the first approach, be careful not to use a single quote instead of a backtick. The command must be enclosed in two such icons:
mydir=`pwd`
In the second approach, the same is written like this:
mydir=$(pwd)
And the script, in the end, might look like this:
#!/bin/bash
mydir=$(pwd)
echo $mydir
During its operation, the output of the command pwdwill be stored in a variable mydir, the contents of which, using the command echo, will go to the console.
Script that saves the results of the command in a variable
Mathematical operations
To perform mathematical operations in a script file, you can use a construction of the form $((a+b)):
In some scenarios, it is required to control the flow of command execution. For example, if a certain value is greater than five, one action must be performed, otherwise another. This is applicable in very many situations, and here the control structure will help us if-then. In its simplest form, it looks like this:
if ΠΊΠΎΠΌΠ°Π½Π΄Π°
then
ΠΊΠΎΠΌΠ°Π½Π΄Ρ
fi
And here is a working example:
#!/bin/bash
if pwd
then
echo "It works"
fi
In this case, if the execution of the command pwdcompletes successfully, the text "it works" will be displayed in the console.
Let's use the knowledge we have and write a more complex scenario. Let's say we need to find a user in /etc/passwd, and if it was found, report that it exists.
#!/bin/bash
user=likegeeks
if grep $user /etc/passwd
then
echo "The user $user Exists"
fi
This is what happens after running this script.
User search
Here we have used the command grepto search for a user in a file /etc/passwd. If the team grepunfamiliar to you, its description can be found here.
In this example, if the user is found, the script will display an appropriate message. What if the user could not be found? In this case, the script will simply complete the execution without telling us anything. I would like him to tell us about this as well, so let's improve the code.
The if-then-else control construct
In order for the program to be able to report both the results of a successful search and a failure, we use the construction if-then-else. Here's how it's set up:
if ΠΊΠΎΠΌΠ°Π½Π΄Π°
then
ΠΊΠΎΠΌΠ°Π½Π΄Ρ
else
ΠΊΠΎΠΌΠ°Π½Π΄Ρ
fi
If the first command returns zero, which means it was successfully executed, the condition will be true and the execution will not go along the branch else. Otherwise, if something other than zero is returned, which means failure, or a false result, the commands after else.
Let's write the following script:
#!/bin/bash
user=anotherUser
if grep $user /etc/passwd
then
echo "The user $user Exists"
else
echo "The user $user doesnβt exist"
fi
His execution went down the line else.
Running a script with an if-then-else construct
Well, let's move on and ask ourselves about more difficult conditions. What if you need to check not one condition, but several? For example, if the required user is found, one message should be displayed, if some other condition is met, another message should be displayed, and so on. In such a situation, nested conditions will help us. It looks like this:
if ΠΊΠΎΠΌΠ°Π½Π΄Π°1
then
ΠΊΠΎΠΌΠ°Π½Π΄Ρ
elif ΠΊΠΎΠΌΠ°Π½Π΄Π°2
then
ΠΊΠΎΠΌΠ°Π½Π΄Ρ
fi
If the first command returns zero, which indicates its successful execution, the commands in the first block will be executed then, otherwise, if the first condition is false, and if the second command returns zero, the second block of code will be executed.
#!/bin/bash
user=anotherUser
if grep $user /etc/passwd
then
echo "The user $user Exists"
elif ls /home
then
echo "The user doesnβt exist but anyway there is a directory under /home"
fi
In such a script, you can, for example, create a new user using the command useradd, if the search returned no results, or do something else useful.
Number Comparison
In scripts, you can compare numeric values. Below is a list of relevant commands.
n1 -eq n2Returns true if n1 equally n2. n1 -ge n2 Returns true if n1more or equal n2. n1 -gt n2Returns true if n1 more n2. n1 -le n2Returns true if n1less or equal n2. n1 -lt n2Returns true if n1 is less than n2. n1 -ne n2Returns true if n1not equal n2.
As an example, let's try one of the comparison operators. Note that the expression is enclosed in square brackets.
#!/bin/bash
val1=6
if [ $val1 -gt 5 ]
then
echo "The test value $val1 is greater than 5"
else
echo "The test value $val1 is not greater than 5"
fi
Here is what this command will output.
Comparing numbers in scripts
Variable value val1greater than 5, eventually the branch is executed thencomparison operator and the corresponding message is displayed in the console.
String comparison
Scripts can also compare string values. Comparison operators look quite simple, but string comparison operators have certain peculiarities, which we will touch on below. Here is a list of operators.
str1 = str2 Tests strings for equality, returns true if strings are identical.
str1 != str2Returns true if the strings are not identical. str1 < str2Returns true if str1less than str2. str1 > str2 Returns true if str1more than str2. -n str1 Returns true if length str1Above zero. -z str1Returns true if length str1is zero.
Here is an example of a string comparison in a script:
#!/bin/bash
user ="likegeeks"
if [$user = $USER]
then
echo "The user $user is the current logged in user"
fi
As a result of the script execution, we get the following.
String Comparison in Scripts
Here is one feature of string comparison that is worth mentioning. Namely, the ">" and "<" operators must be escaped with a backslash, otherwise the script will not work correctly, although no error messages will appear. The script interprets the ">" sign as a command to redirect output.
Here is how working with these operators looks in code:
#!/bin/bash
val1=text
val2="another text"
if [ $val1 > $val2 ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi
Here are the results of the script.
String comparison, warning thrown
Note that the script, although it is executing, gives a warning:
./myscript: line 5: [: too many arguments
To get rid of this warning, we conclude $val2 in double quotes:
#!/bin/bash
val1=text
val2="another text"
if [ $val1 > "$val2" ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi
Now everything works as it should.
String comparison
Another feature of the ">" and "<" operators is how they work with uppercase and lowercase characters. In order to understand this feature, let's prepare a text file with the following content:
Likegeeks
likegeeks
Save it with a name myfileand then run the following command in the terminal:
sort myfile
It will sort the lines from the file like this:
likegeeks
Likegeeks
Team sort, by default, sorts strings in ascending order, meaning the lowercase letter in our example is less than the uppercase letter. Now let's prepare a script that will compare the same strings:
#!/bin/bash
val1=Likegeeks
val2=likegeeks
if [ $val1 > $val2 ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi
If you run it, it turns out that the opposite is true - the lowercase letter is now larger than the uppercase one.
sort command and string comparison in script file
In comparison commands, uppercase letters are smaller than lowercase letters. String comparison here is done by comparing the ASCII character codes, the sort order is thus dependent on the character codes.
Team sort, in turn, uses the sort order specified in the system language settings.
File checks
Perhaps the commands below are used most often in bash scripts. They allow you to check various conditions regarding files. Here is a list of these commands.
-d fileChecks if a file exists and if it is a directory. -e fileChecks if a file exists. -f file Checks if a file exists and if it is a file. -r fileChecks if the file exists and is readable. -s file ΠChecks if the file exists and is not empty. -w fileChecks if the file exists and is writable. -x fileChecks if a file exists and is executable. file1 -nt file2 Checks if it's newer file1Than file2. file1 -ot file2Checks if older file1Than file2. -O file Checks if the file exists and is owned by the current user. -G fileChecks if the file exists and if its group ID matches the current user's group ID.
These commands, as well as many others discussed today, are easy to remember. Their names, being abbreviations for various words, directly indicate the checks they perform.
Let's try one of the commands in practice:
#!/bin/bash
mydir=/home/likegeeks
if [ -d $mydir ]
then
echo "The $mydir directory exists"
cd $ mydir
ls
else
echo "The $mydir directory does not exist"
fi
This script, for an existing directory, will display its contents.
Listing the contents of a directory
We believe that you can experiment with the rest of the commands on your own, they all apply according to the same principle.
Results
Today we talked about how to get started writing bash scripts and covered some basic things. In fact, the topic of bash programming is huge. This article is a translation of the first part of a large series of 11 materials. If you want to continue right now, here is a list of the originals of these materials. For convenience, the one whose translation you have just read is included here.
Bash Script Step By Step - here we are talking about how to start creating bash scripts, the use of variables is considered, conditional constructions, calculations, comparisons of numbers, strings, finding out information about files are described.
Bash Scripting Part 3, Parameters & options - this material is devoted to command line parameters and keys that can be passed to scripts, working with data that the user enters and that can be read from files.
Bash Scripting Part 4, Input & Output - here we are talking about file descriptors and working with them, about input, output, errors, output redirection streams.
Bash Scripting Part 11, Expect Command - this material is dedicated to the Expect tool, with which you can automate interaction with interactive utilities. In particular, this is about expect scripts and how they interact with bash scripts and other programs.
We think that one of the great things about this series of articles is that it starts from the most basic, suitable for users of any level, gradually leads to quite serious topics, giving everyone a chance to advance in Linux command line scripting.
Dear readers! We ask bash-programming gurus to talk about how they got to the heights of mastery, share secrets, and we are waiting for impressions from those who have just written their first script.
Only registered users can participate in the survey. Sign in, you are welcome.