License : Creative Commons Attribution 4.0 International (CC BY-NC-SA 4.0)
Copyright : CentraleSupelec
Last modified : May 11, 2024 02:04
Link to the source : index.md

Using bash command line

Use the geek-side of the force
Use the geek-side of the force

Forewords

Launch a terminal. This is a window where a line called “the prompt” prompts you to type commands. In practice, thanks to the tab key, you can write long filenames in a few keystrokes, because tabulation allows you to complete what you are lazy enough to type. In the same way, the up and down arrows allow you to find a command you have already typed.

If you are laboriously copying text in the following exercises, it means that you have missed the use of the TAB key.

Likewise, it is not a question of issuing stupid commands. Nothing is complicated here, so you need to understand accuratly what you’re doing. Ask if you need to.

The unix copy-paste

No more CTRL-C and CTRL-V. In linux, the mouse selection (with the left button) systematically copies (no need to type CTRL-C afterwards). To paste, you have to click (left) where you want to paste (or move the cursor there if you’re on a text terminal, as in this tutorial), then click on the middle button (the scroll wheel often… or both left and right buttons simultaneously if you don’t have a middle button).

Let us start

In the console terminal, find where you are by typing ‘pwd’.

mylogin@mymachine:~$ pwd

It means Personal Working Directory. In order to see what is in there, type

mylogin@mymachine:~$ ls

Download the archive Zoo.tar.gz, be carefull that it is not decompressed by your navigator at download. Put it {at the root of your account}, i.e. your home.

Default downloads come into the Download directory (or Téléchargement for French installations). Be sure to move the archive from there to your home in that case, or to have selected “save link as” (“enregistrer la cible du lien sous” in French) by right-clicking on the link in order to choose you home as the place to download the file.

Uncompress it using the command tar, with the flags zxvf (z for unzip, x for extract, v for verbosity, f for extracting the argument given after the flags).

mylogin@mymachine:~$ tar zxvf Zoo.tar.gz

In the following, after each command execution, consider typing ls in order to see where you are, or what files have been generated (if any).

Let us now launch the command find. It explores recursively a directory. Let us introduce here the unix notation .. for the parent directory, and . for the one you are currently in. In the next example, we want to print the names of the elements explored by find, when it explores the directory Zoo that we have just get.

mylogin@mymachine:~$ find Zoo -print

Let us now “step into” the directory Zoo, i.e we change directory (cd).

mylogin@mymachine:~$ cd Zoo

… we all agree that you typed only the keys ‘c’, ‘d’, ’ ‘, ’Z’, TAB, enter-key… right ? Type…

mylogin@mymachine:~$ ls

… to see what is in there, and …

mylogin@mymachine:~$ pwd

… to check that you are actually in the Zoo directory.

Step into the Hominides directory, use TAB to avoid fastidious typings, and check (pwd) that everything is ok.

Step into the Lemuriformes directory. Do not forget that the parent directory is ... Use TAB twice if you do not understand why TAB is not able to guess what you want, the alternatives are then displayed.

Go back in Zoo. To do so, you can use ~ that is a shortcut for your home directory.

mylogin@mymachine:~$ cd ~/Zoo

Some manipulations

Let us see what the file cactus.txt contains.

mylogin@mymachine:~$ less cactus.txt

… press the key ‘q’ to exit the less command. We can get the number of words, lines of that file, thanks to the wc (word count) command.

mylogin@mymachine:~$ wc cactus.txt
mylogin@mymachine:~$ wc -l cactus.txt

The command man provides you with manual pages for a command.

mylogin@mymachine:~$ man wc

Let us delete that file (we say “remove”, i.e. rm).

mylogin@mymachine:~$ rm cactus

Let us now introduce the commands mv and cp. The call

mylogin@mymachine:~$ mv A B C D E F

moves the elements A, B, C, D and E into F, which is necessarily an existing directory.

mylogin@mymachine:~$ mv A B 

as two effects, according to what B is. If B is a directory, it moves A into that directory. If B is a name of a file (B can be a file name that do not exist yet)) it renames A, that has to be a file as well, so that it is called B now. If A is a directory, It renames A with the directory name B. Those rules make the use of mv very intuitive.

The command cp works the same, but it copies the elements rather than only moving them.

Let us move the direcrory Poules into the directory Domestiques. First, use find to scan the current directory in order to see where things are. Use TAB (sometimes twice) to build up the command. You should reach the following command (do not copy paste it, rebuild it from few key hits and TAB).

mylogin@mymachine:~$ find .
mylogin@mymachine:~$ mv Vertebres/Mammiferes/Poules/ Vertebres/Oiseaux/Domestiques/

Move cocotte.txt into Poules. Copy cocotte.txt as a new ponleuse.txt file. Rename that file pondeuse.txt. We give the answer as well, but try it on your own.

mylogin@mymachine:~$ mv Vertebres/Mammiferes/Primates/Lemuriformes/cocotte.txt Vertebres/Oiseaux/Domestiques/Poules/
mylogin@mymachine:~$ cp Vertebres/Oiseaux/Domestiques/Poules/cocotte.txt Vertebres/Oiseaux/Domestiques/Poules/ponleuse.txt
mylogin@mymachine:~$ mv Vertebres/Oiseaux/Domestiques/Poules/ponleuse.txt Vertebres/Oiseaux/Domestiques/Poules/pondeuse.txt

Once again, use TAB to write these long expressions, and type TAB twice in order to see why it refuses to complete your command line.

Go back home

mylogin@mymachine:~$ cd ~

And execute one after the others the following commands. It introduces the use of the pipe (i.e. |), that takes tou output of a command and provided it as the input of another, thus creating pipelines of commands (executed in parallel). Be sure that you get accuratly what happens for each command.

mylogin@mymachine:~$ find Zoo -name "*.txt" -print
mylogin@mymachine:~$ find Zoo -name "*.txt" -print | wc -l
mylogin@mymachine:~$ find Zoo -name "*.bad" -print
mylogin@mymachine:~$ find Zoo -name "*.bad" -exec rm \{} \; -print
mylogin@mymachine:~$ find Zoo -print

Go back home, and remove the Primates directory. In order to enable the removing of an entire directory, you will fave to use the flag -r (as recursive) with the rm command. Try without the flag, see the error, and try with the flag.

Now, step into the directory where the file chant.sh is. Let us edit this file with a basic editor.

mylogin@mymachine:~$ gedit chant.sh

Ok, we get the file content, but try to type something in your terminal. What happens ? Quit the editor from its menu (or close the window). Restart now, but add a & symbol to the command line.

mylogin@mymachine:~$ gedit chant.sh &

As you can see (and test), the terminal is available. The editor runs without blocking the command interpretor. We say that it is detached from the command line interpretor.

Let is kill the editor from the command lines. Type

mylogin@mymachine:~$ jobs

And note the number associated with the execution of gedit. Let us say that it is 73 (you have probably 1). You can kill the job gedit by:

mylogin@mymachine:~$ kill %73

In unix, files do have owners, which are gathers into groups. Users have permissions (read, write, execute) on files, depending on them being owners, or member of the same group as the owner. Try

mylogin@mymachine:~$ ls -al

Let us add the execution flag to chant.sh, and check it.

mylogin@mymachine:~$ chmod +x chant.sh
mylogin@mymachine:~$ ls -al

Let us now execute the script

mylogin@mymachine:~$ chant.sh

It didn’t work, did it ? Indeed, when you write the name of an executable file in the command, the interpreter runs it only if it lies in some determined directories. Type

mylogin@mymachine:~$ which ls

You get a path, where the executable file ls is. Executable files in that directory can be launched directly. As our current directory is not such a directory, launching directly chant.sh fails, even if it is actually a file with the executable permission on.

To solve this, we could add . into the list of the directories where commands can be found, but it is not recommended (so I do not tell you how for now). A better solution is to provide a full path to our executable file, rather than just typing it. In this case, if the file has the execution flag on, it will be executed. Here, as the file is in the current directory, the full path is ./chant.sh. Try it.

mylogin@mymachine:~$ ./chant.sh

And for this, completion with TAB works, it proposes the executable files only.

Try also

mylogin@mymachine:~$ cd ..
mylogin@mymachine:~$ Sauvages/chant.sh

Environment Variables.

To configure certain things, to set up the execution of certain programs, environment variables are available. These variables contain strings that can be read by certain programs. To illustrate the use of these variables, we introduce the command echo, that you will easily understand by typing

mylogin@mymachine:~$ echo coucou hello
mylogin@mymachine:~$ echo "coucou\nhello"
mylogin@mymachine:~$ echo -e "coucou\nhello"

Now that we know how to use echo, let us define an environment variable.

mylogin@mymachine:~$ export TOTO=dir
export TITI=file

We can use it by using the $ symbol.

mylogin@mymachine:~$ echo TOTO
mylogin@mymachine:~$ echo $TOTO
mylogin@mymachine:~$ echo $TOTO/$TITI
mylogin@mymachine:~$ echo $HOME
mylogin@mymachine:~$ cd $HOME

You can list all the currently defined environment variables by

mylogin@mymachine:~$ env

and you can select some of them by a pipeline to a the grep command. grep toto file outputs the lines of file that contain the sequence toto. The command grep is thus very usefull to filter the output of very verbose commands. Let us display the environement variables containing the word PATH:

mylogin@mymachine:~$ env | grep PATH

Finally, if you want these variables to be set each time you launch a terminal, you need to write the commands export ...=... in the file ~/.bashrc. If you ever have a file definitions.config where there are environment variable definitions, and you want the shell to read it to define the variables in it (to execute the exports), you can type:

mylogin@mymachine:~$ source definitions.config