Linux Basics: Introduction to bash
What is the article about?
After reading this article, you will learn what bash is (standard Linux command interpreter), learn how to deal with standard commands: ls, cp, mv … understand the purpose of inodes, hard and symbolic links and much more.
This guide is intended for beginners in Linux and for those who want to repeat or improve understanding of the basic principles of Linux, such as copying and moving files, creating links, using standard Linux commands along with redirections and pipes. In this article you will find many examples explaining the material presented. For beginners, most of the information will be new, and for more advanced users, this material can be an excellent tool for generalizing existing knowledge and skills.
Introduction to bash
If you use Linux, then you know that after login you are welcomed by an invitation from the command interpreter. For example:
If a graphical shell is loaded after login, then to get to the command interpreter, you need to start the terminal emulator (gnome-terminal, xfce4-terminal, konsole, xterm, rxvt …) or switch to one of the virtual terminals by pressing Ctrl – Alt – F1 or Ctrl – Alt – F2 , etc.
The command prompt on your computer may differ from what is shown in the example. It may contain the user name, the computer name and the name of the current working directory. But despite all these differences, the program that prints this invitation is called a “ shell ” (shell), and most likely in the role of your command shell is a program called bash .
Are you running bash?
You can check whether bash is running with the following command:
\$ echo \$SHELL /bin/bash
If as a result of executing this command you received an error or its output differs from that in the example, then it is possible that your system does not use bash as the command shell. Despite this, most of the material will be relevant, but still, recommend that you switch to bash. This can be done (if bash is installed in the system) with the command:
What is bash
Bash (acronym for « Bed and ourne- a GAIN SH ell») is the standard command interpreter on most Linux systems. His responsibilities include the processing and execution of commands with which the user controls the computer. After you have completed your work, you can complete the shell process. After pressing the Ctrl – D keys , the exit or logout commands will finish the command interpreter process and the screen will again prompt you to enter your username and password.
Let’s start using bash to navigate the file system. To get started, type the following command:
$ cd /
With this command, we specified bash that we want to move to the root directory – / . All directories in the system are organized in a tree structure and / this is its beginning (or root). The cd command is used to change the current working directory.
To find out where in the file system you are currently located (current working directory) type:
\$ pwd /
In the example above, the / – command argument cd – is called a path . This is the place of the file system where we want to move. In this case, / is an absolute path, which means that the path is relative to the root directory.
Here are some examples of absolute paths.
/dev /usr /usr/bin /usr/local/bin
As you may have noticed, all these paths are united by the fact that they begin with / . Specifying the path / usr / local / bin as an argument to the cd command, we tell it to go to the root directory / , then to the usr directory, then to local and bin. Absolute paths always begin with /
The second kind of path is called a relative. Bash, cd command, and other commands count these paths relative to the current directory. Relative paths never begin with/. For example, if we are in /usr
\$ cd /usr
Then we can go to / usr / local / bin using the relative path
\$ cd local/bin \$ pwd /usr/local/bin
Relative paths may contain one or several “..” directories . “..” indicates the parent directory in relation to our working directory. Example:
\$ pwd /usr/local/bin \$ cd .. \$ pwd /usr/local
As you can see, the cd command .. ‘raises us to a higher level’.
You can add .. to the relative path. This will allow you to move to a directory that is on the same level as the one we are in. Example:
\$ pwd /usr/local \$ cd ../share \$ pwd /usr/share
Examples using relative paths
Relative paths can be quite complex. Here are some examples. The result of the commands is not shown, try to determine in which directory you will be using bash.
\$ cd /bin \$ cd ../usr/share/zoneinfo \$ cd /usr/X11R6/bin \$ cd ../lib/X11 \$ cd /usr/bin \$ cd ../bin/../bin
Working directory “.”
Before you finish talking about the cd command, a few more things should be mentioned. First, there is another special directory “.” , Which points to the current directory. This directory is used to run executable files located in the current directory.
In the last example, myprog is an executable file located in the current directory that will be launched for execution.
cd and user’s home directory
In order to go to the home directory, you need to type
Without the cd argument, move you to your home directory. For the superuser, the home directory is usually / root, and for ordinary users, /home/username/. But what if we want to specify a specific file located in the home directory. For example, as an argument to the program ‘myprog’? You can write:
\$ ./myprog /home/user/myfile.txt
However, using absolute file paths is not always convenient. The same operation can be done with the help of the ~ –type:
\$ ./myprog ~/myfile.txt
~ Is a special name that indicates in bash the user’s home directory.
Home directories of other users
But what if we need to specify a file in another user’s home directory? To do this, after the tilde you need to specify the name of this user. For example, to point to the fredsfile.txt file located in the home directory of the user fred:
\$ ./myprog ~fred/fredsfile.txt
Introduction to ls
Probably you are already familiar with the ls command , which, invoked without arguments, displays a list of files stored in the working directory:
\$ ls -a . bin gentoo-x86 include libexec portage share tmp .. distfiles i686-linux info local portage.old src X11R6 doc i686-pc-linux-gnu lib man sbin ssl
If you specify the -a option, you will see all files, including hidden files (whose names begin with a dot).
\$ ls -a . bin gentoo-x86 include libexec portage share tmp .. distfiles i686-linux info local portage.old src X11R6 doc i686-pc-linux-gnu lib man sbin ssl
Detailed directory listing
After the ls command itself, you can specify one or more files or directories as its argument. If you specify a file name, the ls command will display information only about this file. And if you specify the name of the directory, ls will show all its contents. The option ‘-l’ command ls can be very useful if you want to except the file name to find out more information about them (the rights to the file, the owner name, file modification time and size).
The following example shows the use of the ‘-l’ option to display information about the files stored in the / usr directory
\$ ls -l /usr drwxr-xr-x 7 root root 168 Nov 24 14:02 X11R6 drwxr-xr-x 2 root root 14576 Dec 27 08:56 bin drwxr-xr-x 2 root root 8856 Dec 26 12:47 distfiles lrwxrwxrwx 1 root root 9 Dec 22 20:57 doc -> share/doc drwxr-xr-x 62 root root 1856 Dec 27 15:54 gentoo-x86 drwxr-xr-x 4 root root 152 Dec 12 23:10 i686-linux drwxr-xr-x 4 root root 96 Nov 24 13:17 i686-pc-linux-gnu drwxr-xr-x 54 root root 5992 Dec 24 22:30 include lrwxrwxrwx 1 root root 10 Dec 22 20:57 info -> share/info drwxr-xr-x 28 root root 13552 Dec 26 00:31 lib drwxr-xr-x 3 root root 72 Nov 25 00:34 libexec drwxr-xr-x 8 root root 240 Dec 22 20:57 local lrwxrwxrwx 1 root root 9 Dec 22 20:57 man -> share/man lrwxrwxrwx 1 root root 11 Dec 8 07:59 portage -> gentoo-x86/ drwxr-xr-x 60 root root 1864 Dec 8 07:55 portage.old drwxr-xr-x 3 root root 3096 Dec 22 20:57 sbin drwxr-xr-x 46 root root 1144 Dec 24 15:32 share drwxr-xr-x 8 root root 328 Dec 26 00:07 src drwxr-xr-x 6 root root 176 Nov 24 14:25 ssl lrwxrwxrwx 1 root root 10 Dec 22 20:57 tmp -> ../var/tmp
The first column shows the access information for each file in the list. (I will explain a little later what letter means). The next column shows the number of links to each item in the list. The third and fourth columns are the owner and group of the file, respectively. The fifth column is the size. The sixth is the last file modification time (‘last modified time’ or mtime). The last column is the name of the file or directory (If this is a link, then after the ‘ -> ‘ sign stands the name of the object it refers to).
How to view directories only
Sometimes there is a need to look at information only about directories, and not about all their contents. The ‘-d’ option will help with this task, which tells the command to output information only about directories. Example:
\$ ls -dl /usr /usr/bin /usr/X11R6/bin ../share drwxr-xr-x 4 root root 96 Dec 18 18:17 ../share drwxr-xr-x 17 root root 576 Dec 24 09:03 /usr drwxr-xr-x 2 root root 3192 Dec 26 12:52 /usr/X11R6/bin drwxr-xr-x 2 root root 14576 Dec 27 08:56 /usr/bin
Recursive list and inode information
The effect of the -R option is the opposite of the -d action . It allows you to display information about files located in the directory recursively. First, the contents of the top-level directory are displayed, then the contents of all subdirectories are listed in turn, and so on. The output of this command can be quite lengthy, so we do not give it an example, but you can try to do it yourself by typing ‘ ls -R ‘ or ‘ ls -Rl ‘ on the command line .
And finally, the option ‘-i’ is used to display inodes of each file system object.
\$ ls -i /usr 1409 X11R6 314258 i686-linux 43090 libexec 13394 sbin 1417 bin 1513 i686-pc-linux-gnu 5120 local 13408 share 8316 distfiles 1517 include 776 man 23779 src 43 doc 1386 info 93892 portage 36737 ssl 70744 gentoo-x86 1585 lib 5132 portage.old 784 tmp
What are inodes?
Each file system object (file, directory …) has its own unique number, called inode (inode number). This information may seem insignificant, but understanding the function of inodes will help you to understand many of the operations on the file system. For example, let’s look at “.” And “..” as links that are present in each directory. To understand what the “..” directory is, we find out the inode of the / use / local directory
\$ ls -id /usr/local 5120 /usr/local
As we can see, the inode of the / usr / local directory is 5120. Now let’s see which inode of the / usr / local / bin / .. directory:
\$ ls -id /usr/local/bin/.. 5120 /usr/local/bin/..
It turns out that the inodes of the / usr / local and / usr / local / bin / .. directories are the same! This means that two names refer to the inode 5120: / usr / local and / usr / local / bin / .. That is, these are two different names for the same directory. Each inode points to a specific disk space.
Each inode can have several names of file system objects. The number of file ‘synonyms’ (file system objects referring to one inode) indicates the number in the second column of the output of the ‘ ls -l ‘ command.
\$ ls -dl /usr/local drwxr-xr-x 8 root root 240 Dec 22 20:57 /usr/local
This example shows (the second column) that the directory / usr / local is referenced by 8 different filesystem objects. Here are their names:
/usr/local /usr/local/. /usr/local/bin/.. /usr/local/games/.. /usr/local/lib/.. /usr/local/sbin/.. /usr/local/share/.. /usr/local/src/..
Let’s look at the mkdir command. It serves to create new directories. The following example shows how to create three new directories (tic, tac, toe) in the / tmp directory
\$ cd /tmp $ mkdir tic tac toe
By default, the mkdir command cannot create a nested directory structure. Therefore, if you need to create several directories nested within one another ( won / der / ful ), then you will have to call this command three times in turn:
\$ mkdir won/der/ful mkdir: cannot create directory 'won/der/ful': No such file or directory \$ mkdir won \$ mkdir won/der \$ mkdir won/der/ful
You can simplify this operation by adding the `-p ‘ option to the mkdir command. This option allows you to create a nested directory structure:
\$ mkdir -p easy/as/pie
To learn more about the capabilities of this utility, read the help file that is invoked by the man mkdir command. There are references to almost all commands from this manual (for example, man ls ), except cd, since it is built into bash (for such commands, help is called like this: help cd )
Let’s move on to learning the cp and mv commands used to copy, rename and move files and directories. But before that, create an empty file in the / tmp directory using the touch command :
\$ cd /tmp \$ touch copyme
The touch command updates the time of the last access to the file (the sixth column of the output of the ls -l command ) if it already exists or creates a new empty file if it does not already exist. After this operation, we should have an empty file / tmp / copyme .
Now that we have an empty file, we write the text string into it using the echo command , which outputs the argument passed to it to the standard output device (the text terminal in our case).
\$ echo "firstfile" firstfile
To write a line to our file, redirect the echo command output to it :
\$ echo "firstfile" > copyme
The > (more) sign tells the shell to redirect the output of the command on the left to the file whose name is on the right. If a file with this name does not exist, it will be created automatically. And if there is already such a file, it will be overwritten (all its contents will be erased before writing our line). The command ‘ls -l’ will show that our file size is now 10 bytes – nine bytes are occupied by the word ‘firstfile’ and one byte is a newline character.
\$ ls -l copyme -rw-r--r-- 1 root root 10 Dec 28 14:13 copyme
cat and cp
To output the contents of the file to the terminal, use the cat command :
\$ cat copyme firstfile
Now we can begin to analyze the basic functionality of the cp command . This command takes two arguments. The first is the name of an existing file (‘copyme’), the second is the name of the new copy that we want to make (‘copiedme’).
\$ cp copyme copiedme
We can make sure that the new copy of the file has a different inode number (this means that we received a really new separate file, and not just a link to the old one)
\$ ls -i copyme copiedme 648284 copiedme 650704 copyme
Now use the mv command to rename the file (“copiedme” -> “movedme”). The inode number after this operation does not change, only the file name is changed.
\$ mv copiedme movedme \$ ls -i movedme 648284 movedme
The inode number does not change only provided that the renamed file remains within the file system where the source file was located. We will take a closer look at the file system layout in one of the following parts of this tutorial.
The mv command allows you not only to rename files, but also to move them. For example, to move the /var/tmp/myfile.txt file to the / home / user directory, the following command should be given:
\$ mv /var/tmp/myfile.txt /home/user
The file will be moved to the user’s home directory user , even if it is in another file system (in this case, the file will be copied to the new location and then the original will be deleted). As you might have guessed, moving a file to another file system causes its inode to change. This is because each file system has its own separate set of inodes.It should be noted that there is a possibility that the newly assigned inode number may coincide with the old one, but it is extremely small.
To move several files to one directory at the same time you need to write:
\$ mv /var/tmp/myfile1.txt /var/tmp/myfile2.txt /home/user
\$ mv -t /home/user /var/tmp/myfile1.txt /var/tmp/myfile2.txt
If you add the option ‘-v’, the report on the operation performed will be displayed:
\$ mv -vt /home/user /var/tmp/myfile1.txt /var/tmp/myfile2.txt '/var/tmp/myfile1.txt' -> '/home/user/myfile1.txt' '/var/tmp/myfile2.txt' -> '/home/user/myfile2.txt'