Terminal (1/3): navigation, files and commands

Terminal (1/3): navigation, files and commands

Disclaimer: This post has been translated to English using a machine translation model. Please, let me know if you find any mistakes.

πŸ“š **This post is part of the _Introduction to the terminal_ series**, divided into three chapters that should be read in order:

> * πŸ‘‰ **Part 1: Navigation, files and commands**

* Part 2: Network, compression and processes

* Part 3: System administration

Post formatlink image 68

To avoid having to keep putting console screenshots in every action I take, I have created the following function that receives the terminal command we want to execute and returns the output that the terminal would give us.

Sometimes I will use this function, and other times I will use ! before each command, which in notebooks means you are going to execute a terminal command.

	
< > Input
Python
import subprocess
import os
last_directory = ''
def terminal(command, max_lines_output=None):
global last_directory
debug = False
str = command.split()
# Check if there are " or ' characters
for i in range(len(str)):
if debug: print(f"i = {i}, str[i] = {str[i]}")
if len(str[i]) &gt; 0:
if str[i][0] == '"' or str[i][0] == "'":
for j in range(i+1,len(str)):
if debug: print(f" j = {j}, str[j] = {str[j]}")
if str[j][-1] == '"' or str[j][-1] == "'":
for k in range(i+1,j+1):
if debug: print(f" k = {k}, str[i] = {str[i]}, str[k] = {str[k]}")
str[i] = str[i] + " " + str[k]
if debug: print(f" k = {k}, str[i] = {str[i]}, str[k] = {str[k]}")
str[j:] = [""]
str[i] = str[i].replace('"','')
# Remove empty strings
str = [x for x in str if x != ""]
if debug:
print(str)
return
if str[0] == "cd":
last_dir = os.getcwd()
if len(str) == 1:
os.chdir('/home/wallabot')
else:
if str[1] == "-":
os.chdir(last_directory)
else:
os.chdir(str[1])
last_directory = last_dir
else:
result = subprocess.run(str, stdout=subprocess.PIPE).stdout.decode('utf-8')
if max_lines_output is not None:
result_split = result.split(' ')
print(' '.join(result_split[:max_lines_output]))
print(" ...")
print(' '.join(result_split[-5:]))
else:
print(result)
Copied

First commands to move around the terminallink image 69

ls (listar directorio)link image 70

The first command we are going to see is ls (list directory), which is used to list all the files in the folder we are in.

	
< > Input
Python
terminal("ls")
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
2021-04-23-Calculo-matricial-con-Numpy.ipynb
2021-06-15-Manejo-de-datos-con-Pandas.ipynb
2022-09-12 Introduccion a la terminal.ipynb
2022-09-12 Introduccion a la terminal.txt
command-line-cheat-sheet.pdf
CSS.ipynb
Docker.html
Docker.ipynb
Expresiones regulares.html
Expresiones regulares.ipynb
html_files
html.ipynb
introduccion_python
movies.csv
movies.dat
notebooks_translated
__pycache__
ssh.ipynb
test.html
test.ipynb

Commands can normally receive options (flags), which are introduced with the character -, for example, let's look at ls -l, which returns the list of files in the directory we are in, but with more information

	
< > Input
Python
terminal('ls -l')
Copied
>_ Output
			
total 4512
-rw-rw-r-- 1 wallabot wallabot 285898 nov 12 02:07 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 78450 nov 13 00:10 2021-04-23-Calculo-matricial-con-Numpy.ipynb
-rw-rw-r-- 1 wallabot wallabot 484213 nov 13 00:44 2021-06-15-Manejo-de-datos-con-Pandas.ipynb
-rw-rw-r-- 1 wallabot wallabot 320810 dic 6 00:11 2022-09-12 Introduccion a la terminal.ipynb
-rw-rw-r-- 1 wallabot wallabot 320594 dic 6 00:04 2022-09-12 Introduccion a la terminal.txt
-rw-rw-r-- 1 wallabot wallabot 119471 oct 3 16:13 command-line-cheat-sheet.pdf
-rw-rw-r-- 1 wallabot wallabot 2660 sep 18 03:32 CSS.ipynb
-rw-rw-r-- 1 wallabot wallabot 699225 nov 27 04:16 Docker.html
-rw-rw-r-- 1 wallabot wallabot 509125 sep 22 16:48 Docker.ipynb
-rw-rw-r-- 1 wallabot wallabot 156193 nov 27 04:21 Expresiones regulares.html
-rw-rw-r-- 1 wallabot wallabot 53094 oct 2 04:57 Expresiones regulares.ipynb
drwxrwxr-x 2 wallabot wallabot 4096 nov 28 14:39 html_files
-rw-rw-r-- 1 wallabot wallabot 14775 sep 18 03:29 html.ipynb
drwxrwxr-x 3 wallabot wallabot 4096 nov 12 01:51 introduccion_python
-rw-rw-r-- 1 wallabot wallabot 446172 oct 2 04:39 movies.csv
-rw-rw-r-- 1 wallabot wallabot 522197 oct 2 04:33 movies.dat
drwxrwxr-x 2 wallabot wallabot 4096 nov 28 14:39 notebooks_translated
drwxrwxr-x 2 wallabot wallabot 4096 ago 27 03:25 __pycache__
-rw-rw-r-- 1 wallabot wallabot 586 dic 4 02:31 ssh.ipynb
-rw-rw-r-- 1 wallabot wallabot 292936 nov 9 01:46 test.html
-rw-rw-r-- 1 wallabot wallabot 260227 nov 9 01:13 test.ipynb

As we can see, we have how many bytes each file occupies, but when we have files that take up a lot of space, this is not very easy to read, so we can add the h (human) option, which gives us information that is easier to read

	
< > Input
Python
terminal('ls -lh')
Copied
>_ Output
			
total 4,5M
-rw-rw-r-- 1 wallabot wallabot 280K nov 12 02:07 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 77K nov 13 00:10 2021-04-23-Calculo-matricial-con-Numpy.ipynb
-rw-rw-r-- 1 wallabot wallabot 473K nov 13 00:44 2021-06-15-Manejo-de-datos-con-Pandas.ipynb
-rw-rw-r-- 1 wallabot wallabot 314K dic 6 00:11 2022-09-12 Introduccion a la terminal.ipynb
-rw-rw-r-- 1 wallabot wallabot 314K dic 6 00:04 2022-09-12 Introduccion a la terminal.txt
-rw-rw-r-- 1 wallabot wallabot 117K oct 3 16:13 command-line-cheat-sheet.pdf
-rw-rw-r-- 1 wallabot wallabot 2,6K sep 18 03:32 CSS.ipynb
-rw-rw-r-- 1 wallabot wallabot 683K nov 27 04:16 Docker.html
-rw-rw-r-- 1 wallabot wallabot 498K sep 22 16:48 Docker.ipynb
-rw-rw-r-- 1 wallabot wallabot 153K nov 27 04:21 Expresiones regulares.html
-rw-rw-r-- 1 wallabot wallabot 52K oct 2 04:57 Expresiones regulares.ipynb
drwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 html_files
-rw-rw-r-- 1 wallabot wallabot 15K sep 18 03:29 html.ipynb
drwxrwxr-x 3 wallabot wallabot 4,0K nov 12 01:51 introduccion_python
-rw-rw-r-- 1 wallabot wallabot 436K oct 2 04:39 movies.csv
-rw-rw-r-- 1 wallabot wallabot 510K oct 2 04:33 movies.dat
drwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 notebooks_translated
drwxrwxr-x 2 wallabot wallabot 4,0K ago 27 03:25 __pycache__
-rw-rw-r-- 1 wallabot wallabot 586 dic 4 02:31 ssh.ipynb
-rw-rw-r-- 1 wallabot wallabot 287K nov 9 01:46 test.html
-rw-rw-r-- 1 wallabot wallabot 255K nov 9 01:13 test.ipynb

If we want to see hidden files, we can use the a option, which will show us all the files in a directory.

	
< > Input
Python
terminal('ls -lha')
Copied
>_ Output
			
total 4,5M
drwxrwxr-x 6 wallabot wallabot 4,0K dic 6 00:04 .
drwxrwxr-x 5 wallabot wallabot 4,0K oct 2 03:10 ..
-rw-rw-r-- 1 wallabot wallabot 280K nov 12 02:07 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 77K nov 13 00:10 2021-04-23-Calculo-matricial-con-Numpy.ipynb
-rw-rw-r-- 1 wallabot wallabot 473K nov 13 00:44 2021-06-15-Manejo-de-datos-con-Pandas.ipynb
-rw-rw-r-- 1 wallabot wallabot 314K dic 6 00:11 2022-09-12 Introduccion a la terminal.ipynb
-rw-rw-r-- 1 wallabot wallabot 314K dic 6 00:04 2022-09-12 Introduccion a la terminal.txt
-rw-rw-r-- 1 wallabot wallabot 117K oct 3 16:13 command-line-cheat-sheet.pdf
-rw-rw-r-- 1 wallabot wallabot 2,6K sep 18 03:32 CSS.ipynb
-rw-rw-r-- 1 wallabot wallabot 683K nov 27 04:16 Docker.html
-rw-rw-r-- 1 wallabot wallabot 498K sep 22 16:48 Docker.ipynb
-rw-rw-r-- 1 wallabot wallabot 153K nov 27 04:21 Expresiones regulares.html
-rw-rw-r-- 1 wallabot wallabot 52K oct 2 04:57 Expresiones regulares.ipynb
drwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 html_files
-rw-rw-r-- 1 wallabot wallabot 15K sep 18 03:29 html.ipynb
drwxrwxr-x 3 wallabot wallabot 4,0K nov 12 01:51 introduccion_python
-rw-rw-r-- 1 wallabot wallabot 436K oct 2 04:39 movies.csv
-rw-rw-r-- 1 wallabot wallabot 510K oct 2 04:33 movies.dat
drwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 notebooks_translated
drwxrwxr-x 2 wallabot wallabot 4,0K ago 27 03:25 __pycache__
-rw-rw-r-- 1 wallabot wallabot 586 dic 4 02:31 ssh.ipynb
-rw-rw-r-- 1 wallabot wallabot 287K nov 9 01:46 test.html
-rw-rw-r-- 1 wallabot wallabot 255K nov 9 01:13 test.ipynb

If what we want is for it to sort them by size, we can use the S option

	
< > Input
Python
terminal('ls -lhS')
Copied
>_ Output
			
total 4,5M
-rw-rw-r-- 1 wallabot wallabot 683K nov 27 04:16 Docker.html
-rw-rw-r-- 1 wallabot wallabot 510K oct 2 04:33 movies.dat
-rw-rw-r-- 1 wallabot wallabot 498K sep 22 16:48 Docker.ipynb
-rw-rw-r-- 1 wallabot wallabot 473K nov 13 00:44 2021-06-15-Manejo-de-datos-con-Pandas.ipynb
-rw-rw-r-- 1 wallabot wallabot 436K oct 2 04:39 movies.csv
-rw-rw-r-- 1 wallabot wallabot 314K dic 6 00:11 2022-09-12 Introduccion a la terminal.ipynb
-rw-rw-r-- 1 wallabot wallabot 314K dic 6 00:04 2022-09-12 Introduccion a la terminal.txt
-rw-rw-r-- 1 wallabot wallabot 287K nov 9 01:46 test.html
-rw-rw-r-- 1 wallabot wallabot 280K nov 12 02:07 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 255K nov 9 01:13 test.ipynb
-rw-rw-r-- 1 wallabot wallabot 153K nov 27 04:21 Expresiones regulares.html
-rw-rw-r-- 1 wallabot wallabot 117K oct 3 16:13 command-line-cheat-sheet.pdf
-rw-rw-r-- 1 wallabot wallabot 77K nov 13 00:10 2021-04-23-Calculo-matricial-con-Numpy.ipynb
-rw-rw-r-- 1 wallabot wallabot 52K oct 2 04:57 Expresiones regulares.ipynb
-rw-rw-r-- 1 wallabot wallabot 15K sep 18 03:29 html.ipynb
drwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 html_files
drwxrwxr-x 3 wallabot wallabot 4,0K nov 12 01:51 introduccion_python
drwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 notebooks_translated
drwxrwxr-x 2 wallabot wallabot 4,0K ago 27 03:25 __pycache__
-rw-rw-r-- 1 wallabot wallabot 2,6K sep 18 03:32 CSS.ipynb
-rw-rw-r-- 1 wallabot wallabot 586 dic 4 02:31 ssh.ipynb

If we want it to show us the files sorted alphabetically, but in reverse, we must use the -r option

	
< > Input
Python
terminal('ls -lhr')
Copied
>_ Output
			
total 4,5M
-rw-rw-r-- 1 wallabot wallabot 255K nov 9 01:13 test.ipynb
-rw-rw-r-- 1 wallabot wallabot 287K nov 9 01:46 test.html
-rw-rw-r-- 1 wallabot wallabot 586 dic 4 02:31 ssh.ipynb
drwxrwxr-x 2 wallabot wallabot 4,0K ago 27 03:25 __pycache__
drwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 notebooks_translated
-rw-rw-r-- 1 wallabot wallabot 510K oct 2 04:33 movies.dat
-rw-rw-r-- 1 wallabot wallabot 436K oct 2 04:39 movies.csv
drwxrwxr-x 3 wallabot wallabot 4,0K nov 12 01:51 introduccion_python
-rw-rw-r-- 1 wallabot wallabot 15K sep 18 03:29 html.ipynb
drwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 html_files
-rw-rw-r-- 1 wallabot wallabot 52K oct 2 04:57 Expresiones regulares.ipynb
-rw-rw-r-- 1 wallabot wallabot 153K nov 27 04:21 Expresiones regulares.html
-rw-rw-r-- 1 wallabot wallabot 498K sep 22 16:48 Docker.ipynb
-rw-rw-r-- 1 wallabot wallabot 683K nov 27 04:16 Docker.html
-rw-rw-r-- 1 wallabot wallabot 2,6K sep 18 03:32 CSS.ipynb
-rw-rw-r-- 1 wallabot wallabot 117K oct 3 16:13 command-line-cheat-sheet.pdf
-rw-rw-r-- 1 wallabot wallabot 314K dic 6 00:04 2022-09-12 Introduccion a la terminal.txt
-rw-rw-r-- 1 wallabot wallabot 314K dic 6 00:11 2022-09-12 Introduccion a la terminal.ipynb
-rw-rw-r-- 1 wallabot wallabot 473K nov 13 00:44 2021-06-15-Manejo-de-datos-con-Pandas.ipynb
-rw-rw-r-- 1 wallabot wallabot 77K nov 13 00:10 2021-04-23-Calculo-matricial-con-Numpy.ipynb
-rw-rw-r-- 1 wallabot wallabot 280K nov 12 02:07 2021-02-11-Introduccion-a-Python.ipynb

cd (change directory)link image 71

The second command will be cd (change directory), which allows us to change directories

	
< > Input
Python
terminal('cd /home/wallabot/Documentos/')
Copied

If we now use ls again to see the files we have, we see that they change

	
< > Input
Python
terminal('ls')
Copied
>_ Output
			
aprendiendo-git.pdf
balena-etcher-electron-1.7.9-linux-x64
camerasIP
Documentacion
gstreamer
gstreamer_old
jetsonNano
kaggle
Libros
nerf
prueba.txt
pytorch
wallabot
web

If to cd, instead of giving it the directory we want to move to, we give it the - character, it will return to the previous directory where it was

	
< > Input
Python
terminal('cd -')
Copied
	
< > Input
Python
terminal('ls')
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
2021-04-23-Calculo-matricial-con-Numpy.ipynb
2021-06-15-Manejo-de-datos-con-Pandas.ipynb
2022-09-12 Introduccion a la terminal.ipynb
2022-09-12 Introduccion a la terminal.txt
command-line-cheat-sheet.pdf
CSS.ipynb
Docker.html
Docker.ipynb
Expresiones regulares.html
Expresiones regulares.ipynb
html_files
html.ipynb
introduccion_python
movies.csv
movies.dat
notebooks_translated
__pycache__
ssh.ipynb
test.html
test.ipynb

If we wanted to move to the home directory by entering only cd in the terminal, it would take us there.

	
< > Input
Python
terminal('cd')
Copied

pwd (print working directory)link image 72

To get the directory we are in, we can use pwd (print working directory)

	
< > Input
Python
terminal('pwd')
Copied
>_ Output
			
/home/wallabot

We can move using the cd command via relative paths and absolute paths. For example, let’s move to a directory using an absolute path.

	
< > Input
Python
terminal('cd /home/wallabot/Documentos/')
Copied
	
< > Input
Python
terminal('pwd')
Copied
>_ Output
			
/home/wallabot/Documentos
	
< > Input
Python
terminal('ls')
Copied
>_ Output
			
aprendiendo-git.pdf
balena-etcher-electron-1.7.9-linux-x64
camerasIP
Documentacion
gstreamer
gstreamer_old
jetsonNano
kaggle
Libros
nerf
prueba.txt
pytorch
wallabot
web

We can move using relative paths if we only specify the direction starting from the point where we are located.

	
< > Input
Python
terminal('cd web')
Copied
	
< > Input
Python
terminal('pwd')
Copied
>_ Output
			
/home/wallabot/Documentos/web

Also, using relative paths we can go up one directory using ..

	
< > Input
Python
terminal('cd ..')
Copied
	
< > Input
Python
terminal('pwd')
Copied
>_ Output
			
/home/wallabot/Documentos

If instead of .. we use ., we are referring to the directory we are currently in, that is, if we type cd . we will not move, since we are telling the terminal to go to the directory we are already in.

	
< > Input
Python
terminal('cd .')
Copied
	
< > Input
Python
terminal('pwd')
Copied
>_ Output
			
/home/wallabot/Documentos

Let's move to a path where we have files to display the following command

	
< > Input
Python
terminal('cd web/portafolio/posts/')
Copied
	
< > Input
Python
terminal('ls')
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
2021-04-23-Calculo-matricial-con-Numpy.ipynb
2021-06-15-Manejo-de-datos-con-Pandas.ipynb
2022-09-12 Introduccion a la terminal.ipynb
2022-09-12 Introduccion a la terminal.txt
command-line-cheat-sheet.pdf
CSS.ipynb
Docker.html
Docker.ipynb
Expresiones regulares.html
Expresiones regulares.ipynb
html_files
html.ipynb
introduccion_python
movies.csv
movies.dat
notebooks_translated
__pycache__
ssh.ipynb
test.html
test.ipynb

File information with filelink image 73

If I do not know what type of file one in particular is, using the file command I can obtain a description

	
< > Input
Python
terminal('file 2021-02-11-Introduccion-a-Python.ipynb')
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb: UTF-8 Unicode text, with very long lines

Manipulating files and directorieslink image 74

Let’s move first to the home.

	
< > Input
Python
terminal('cd /home/wallabot/Documentos/')
Copied

Directory tree with treelink image 75

We can see the entire folder structure we are in using the tree command

	
< > Input
Python
terminal('tree', max_lines_output=20)
Copied
>_ Output
			
.
β”œβ”€β”€ aprendiendo-git.pdf
β”œβ”€β”€ balena-etcher-electron-1.7.9-linux-x64
β”‚Β Β  └── balenaEtcher-1.7.9-x64.AppImage
β”œβ”€β”€ camerasIP
β”‚Β Β  β”œβ”€β”€ camerasIP.py
β”‚Β Β  β”œβ”€β”€ camerasIP.sh
β”‚Β Β  β”œβ”€β”€ config.py
β”‚Β Β  β”œβ”€β”€ __pycache__
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ config.cpython-38.pyc
β”‚Β Β  β”‚Β Β  └── config.cpython-39.pyc
β”‚Β Β  └── README.md
β”œβ”€β”€ Documentacion
β”‚Β Β  β”œβ”€β”€ Curriculum Vitae (5).pdf
β”‚Β Β  β”œβ”€β”€ Firma Pris.PNG
β”‚Β Β  └── Firma.png
β”œβ”€β”€ gstreamer
β”‚Β Β  β”œβ”€β”€ basic_tutorial_c
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ basic_tutorial_1_hello_world
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ basic-tutorial-1
...
β”œβ”€β”€ upload_page.py
└── utils.py
873 directories, 119679 files

But the output shows too many lines, and this is because tree is a command that shows all the files from the path we are in, so it is a bit difficult to read. However, with the L option we can indicate how many levels we want it to go deep.

	
< > Input
Python
terminal('tree -L 2')
Copied
>_ Output
			
.
β”œβ”€β”€ aprendiendo-git.pdf
β”œβ”€β”€ balena-etcher-electron-1.7.9-linux-x64
β”‚Β Β  └── balenaEtcher-1.7.9-x64.AppImage
β”œβ”€β”€ camerasIP
β”‚Β Β  β”œβ”€β”€ camerasIP.py
β”‚Β Β  β”œβ”€β”€ camerasIP.sh
β”‚Β Β  β”œβ”€β”€ config.py
β”‚Β Β  β”œβ”€β”€ __pycache__
β”‚Β Β  └── README.md
β”œβ”€β”€ Documentacion
β”‚Β Β  β”œβ”€β”€ Curriculum Vitae (5).pdf
β”‚Β Β  β”œβ”€β”€ Firma Pris.PNG
β”‚Β Β  └── Firma.png
β”œβ”€β”€ gstreamer
β”‚Β Β  β”œβ”€β”€ basic_tutorial_c
β”‚Β Β  └── README.md
β”œβ”€β”€ gstreamer_old
β”‚Β Β  β”œβ”€β”€ basic_tutorial_c
β”‚Β Β  └── basic_tutorial_python
...
β”œβ”€β”€ wallabot
β”‚Β Β  β”œβ”€β”€ Microfono - Blue Yeti X
β”‚Β Β  β”œβ”€β”€ placa base - Asus prime x570-p
β”‚Β Β  └── Silla - Corsair T3 Rush
└── web
β”œβ”€β”€ jupyter-to-html
β”œβ”€β”€ jupyter-translator
β”œβ”€β”€ portafolio
└── wordpress_api_rest
30 directories, 12 files

We can see that it shows there are 30 directories and 12 files, whereas before it indicated 873 directories and 119679 files

Create folders with mkdir (make directory)link image 76

If we want to create a new directory, we can use the mkdir command (make directory) and a name

	
< > Input
Python
terminal("cd /home/wallabot/Documentos/web/portafolio/posts/")
Copied
	
< > Input
Python
terminal('mkdir prueba')
Copied
>_ Output
			
	
< > Input
Python
terminal('ls')
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
2021-04-23-Calculo-matricial-con-Numpy.ipynb
2021-06-15-Manejo-de-datos-con-Pandas.ipynb
2022-09-12 Introduccion a la terminal.ipynb
2022-09-12 Introduccion a la terminal.txt
command-line-cheat-sheet.pdf
CSS.ipynb
Docker.html
Docker.ipynb
Expresiones regulares.html
Expresiones regulares.ipynb
html_files
html.ipynb
introduccion_python
movies.csv
movies.dat
notebooks_translated
prueba
__pycache__
ssh.ipynb
test.html
test.ipynb

If what we want is to create a directory with spaces in its name, we have to put the name in quotation marks.

	
< > Input
Python
terminal('mkdir "directorio prueba"')
Copied
>_ Output
			
	
< > Input
Python
terminal('ls')
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
2021-04-23-Calculo-matricial-con-Numpy.ipynb
2021-06-15-Manejo-de-datos-con-Pandas.ipynb
2022-09-12 Introduccion a la terminal.ipynb
2022-09-12 Introduccion a la terminal.txt
command-line-cheat-sheet.pdf
CSS.ipynb
directorio prueba
Docker.html
Docker.ipynb
Expresiones regulares.html
Expresiones regulares.ipynb
html_files
html.ipynb
introduccion_python
movies.csv
movies.dat
notebooks_translated
prueba
__pycache__
ssh.ipynb
test.html
test.ipynb

Let's go inside the prueba folder that we created, to keep looking there at the terminal

	
< > Input
Python
terminal("cd prueba")
Copied

Create files with touchlink image 77

In case we want to create a file, the command we need to use is touch

	
< > Input
Python
terminal("touch prueba.txt")
Copied
>_ Output
			
	
< > Input
Python
terminal("ls")
Copied
>_ Output
			
prueba.txt

Copy files with cp (copy)link image 78

If we want to copy a file, we do it using the cp (copy) command

	
< > Input
Python
terminal("cp prueba.txt prueba_copy.txt")
Copied
>_ Output
			
	
< > Input
Python
terminal("ls")
Copied
>_ Output
			
prueba_copy.txt
prueba.txt

Move files with mv (move)link image 79

If what we want is to move it, what we use is the mv (move) command

	
< > Input
Python
terminal("mv prueba.txt ../prueba.txt")
Copied
>_ Output
			
	
< > Input
Python
terminal("ls")
Copied
>_ Output
			
prueba_copy.txt
	
< > Input
Python
terminal("ls ../")
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
2021-04-23-Calculo-matricial-con-Numpy.ipynb
2021-06-15-Manejo-de-datos-con-Pandas.ipynb
2022-09-12 Introduccion a la terminal.ipynb
2022-09-12 Introduccion a la terminal.txt
command-line-cheat-sheet.pdf
CSS.ipynb
directorio prueba
Docker.html
Docker.ipynb
Expresiones regulares.html
Expresiones regulares.ipynb
html_files
html.ipynb
introduccion_python
movies.csv
movies.dat
notebooks_translated
prueba
prueba.txt
__pycache__
ssh.ipynb
test.html
test.ipynb

Rename files with mv (move)link image 80

The mv command also serves to rename files, since if what we do is move it within the same directory, but giving it another name, in the end that is renaming the file.

	
< > Input
Python
terminal("mv prueba_copy.txt prueba_move.txt")
Copied
>_ Output
			
	
< > Input
Python
terminal("ls")
Copied
>_ Output
			
prueba_move.txt

Delete files with rm (remove)link image 81

To delete files or directories, we use the rm command (remove)

	
< > Input
Python
terminal("rm prueba_move.txt")
Copied
>_ Output
			
	
< > Input
Python
terminal("ls")
Copied
>_ Output
			

Remove directories with rm -r (recursive remove)link image 82

If what we want is to delete a directory with files inside, we must use the -r flag.

	
< > Input
Python
terminal("cd ..")
Copied
	
< > Input
Python
terminal('rm -r "directorio prueba"')
Copied
>_ Output
			
	
< > Input
Python
terminal("ls")
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
2021-04-23-Calculo-matricial-con-Numpy.ipynb
2021-06-15-Manejo-de-datos-con-Pandas.ipynb
2022-09-12 Introduccion a la terminal.ipynb
2022-09-12 Introduccion a la terminal.txt
command-line-cheat-sheet.pdf
CSS.ipynb
Docker.html
Docker.ipynb
Expresiones regulares.html
Expresiones regulares.ipynb
html_files
html.ipynb
introduccion_python
movies.csv
movies.dat
notebooks_translated
prueba
prueba.txt
__pycache__
ssh.ipynb
test.html
test.ipynb

As you can see, it never asks if we are sure; to make it ask, you need to add the -i (interactive) flag

	
< > Input
Python
terminal("rm -i prueba.txt")
Copied
>_ Output
			
rm: ΒΏborrar el fichero regular vacΓ­o 'prueba.txt'? (s/n) s

Sync files using rsynclink image 83

So far we have seen how to copy, move, and delete files, but suppose we have a folder and we copy those files to another one. Now suppose we modify a file in the first folder and want the second one to have the changes. We have two options: copy all the files again, or perform a synchronization using rsync

First, we are going to create a new folder in which we will create several files

	
< > Input
Python
!mkdir sourcefolder
!touch sourcefolder/file1 sourcefolder/file2 sourcefolder/file3
Copied

Now we create a second folder, which is the one we are going to synchronize with the first one

	
< > Input
Python
!mkdir syncfolder
Copied
	
< > Input
Python
!echo "ls sourcefolder:" && ls sourcefolder && echo "ls syncfolder:" && ls syncfolder
Copied
>_ Output
			
ls sourcefolder:
file1 file2 file3
ls syncfolder:

We synchronize the two folders with rsync; the first time it will only copy the files from the first folder to the second. To do this, we must also add the -r (recursive) flag.

	
< > Input
Python
!rsync -r sourcefolder/ syncfolder/
Copied
	
< > Input
Python
!echo "ls sourcefolder:" && ls sourcefolder && echo "ls syncfolder:" && ls syncfolder
Copied
>_ Output
			
ls sourcefolder:
file1 file2 file3
ls syncfolder:
file1 file2 file3

If I now create a new file in sourcefolder and synchronize again, only that file is copied to syncfolder. To see that only one file is copied, we can use the -v (verbose) flag.

	
< > Input
Python
!touch sourcefolder/file4
Copied
	
< > Input
Python
!rsync -r -v sourcefolder/ syncfolder/
Copied
>_ Output
			
sending incremental file list
file1
file2
file3
file4
sent 269 bytes received 92 bytes 722.00 bytes/sec
total size is 0 speedup is 0.00

But it seems that it has copied all the files, so to prevent this from happening and copy only the ones that have been modified, you need to use the -u flag

	
< > Input
Python
!touch sourcefolder/file5
Copied
	
< > Input
Python
!rsync -r -v -u sourcefolder/ syncfolder/
Copied
>_ Output
			
sending incremental file list
file5
sent 165 bytes received 35 bytes 400.00 bytes/sec
total size is 0 speedup is 0.00
	
< > Input
Python
!echo "ls sourcefolder:" && ls sourcefolder && echo "ls syncfolder:" && ls syncfolder
Copied
>_ Output
			
ls sourcefolder:
file1 file2 file3 file4 file5
ls syncfolder:
file1 file2 file3 file4 file5

And what happens if I create a new file in syncfolder?

	
< > Input
Python
!touch syncfolder/file6
Copied
	
< > Input
Python
!rsync -r -v -u sourcefolder/ syncfolder/
Copied
>_ Output
			
sending incremental file list
sent 122 bytes received 12 bytes 268.00 bytes/sec
total size is 0 speedup is 0.00
	
< > Input
Python
!echo "ls sourcefolder:" && ls sourcefolder && echo "ls syncfolder:" && ls syncfolder
Copied
>_ Output
			
ls sourcefolder:
file1 file2 file3 file4 file5
ls syncfolder:
file1 file2 file3 file4 file5 file6

It doesn’t sync, so it’s important to keep that in mind

Some important flags to keep in mind are:

  • -a: This flag is a shortcut for several options, including -r (recursive), -l (copy symbolic links), -p (preserve permissions), -t (preserve modification time), and -g (preserve group). This option is useful for making an exact copy of a directory, including all its subfolders and files.
  • -v: This flag enables verbose output, showing the files being copied and the progress of the operation.
  • -r: This flag is used to copy recursively, which means it copies all subfolders and files within a directory.
  • -u: This flag is used to copy only new or modified files. If a file already exists at the destination and is newer than the source file, it is not copied.* -n: This flag is used to perform a dry run, which means no changes are made to the destination.
  • --exclude: This flag is used to exclude specific files or folders from the copy operation. You can specify multiple files or folders to exclude by using this option several times.
  • -z: This flag is used to compress data during transfer, which reduces the bandwidth used and speeds up the transfer rate.
  • -h: this flag is used to display information in a more readable format, especially when working with large amounts of data or large file sizes.

We deleted the two created folders

	
< > Input
Python
!rm -r sourcefolder syncfolder
Copied

Exploring the contents of the fileslink image 84

To avoid having to open a file from a graphical interface, we have several ways. I’m going to copy a text file into this folder first.

	
< > Input
Python
terminal("cd prueba")
Copied
	
< > Input
Python
terminal("cp ../2021-02-11-Introduccion-a-Python.ipynb .")
Copied
>_ Output
			
	
< > Input
Python
terminal("ls")
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb

File headers with headlink image 85

The first command to be able to look inside a text file is head, which allows us to see the first 10 lines of a file, but if you add the -n flag you can specify the number of lines

	
< > Input
Python
terminal("head 2021-02-11-Introduccion-a-Python.ipynb")
Copied
>_ Output
			
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "dsaKCKL0IxZl"
},
"source": [
"# IntroducciΓ³n a Python"
]
	
< > Input
Python
terminal("head -n 5 2021-02-11-Introduccion-a-Python.ipynb")
Copied
>_ Output
			
{
"cells": [
{
"cell_type": "markdown",
"metadata": {

File tail with taillink image 86

In case you want to see the last lines, we use tail

	
< > Input
Python
terminal("tail 2021-02-11-Introduccion-a-Python.ipynb")
Copied
>_ Output
			
},
"vscode": {
"interpreter": {
"hash": "d5745ab6aba164e1152437c779991855725055592b9f2bdb41a4825db7168d26"
}
}
},
"nbformat": 4,
"nbformat_minor": 0
}
	
< > Input
Python
terminal("tail -n 5 2021-02-11-Introduccion-a-Python.ipynb")
Copied
>_ Output
			
}
},
"nbformat": 4,
"nbformat_minor": 0
}

If we want to continuously see the last lines of a file, for example, if we want to continuously monitor a LOG file to see events, we add the -f flag; this will keep the terminal continuously checking the file, and every time a new line appears in it, it will display it

For example, if I monitor the login log on my machine

	
< > Input
Python
!tail -f /var/log/auth.log
Copied
>_ Output
			
Dec 1 16:27:22 wallabot gcr-prompter[1457]: Gcr: calling the PromptDone method on /org/gnome/keyring/Prompt/p2@:1.26, and ignoring reply
Dec 1 16:27:22 wallabot gnome-keyring-daemon[1178]: asked to register item /org/freedesktop/secrets/collection/login/10, but it's already registered
Dec 1 16:27:26 wallabot systemd-logind[835]: Watching system buttons on /dev/input/event28 (Logitech Wireless Mouse MX Master 3)
Dec 1 16:27:33 wallabot gcr-prompter[1457]: Gcr: 10 second inactivity timeout, quitting
Dec 1 16:27:33 wallabot gcr-prompter[1457]: Gcr: unregistering prompter
Dec 1 16:27:33 wallabot gcr-prompter[1457]: Gcr: disposing prompter
Dec 1 16:27:33 wallabot gcr-prompter[1457]: Gcr: finalizing prompter
Dec 1 16:27:34 wallabot polkitd(authority=local): Operator of unix-session:1 successfully authenticated as unix-user:wallabot to gain TEMPORARY authorization for action org.debian.apt.install-or-remove-packages for system-bus-name::1.96 [/usr/bin/python3 /usr/bin/update-manager --no-update --no-focus-on-map] (owned by unix-user:wallabot)
Dec 1 16:27:42 wallabot systemd-logind[835]: Watching system buttons on /dev/input/event30 (T9-R (AVRCP))
Dec 1 16:27:49 wallabot gnome-keyring-daemon[1178]: asked to register item /org/freedesktop/secrets/collection/login/2, but it's already registered

We see in the last two lines my login when I turned on my computer today.

Now I connect via SSH to my own machine

	
< > Input
Python
!ssh localhost
Copied
>_ Output
			
wallabot@localhost's password:
Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.15.0-53-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
1 device has a firmware upgrade available.
Run `fwupdmgr get-upgrades` for more information.
Se pueden aplicar 0 actualizaciones de forma inmediata.
Your Hardware Enablement Stack (HWE) is supported until April 2025.
*** System restart required ***
Last login: Sun May 8 02:18:09 2022 from 192.168.1.147

In the console where the login was being monitored, two new lines have appeared

>_ Output
			
Dec 1 16:32:23 wallabot sshd[25647]: Accepted password for wallabot from 127.0.0.1 port 54668 ssh2
Dec 1 16:32:23 wallabot sshd[25647]: pam_unix(sshd:session): session opened for user wallabot by (uid=0)
Dec 1 16:32:23 wallabot systemd-logind[835]: New session 4 of user wallabot.

And when I close the SSH session, two new lines appear

>_ Output
			
Dec 1 16:33:52 wallabot sshd[25647]: pam_unix(sshd:session): session closed for user wallabot
Dec 1 16:33:52 wallabot systemd-logind[835]: Session 4 logged out. Waiting for processes to exit.
Dec 1 16:33:52 wallabot systemd-logind[835]: Removed session 4.

The most powerful file viewer: lesslink image 87

One of the most powerful commands for viewing inside files is less

	
< > Input
Python
terminal("less 2021-02-11-Introduccion-a-Python.ipynb", max_lines_output=20)
Copied
>_ Output
			
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "dsaKCKL0IxZl"
},
"source": [
"# IntroducciΓ³n a Python"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ho_8zgIiI0We"
},
"source": [
"## 1. Resumen"
]
},
...
},
"nbformat": 4,
"nbformat_minor": 0
}

Being inside a notebook, you cannot see what is really happening when using less, but when we use it we enter the document, and we can move through it using the keys or the mouse

If we want to search for something within the document, we type the / character and what we want to search for. To move between the different matches it has found, we press the n key, and if we want to go back through the searches, we press shift+n

To exit, just press q

The cat viewerlink image 88

It does not allow you to navigate through the file or perform searches.

	
< > Input
Python
terminal("cat 2021-02-11-Introduccion-a-Python.ipynb", max_lines_output=20)
Copied
>_ Output
			
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "dsaKCKL0IxZl"
},
"source": [
"# IntroducciΓ³n a Python"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ho_8zgIiI0We"
},
"source": [
"## 1. Resumen"
]
},
...
},
"nbformat": 4,
"nbformat_minor": 0
}

Default system editor xdg-openlink image 89

If we want to open it with the file's default editor, we have to use xdg-open

	
< > Input
Python
terminal("xdg-open 2021-02-11-IntroducciΓ³n-a-Python.ipynb")
Copied
>_ Output
			

File browser nautiluslink image 90

If what we want is to open the folder we are in, we use nautilus

	
< > Input
Python
terminal("nautilus")
Copied
>_ Output
			

And if what we want is for it to open at a specific route, the route is included

	
< > Input
Python
terminal("nautilus ~/")
Copied
>_ Output
			

Word count of a file with wc (word count)link image 91

Finally, a very useful command is wc (word count), which shows you how many lines, words, and bytes a file has

	
< > Input
Python
terminal("wc 2021-02-11-Introduccion-a-Python.ipynb")
Copied
>_ Output
			
11678 25703 285898 2021-02-11-Introduccion-a-Python.ipynb

As we can see, the file has 11,678 lines, 25,703 words, and occupies 285,898 bytes

What is a command?link image 92

A command can be four things

  • An executable program, these are usually stored in the /usr/bin path
  • A shell command* A shell function
  • An alias

To see which class a command belongs to, we use type

	
< > Input
Python
!type cd
Copied
>_ Output
			
cd is a shell builtin
	
< > Input
Python
!type mkdir
Copied
>_ Output
			
mkdir is /usr/bin/mkdir
	
< > Input
Python
!type ls
Copied
>_ Output
			
ls is /usr/bin/ls

What is an alias?link image 93

An alias is a command that we define ourselves; it is defined using the alias command. For example, let’s create the alias l, which will run ls -h

	
< > Input
Python
!alias l='ls -l'
Copied

When we run l, it shows us the result of ls -h

	
< > Input
Python
!l
Copied
>_ Output
			
2021-02-11-IntroducciΓ³n-a-Python.ipynb

But this has the problem that when we close the terminal, the alias disappears. Later on, we will learn how to create permanent aliases

Command helplink image 94

Help with helplink image 95

With many shell commands, we can get their help using the help command

	
< > Input
Python
!help cd
Copied
>_ Output
			
cd: cd [-L|[-P [-e]]] [dir]
Modifica el directorio de trabajo del shell.
Modifica el directorio actual a DIR. DIR por defecto es el valor de la
variable de shell HOME.
La variable CDPATH define la ruta de bΓΊsqueda para el directorio que
contiene DIR. Los nombres alternativos de directorio en CDPATH se
separan con dos puntos (:). Un nombre de directorio nulo es igual que
el directorio actual. Si DIR comienza con una barra inclinada (/),
entonces no se usa CDPATH.
Si no se encuentra el directorio, y la opciΓ³n del shell "cdable_vars"
estΓ‘ activa, entonces se trata la palabra como un nombre de variable.
Si esa variable tiene un valor, se utiliza su valor para DIR.
Opciones:
-L fuerza a seguir los enlaces simbΓ³licos: resuelve los enlaces
simbΓ³licos en DIR despuΓ©s de procesar las instancias de ".."
-P usa la estructura fΓ­sica de directorios sin seguir los enlaces
simbΓ³licos: resuelve los enlaces simbΓ³licos en DIR antes de procesar
las instancias de ".."
-e si se da la opciΓ³n -P y el directorio actual de trabajo no se
puede determinar con Γ©xito, termina con un estado diferente de cero.
La acciΓ³n por defecto es seguir los enlaces simbΓ³licos, como si se
especificara "-L".
".." se procesa quitando la componente del nombre de la ruta inmediatamente
anterior hasta una barra inclinada o el comienzo de DIR.
Estado de Salida:
Devuelve 0 si se cambia el directorio, y si $PWD estΓ‘ definido como
correcto cuando se emplee -P; de otra forma es diferente a cero.

Manual with manlink image 96

Another command is man, which refers to the user manual.

	
< > Input
Python
terminal("man ls", max_lines_output=20)
Copied
>_ Output
			
LS(1) User Commands LS(1)
NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is speci‐
fied.
Mandatory arguments to long options are mandatory for short options
too.
-a, --all
do not ignore entries starting with .
-A, --almost-all
...
Full documentation at: &lt;https://www.gnu.org/software/coreutils/ls&gt;
or available locally via: info '(coreutils) ls invocation'
GNU coreutils 8.30 September 2019 LS(1)

To exit, press q, since man uses less as the manual viewer

Information with infolink image 97

Another command is info

	
< > Input
Python
terminal("info ls", max_lines_output=20)
Copied
>_ Output
			
File: coreutils.info, Node: ls invocation, Next: dir invocation, Up: Directory listing
10.1 β€˜ls’: List directory contents
==================================
The β€˜ls’ program lists information about files (of any type, including
directories). Options and file arguments can be intermixed arbitrarily,
as usual.
For non-option command-line arguments that are directories, by
default β€˜ls’ lists the contents of directories, not recursively, and
omitting files with names beginning with β€˜.’. For other non-option
arguments, by default β€˜ls’ lists just the file name. If no non-option
argument is specified, β€˜ls’ operates on the current directory, acting as
if it had been invoked with a single argument of β€˜.’.
By default, the output is sorted alphabetically, according to the
locale settings in effect.(1) If standard output is a terminal, the
output is in columns (sorted vertically) and control characters are
output as question marks; otherwise, the output is listed one per line
...
β€˜--show-control-chars’
Print nongraphic characters as-is in file names. This is the
default unless the output is a terminal and the program is β€˜ls’.

To exit, press q, since info uses less as the information viewer

Information about a command with whatislink image 98

Another command is whatis

	
< > Input
Python
terminal("whatis ls")
Copied
>_ Output
			
ls (1) - list directory contents

Wildcardslink image 99

Wildcards are special characters that help us perform special searches. For example, if I want to search for all files that end in .txt. Let's create a few files to see them.

	
< > Input
Python
terminal("touch file.txt dot.txt dot2.txt index.html datos1 datos123 Abc")
Copied
>_ Output
			
	
< > Input
Python
terminal("ls")
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
Abc
datos1
datos123
dot2.txt
dot.txt
file.txt
index.html

All the characters *link image 100

Let's now look for all .txt files

	
< > Input
Python
!ls *.txt
Copied
>_ Output
			
dot2.txt dot.txt file.txt

Let's now search for all those that start with the word datos

	
< > Input
Python
!ls datos*
Copied
>_ Output
			
datos1 datos123

Numbers ?link image 101

But what happens if what we actually want is for it to show us all the files that start with the word datos but followed only by a number? We have to put a question mark ?

	
< > Input
Python
!ls datos?
Copied
>_ Output
			
datos1

If what we want is for it to have three numbers, then we have to put three question marks ???

	
< > Input
Python
!ls datos???
Copied
>_ Output
			
datos123

Uppercase [[:upper:]]link image 102

If we want it to look for files that start with uppercase letters

	
< > Input
Python
!ls [[:upper:]]*
Copied
>_ Output
			
Abc

Lowercase [[:lower:]]link image 103

For files that start with lowercase letters.

	
< > Input
Python
!ls [[:lower:]]*
Copied
>_ Output
			
datos1 datos123 dot2.txt dot.txt file.txt index.html

Classeslink image 104

By using brackets, we can create classes. So if we want to search for files that start with the letters d or f followed by any character

	
< > Input
Python
!ls [df]*
Copied
>_ Output
			
datos1 datos123 dot2.txt dot.txt file.txt

Redirections: how the shell workslink image 105

A command works as follows

pipeline command

It has a standard input, which by default is the text we enter via the keyboard, a standard output, which by default is the text that appears in the console, and a standard error which is also, by default, text that appears in the console, but in a different format

Redirection of standard outputlink image 106

But with the character > we can modify the standard output of a command. For example, if we want to list with ls the files in the folder we are in, but we do not want the result to be printed on screen, but rather saved in a file, we would do the following ls > lista.txt, this writes the list in lista.txt. Also, if lista.txt does not exist, it creates it

	
< > Input
Python
!ls &gt; lista.txt
Copied

We can see that it has created the file and see what's inside

	
< > Input
Python
terminal("ls")
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
Abc
datos1
datos123
dot2.txt
dot.txt
file.txt
index.html
lista.txt
	
< > Input
Python
terminal("cat lista.txt")
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
Abc
datos1
datos123
dot2.txt
dot.txt
file.txt
index.html
lista.txt

We see that inside lista.txt appears lista.txt; that is because it first creates the file and then runs the command

We do the same, but with the parent folder

	
< > Input
Python
!ls ../ &gt; lista.txt
Copied

If we look again inside lista.txt

	
< > Input
Python
terminal("cat lista.txt")
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
2021-04-23-Calculo-matricial-con-Numpy.ipynb
2021-06-15-Manejo-de-datos-con-Pandas.ipynb
2022-09-12 Introduccion a la terminal.ipynb
2022-09-12 Introduccion a la terminal.txt
command-line-cheat-sheet.pdf
CSS.ipynb
Docker.html
Docker.ipynb
Expresiones regulares.html
Expresiones regulares.ipynb
html_files
html.ipynb
introduccion_python
movies.csv
movies.dat
notebooks_translated
prueba
__pycache__
ssh.ipynb
test.html
test.ipynb

We see that the content is overwritten

If what we want is for the content to be concatenated, we must use >>

	
< > Input
Python
!ls &gt; lista.txt
Copied
	
< > Input
Python
!ls ../ &gt;&gt; lista.txt
Copied
	
< > Input
Python
terminal("cat lista.txt")
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb
Abc
datos1
datos123
dot2.txt
dot.txt
file.txt
index.html
lista.txt
2021-02-11-Introduccion-a-Python.ipynb
2021-04-23-Calculo-matricial-con-Numpy.ipynb
2021-06-15-Manejo-de-datos-con-Pandas.ipynb
2022-09-12 Introduccion a la terminal.ipynb
2022-09-12 Introduccion a la terminal.txt
command-line-cheat-sheet.pdf
CSS.ipynb
Docker.html
Docker.ipynb
Expresiones regulares.html
Expresiones regulares.ipynb
html_files
html.ipynb
introduccion_python
movies.csv
movies.dat
notebooks_translated
prueba
__pycache__
ssh.ipynb
test.html
test.ipynb

Now the information has been concatenated.

This is very useful for creating log files

Redirection of standard errorlink image 107

If we perform an incorrect operation, we get an error; let's see what happens when redirecting a command that produces an error

	
< > Input
Python
!ls fjhdsalkfs &gt; lista.txt
Copied
>_ Output
			
ls: no se puede acceder a 'fjhdsalkfs': No existe el archivo o el directorio

As we can see, it has given an error, but if we now look inside lista.txt

	
< > Input
Python
terminal("cat lista.txt")
Copied
>_ Output
			

We can see that the file is empty; that is because we have not redirected standard error to lista.txt, but rather standard output. As we saw in the image, there are two output streams in a command: the first is standard output and the second is standard error, so to redirect standard error you must indicate it with 2>. Let's do it now like this

	
< > Input
Python
!ls kjhsfskjd 2&gt; lista.txt
Copied
	
< > Input
Python
terminal("cat lista.txt")
Copied
>_ Output
			
ls: no se puede acceder a 'kjhsfskjd': No existe el archivo o el directorio

As we can see, it has now been redirected.

Redirection of standard output and standard errorlink image 108

If we want to redirect both of them, we use the following

	
< > Input
Python
!ls kjhsfskjd &gt; lista.txt 2&gt;&amp;1
Copied

Let's look inside lista.txt

	
< > Input
Python
terminal("cat lista.txt")
Copied
>_ Output
			
ls: no se puede acceder a 'kjhsfskjd': No existe el archivo o el directorio

If we now run a command without errors

	
< > Input
Python
!ls . &gt;&gt; lista.txt 2&gt;&amp;1
Copied

Let's look inside lista.txt (**note**, we have now concatenated)

	
< > Input
Python
terminal("cat lista.txt")
Copied
>_ Output
			
ls: no se puede acceder a 'kjhsfskjd': No existe el archivo o el directorio
2021-02-11-Introduccion-a-Python.ipynb
Abc
datos1
datos123
dot2.txt
dot.txt
file.txt
index.html
lista.txt

As can be seen, both the standard error and the standard output have been redirected to the same file

Pipelineslink image 109

We can create pipelines by making the standard output of one command become the standard input of another. For example, we are going to make the output of ls -lha the input of grep, which we will see later, but it is a command for searching.

	
< > Input
Python
!ls -lha | grep -i "txt"
Copied
>_ Output
			
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot2.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 file.txt
-rw-rw-r-- 1 wallabot wallabot 182 dic 6 01:06 lista.txt

As we can see, what we have done is pipe the output of ls to grep, with which we have searched for any file with txt in the name

Control operators - chaining commandslink image 110

Sequential commandslink image 111

One way to chain commands sequentially is to separate them with ;. This creates different threads for each task

	
< > Input
Python
!ls; echo 'Hola'; cal
Copied
>_ Output
			
2021-02-11-Introduccion-a-Python.ipynb datos123 file.txt
Abc dot2.txt index.html
datos1 dot.txt lista.txt
Hola
Diciembre 2022
do lu ma mi ju vi sΓ‘
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

As we can see, first the ls command was executed, then Hola was printed thanks to the echo "Hola" command, and finally a calendar was printed thanks to the cal command

Let's now do another example to see that they are executed sequentially.

	
< > Input
Python
!echo "Before touch;"; ls -lha; touch secuential.txt; echo "After touch:"; ls -lha
Copied
>_ Output
			
Before touch;
total 292K
drwxrwxr-x 2 wallabot wallabot 4,0K dic 6 01:04 .
drwxrwxr-x 7 wallabot wallabot 4,0K dic 6 00:24 ..
-rw-rw-r-- 1 wallabot wallabot 280K dic 6 00:28 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 Abc
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos1
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos123
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot2.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 file.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html
-rw-rw-r-- 1 wallabot wallabot 182 dic 6 01:06 lista.txt
After touch:
total 292K
drwxrwxr-x 2 wallabot wallabot 4,0K dic 6 01:07 .
drwxrwxr-x 7 wallabot wallabot 4,0K dic 6 00:24 ..
-rw-rw-r-- 1 wallabot wallabot 280K dic 6 00:28 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 Abc
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos1
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos123
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot2.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 file.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html
-rw-rw-r-- 1 wallabot wallabot 182 dic 6 01:06 lista.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 01:07 secuential.txt

As can be seen, in the first ls sequential.txt does not appear, while in the second it does. That means the commands were executed in order, one after another

Parallel Commandslink image 112

If what we want is for the commands to execute in parallel, we need to use the & operator. This will cause a new process to be created for each command.

Let's look at the previous example

	
< > Input
Python
!rm secuential.txt
Copied
	
< > Input
Python
!echo "Before touch;" &amp; ls -lha &amp; touch secuential.txt &amp; echo "After touch:" &amp; ls -lha
Copied
>_ Output
			
Before touch;
After touch:
total 292K
drwxrwxr-x 2 wallabot wallabot 4,0K dic 6 01:08 .
drwxrwxr-x 7 wallabot wallabot 4,0K dic 6 00:24 ..
-rw-rw-r-- 1 wallabot wallabot 280K dic 6 00:28 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 Abc
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos1
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos123
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot2.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 file.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html
-rw-rw-r-- 1 wallabot wallabot 182 dic 6 01:06 lista.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 01:08 secuential.txt

Now it can be seen that they have not been executed sequentially, since first the echos have been executed, which are the ones that take the least time, and then the rest.

Conditional Commandslink image 113

Andlink image 114

Using the && operator, a command will execute when the previous one has executed successfully

	
< > Input
Python
!rm secuential.txt
Copied
	
< > Input
Python
!echo "Before touch;" && ls -lha && touch secuential.txt && echo "After touch:" && ls -lha
Copied
>_ Output
			
Before touch;
total 292K
drwxrwxr-x 2 wallabot wallabot 4,0K dic 6 01:08 .
drwxrwxr-x 7 wallabot wallabot 4,0K dic 6 00:24 ..
-rw-rw-r-- 1 wallabot wallabot 280K dic 6 00:28 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 Abc
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos1
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos123
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot2.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 file.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html
-rw-rw-r-- 1 wallabot wallabot 182 dic 6 01:06 lista.txt
After touch:
total 292K
drwxrwxr-x 2 wallabot wallabot 4,0K dic 6 01:08 .
drwxrwxr-x 7 wallabot wallabot 4,0K dic 6 00:24 ..
-rw-rw-r-- 1 wallabot wallabot 280K dic 6 00:28 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 Abc
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos1
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos123
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot2.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 file.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html
-rw-rw-r-- 1 wallabot wallabot 182 dic 6 01:06 lista.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 01:08 secuential.txt

Here we can see how they have been executed one after another, that is, one command does not start until the previous one finishes

But then, what is the difference between ; and &&?

In the first case, the sequential ; means one command is executed first and then another, but for a command to run, it does not matter whether the previous one executed successfully.

	
< > Input
Python
!rm prueba ; ls -lha
Copied
>_ Output
			
rm: no se puede borrar 'prueba': No existe el archivo o el directorio
total 292K
drwxrwxr-x 2 wallabot wallabot 4,0K dic 6 01:08 .
drwxrwxr-x 7 wallabot wallabot 4,0K dic 6 00:24 ..
-rw-rw-r-- 1 wallabot wallabot 280K dic 6 00:28 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 Abc
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos1
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos123
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot2.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 file.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html
-rw-rw-r-- 1 wallabot wallabot 182 dic 6 01:06 lista.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 01:08 secuential.txt

As can be seen, first rm prueba is executed, it gives an error and even so ls -lha prueba is executed

In the conditional form &&, if a command does not execute successfully, the next one is not executed.

	
< > Input
Python
!rm prueba && ls -lha
Copied
>_ Output
			
rm: no se puede borrar 'prueba': No existe el archivo o el directorio

As can be seen, ls -lha prueba is not executed because rm prueba has produced an error

Orlink image 115

Unlike &&, or will execute all processes, regardless of their result. The || operator must be used.

	
< > Input
Python
!rm prueba || ls -lha
Copied
>_ Output
			
rm: no se puede borrar 'prueba': No existe el archivo o el directorio
total 292K
drwxrwxr-x 2 wallabot wallabot 4,0K dic 6 01:08 .
drwxrwxr-x 7 wallabot wallabot 4,0K dic 6 00:24 ..
-rw-rw-r-- 1 wallabot wallabot 280K dic 6 00:28 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 Abc
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos1
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos123
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot2.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 file.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html
-rw-rw-r-- 1 wallabot wallabot 182 dic 6 01:06 lista.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 01:08 secuential.txt

The difference between this and ; is that || (or) does not create a new thread for each command

How permissions are handledlink image 116

When listing the files in a directory with the -l (long) flag, some symbols appear next to each file.

	
< > Input
Python
!mkdir subdirectorio
Copied
	
< > Input
Python
!ls -l
Copied
>_ Output
			
total 288
-rw-rw-r-- 1 wallabot wallabot 285898 dic 6 00:28 2021-02-11-Introduccion-a-Python.ipynb
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 Abc
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos1
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 datos123
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot2.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 dot.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 file.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html
-rw-rw-r-- 1 wallabot wallabot 182 dic 6 01:06 lista.txt
-rw-rw-r-- 1 wallabot wallabot 0 dic 6 01:08 secuential.txt
drwxrwxr-x 2 wallabot wallabot 4096 dic 6 01:10 subdirectorio

This gives us information about each file

First, let’s see what types of files there are

  • -: Regular file
  • d: Directory* l: Symbolic link
  • b: Special block file. These are files that manage block data information, such as a USB drive.

Then we will see the types of mode:

```html

Owner Group World
rwx r-x r-x
1 1 1 1 0 1 1 0 1
7 5 5
  • r: read
  • w: write
  • x: execute

Symbolic mode:

  • u: For the user only
  • g: Only for the group* o: Only for others (world)
  • a: For all

Modifying permissions in the terminallink image 117

We created a new file

	
< > Input
Python
terminal("cd subdirectorio")
Copied
	
< > Input
Python
!echo "hola mundo" &gt; mitexto.txt
Copied
	
< > Input
Python
!cat mitexto.txt
Copied
>_ Output
			
hola mundo

Let's see the permissions it has.

	
< > Input
Python
!ls -l
Copied
>_ Output
			
total 4
-rw-rw-r-- 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt

As we can see, it has read and write permissions for my user and the group, and only read permissions for others (world).

Changing permissions with chmod (change mode)link image 118

To change the permissions of a file, we use the chmod (change mode) command, where we must specify in octal the permissions of the user, then those of the group, and finally those of everyone else.

	
< > Input
Python
!chmod 755 mitexto.txt
Copied
	
< > Input
Python
!ls -l
Copied
>_ Output
			
total 4
-rwxr-xr-x 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt

We see that now my user has read, write, and execute permissions, while the group and everyone else have read and execute permissions

Let's remove the read permissions only from my user. To change only a user's permissions, we use the symbolic identifier, a + if we want to add permissions, a - if we want to remove them, or an = if we want to reset them, followed by the permission type.

	
< > Input
Python
!chmod u-r mitexto.txt
Copied
	
< > Input
Python
!ls -l
Copied
>_ Output
			
total 4
--wxr-xr-x 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt
	
< > Input
Python
!cat mitexto.txt
Copied
>_ Output
			
cat: mitexto.txt: Permiso denegado

As we can see, by removing read permissions for my user, we cannot read the file.

We give it the read permission again

	
< > Input
Python
!chmod u+r mitexto.txt
Copied
	
< > Input
Python
!ls -l
Copied
>_ Output
			
total 4
-rwxr-xr-x 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt
	
< > Input
Python
!cat mitexto.txt
Copied
>_ Output
			
hola mundo

If we want to add or remove permissions for more than one user, we do it by separating each permission with a ,

	
< > Input
Python
!chmod u-x,go=w mitexto.txt
Copied
	
< > Input
Python
!ls -l
Copied
>_ Output
			
total 4
-rw--w--w- 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt

As can be seen, execution permission has been removed from the user, and write-only permission has been set for the group and everyone else.

User identification with whoamilink image 119

To find out who we are, we can use the whoami command (who am I)

	
< > Input
Python
!whoami
Copied
>_ Output
			
wallabot

User information with idlink image 120

Another way, which also provides more information, is the id command

	
< > Input
Python
!id
Copied
>_ Output
			
uid=1000(wallabot) gid=1000(wallabot) grupos=1000(wallabot),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),120(lpadmin),131(lxd),132(sambashare),998(docker)

This command tells us that our user ID is 1000, the group ID is 1000, and that we belong to the groups wallabot, adm, cdrom, sudo, dip, plugdev, lpadmin, lxd, sambashare, and docker

Change user with the su command (switch user)link image 121

If we want to switch users, we use the su command (switch user). Depending on the user, we have to use sudo (superuser do).

	
< > Input
Python
!sudo su root
Copied
>_ Output
			
root@wallabot:/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio#

As we can see, the prompt changes and now indicates that we are the root user

Let's go to the home folder

	
< > Input
Python
!cd
Copied
>_ Output
			
root@wallabot:~#

But in Linux there is a home folder for each user; we can see this if we run the pwd command

	
< > Input
Python
!pwd
Copied
>_ Output
			
/root

I’m going to create a file in the folder where I previously created the *mitexto.txt* file.

	
< > Input
Python
!touch /home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio/rootfile.txt
Copied
>_ Output
			

I switch back to my user account

	
< > Input
Python
!su wallabot
Copied
>_ Output
			
wallabot@wallabot:

And I go to the directory where the files I created are.

	
< > Input
Python
!cd /home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio
Copied

We see the files that are there and their permissions

	
< > Input
Python
!ls -l
Copied
>_ Output
			
total 4
-rw--w--w- 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt
-rw-r--r-- 1 root root 0 dic 6 01:22 rootfile.txt

As we can see, the user and group of the *rootfile.txt* file are the user root

Yes, now that I am the *wallabot* user, I am trying to delete the file rootfile.txt

	
< > Input
Python
!rm rootfile.txt
Copied
>_ Output
			
rm: ΒΏborrar el fichero regular vacΓ­o 'rootfile.txt' protegido contra escritura? (s/n)

As we can see, it asks us if we want to delete it, since it belongs to another user.

Change a user’s passwordlink image 122

If I want to change the password of the user I currently have active, I use the passwd (password) command

First I check which user I am

	
< > Input
Python
!whoami
Copied
>_ Output
			
wallabot

And now we try changing the password

	
< > Input
Python
!passwd
Copied
>_ Output
			
$ passwd
Cambiando la contraseΓ±a de wallabot.
ContraseΓ±a actual de :
Nueva contraseΓ±a:
Vuelva a escribir la nueva contraseΓ±a

As we can see, it asks for the current password in order to change it.

We can create symbolic links to a specific path using the ln (link) command followed by the -s (symbolic) flag, the directory, and the name of the link

	
< > Input
Python
!ln -s /home/wallabot/Documentos/web web
Copied

If we now list the files

	
< > Input
Python
!ls -l
Copied
>_ Output
			
total 4
-rw--w--w- 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt
-rw-r--r-- 1 root root 0 dic 6 01:22 rootfile.txt
lrwxrwxrwx 1 wallabot wallabot 29 dic 6 01:28 web -&gt; /home/wallabot/Documentos/web

We see the symbolic link web pointing to /home/wallabot/Documentos/web:

I can now go to web

	
< > Input
Python
terminal("cd web")
Copied
	
< > Input
Python
!pwd
Copied
>_ Output
			
/home/wallabot/Documentos/web

Configure the environment variableslink image 124

View environment variables with printenvlink image 125

With the printenv command, we can see all the environment variables

	
< > Input
Python
!printenv
Copied
>_ Output
			
GJS_DEBUG_TOPICS=JS ERROR;JS LOG
VSCODE_CWD=/home/wallabot
LESSOPEN=| /usr/bin/lesspipe %s
CONDA_PROMPT_MODIFIER=(base)
PYTHONIOENCODING=utf-8
USER=wallabot
VSCODE_NLS_CONFIG={"locale":"es","availableLanguages":{"*":"es"},"_languagePackId":"b07c40c9acb9e1d7b3ca14b06f814803.es","_translationsConfigFile":"/home/wallabot/.config/Code/clp/b07c40c9acb9e1d7b3ca14b06f814803.es/tcf.json","_cacheRoot":"/home/wallabot/.config/Code/clp/b07c40c9acb9e1d7b3ca14b06f814803.es","_resolvedLanguagePackCoreLocation":"/home/wallabot/.config/Code/clp/b07c40c9acb9e1d7b3ca14b06f814803.es/6261075646f055b99068d3688932416f2346dd3b","_corruptedFile":"/home/wallabot/.config/Code/clp/b07c40c9acb9e1d7b3ca14b06f814803.es/corrupted.info","_languagePackSupport":true}
VSCODE_HANDLES_UNCAUGHT_ERRORS=true
MPLBACKEND=module://ipykernel.pylab.backend_inline
SSH_AGENT_PID=1373
XDG_SESSION_TYPE=x11
SHLVL=0
HOME=/home/wallabot
CHROME_DESKTOP=code-url-handler.desktop
CONDA_SHLVL=1
DESKTOP_SESSION=ubuntu
GIO_LAUNCHED_DESKTOP_FILE=/usr/share/applications/code.desktop
VSCODE_IPC_HOOK=/run/user/1000/vscode-26527400-1.73.1-main.sock
PYTHONUNBUFFERED=1
GTK_MODULES=gail:atk-bridge
...
QT_IM_MODULE=ibus
GIT_PAGER=cat
PWD=/home/wallabot/Documentos/web
CLICOLOR=1
XDG_DATA_DIRS=/usr/share/ubuntu:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop
XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg
VSCODE_CODE_CACHE_PATH=/home/wallabot/.config/Code/CachedData/6261075646f055b99068d3688932416f2346dd3b
CONDA_EXE=/home/wallabot/anaconda3/bin/conda
CONDA_PREFIX=/home/wallabot/anaconda3
VSCODE_PID=3897

View an environment variable with the echo commandlink image 126

To see a specific environment variable, we can do it using the echo command followed by the $ symbol and the variable name

	
< > Input
Python
!echo $HOME
Copied
>_ Output
			
/home/wallabot

Modify an environment variable for a terminal sessionlink image 127

We can modify an environment variable for the active terminal session; for example, let's add a new path to the PATH variable. First, let's see what's in it.

	
< > Input
Python
!echo $PATH
Copied
>_ Output
			
/home/wallabot/anaconda3/bin:/home/wallabot/anaconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Now we add a new directory

	
< > Input
Python
!PATH=$PATH:"subdirectorio
Copied
>_ Output
			

We’ll look again at what’s inside PATH

	
< > Input
Python
!echo $PATH
Copied
>_ Output
			
/home/wallabot/anaconda3/bin:/home/wallabot/anaconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:subdirectorio

We see that the subdirectory directory has been added.

The problem with this method is that when we open a new terminal, this change in PATH will not be retained

Modify an environment variable for all terminal sessionslink image 128

We're going to the home folder

	
< > Input
Python
terminal("cd /home/wallabot")
Copied

Here, on the home page, we list all files with the -a (all) flag

	
< > Input
Python
!ls -a
Copied
>_ Output
			
. .eclipse .pki
.. Escritorio Plantillas
.afirma .gitconfig .platformio
anaconda3 .gnupg .profile
.audacity-data ImΓ‘genes .psensor
.bash_history .ipython PΓΊblico
.bash_logout .java .python_history
.bashrc .jupyter snap
.cache .lesshst .ssh
.conda Lightworks .sudo_as_admin_successful
.config .Lightworks.thereCanBeOnlyOne .thunderbird
.cortex-debug .local VΓ­deos
.cyberghost logiops .vnc
.dbus .MCTranscodingSDK .vscode
Descargas .mozilla .wget-hsts
.docker MΓΊsica
Documentos .nv

We see that there is a file called .bashrc; this file contains the configuration for our bash

	
< > Input
Python
terminal("cat .bashrc", max_lines_output=3)
Copied
>_ Output
			
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
...
fi
unset __conda_setup
# &lt;&lt;&lt; conda initialize &lt;&lt;&lt;

This file is the one that configures the terminal every time a new one is opened, so if we edit the PATH variable in it, this change will remain for all new terminal windows we open

To modify the PATH variable within the configuration file, we need to add the following line to the file

PATH=$PATH:"subdirectory"

Create alias for all sessionslink image 129

We already saw how to create command aliases, but it also happened that they were lost every time we closed a terminal session. To prevent this from happening, we also added them to the .bashrc configuration file. For example, in my case I have added the following lines

alias ll='ls -l'
alias la='ls -a'
alias lh='ls -h'
alias lha='ls -lha'

The first search command we are going to see is which, which allows us to find the path of binaries

	
< > Input
Python
!which python
Copied
>_ Output
			
/home/wallabot/anaconda3/bin/python

However, if we look for something that is not in any of the PATH routes, which will not be able to tell us the path

	
< > Input
Python
!which cd
Copied

To search for a file with find, we need to indicate the path from which we want to search for the file, followed by the -name flag and the name of the file we want to search for.

	
< > Input
Python
!find ~ -name "2021-02-11-Introduccion-a-Python.ipynb"
Copied
>_ Output
			
/home/wallabot/Documentos/web/portafolio/posts/prueba/2021-02-11-Introduccion-a-Python.ipynb
/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb

As we can see, it is in your directory, plus the copy I created in this notebook and saved in the prueba folder

One very powerful thing about find is that we can use wildcards; for example, if I want to search for all the text files in my web folder.

	
< > Input
Python
!find ~/Documentos/web/ -name *.txt
Copied
>_ Output
			
/home/wallabot/Documentos/web/portafolio/posts/2022-09-12 Introduccion a la terminal.txt
/home/wallabot/Documentos/web/portafolio/posts/prueba/lista.txt
/home/wallabot/Documentos/web/portafolio/posts/prueba/dot.txt
/home/wallabot/Documentos/web/portafolio/posts/prueba/dot2.txt
/home/wallabot/Documentos/web/portafolio/posts/prueba/secuential.txt
/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio/rootfile.txt
/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio/mitexto.txt
/home/wallabot/Documentos/web/portafolio/posts/prueba/file.txt
/home/wallabot/Documentos/web/wordpress_api_rest/page.txt

If we do not want it to distinguish between uppercase and lowercase letters, we must use the -iname flag. For example, if we search for all files that contain the text FILE, but using the -iname flag.

	
< > Input
Python
!find ~/Documentos/web/ -iname *FILE*
Copied
>_ Output
			
/home/wallabot/Documentos/web/portafolio/posts/html_files
/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio/rootfile.txt
/home/wallabot/Documentos/web/portafolio/posts/prueba/file.txt

We see that all the results contain file and not FILE, that is, it has not made a distinction between uppercase and lowercase letters

We can specify the file type with the -type flag. It only supports two types: f for files and d for directories.

	
< > Input
Python
!find ~/Documentos/nerf -name image*
Copied
>_ Output
			
/home/wallabot/Documentos/nerf/instant-ngp/configs/image
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/tiny-cuda-nn/benchmarks/image
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/tiny-cuda-nn/dependencies/cutlass/media/images
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/tiny-cuda-nn/dependencies/fmt/doc/bootstrap/mixins/image.less
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/tiny-cuda-nn/data/images
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/dlss/NVIDIAImageScaling/samples/media/images
/home/wallabot/Documentos/nerf/instant-ngp/data/nerf/fox/images
/home/wallabot/Documentos/nerf/instant-ngp/data/image
	
< > Input
Python
!find ~/Documentos/nerf -name image* -type d
Copied
>_ Output
			
/home/wallabot/Documentos/nerf/instant-ngp/configs/image
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/tiny-cuda-nn/benchmarks/image
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/tiny-cuda-nn/dependencies/cutlass/media/images
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/tiny-cuda-nn/data/images
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/dlss/NVIDIAImageScaling/samples/media/images
/home/wallabot/Documentos/nerf/instant-ngp/data/nerf/fox/images
/home/wallabot/Documentos/nerf/instant-ngp/data/image
	
< > Input
Python
!find ~/Documentos/nerf -name image* -type f
Copied
>_ Output
			
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/tiny-cuda-nn/dependencies/fmt/doc/bootstrap/mixins/image.less

If we want to filter by file size, we can use the -size flag. For example, if we want to find all files larger than 200 MB

	
< > Input
Python
!find ~/Documentos/ -type f -size +200M
Copied
>_ Output
			
/home/wallabot/Documentos/kaggle/hubmap/models/13_efficientnet-b7_final_model.pth
/home/wallabot/Documentos/kaggle/hubmap/models/12_efficientnet-b7_final_model.pth
/home/wallabot/Documentos/kaggle/hubmap/models/14_resnet152_final_model.pth
/home/wallabot/Documentos/kaggle/hubmap/models/14_resnet152_best_model.pth
/home/wallabot/Documentos/kaggle/hubmap/models/12_efficientnet-b7_early_stopping.pth
/home/wallabot/Documentos/kaggle/hubmap/models/efficientnet-b7-dcc49843.pth
/home/wallabot/Documentos/kaggle/hubmap/models/13_efficientnet-b7_early_stopping.pth
/home/wallabot/Documentos/kaggle/hubmap/models/14_resnet152_early_stopping.pth
/home/wallabot/Documentos/kaggle/hubmap/models/12_efficientnet-b7_best_model.pth
/home/wallabot/Documentos/kaggle/hubmap/models/13_efficientnet-b7_best_model.pth

If we want to perform operations after the search, we use the -exec flag

For example, I’m going to search for all folders named subdirectory

	
< > Input
Python
!find ~/ -name subdirectorio -type d
Copied
>_ Output
			
/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio

Can I make them be deleted with the -exec flag

	
< > Input
Python
!find ~/ -name subdirectorio -type d -exec rm -r {} ;
Copied
>_ Output
			
rm: ΒΏborrar el fichero regular vacΓ­o '/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio/rootfile.txt' protegido contra escritura? (s/n) s
find: β€˜/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio’: No existe el archivo o el directorio
	
< > Input
Python
!find ~/ -name subdirectorio -type d
Copied

Lastly, if we use the ! character, we will be indicating that it finds everything that does not match what we have specified

	
< > Input
Python
!find ~/Documentos/web/portafolio/posts/prueba ! -name *.txt
Copied
>_ Output
			
/home/wallabot/Documentos/web/portafolio/posts/prueba
/home/wallabot/Documentos/web/portafolio/posts/prueba/index.html
/home/wallabot/Documentos/web/portafolio/posts/prueba/Abc
/home/wallabot/Documentos/web/portafolio/posts/prueba/datos1
/home/wallabot/Documentos/web/portafolio/posts/prueba/2021-02-11-Introduccion-a-Python.ipynb
/home/wallabot/Documentos/web/portafolio/posts/prueba/datos123

As we can see, it has found everything that is not a .txt

grep is a very powerful search command, which is why we dedicate a section to it on its own. The grep command uses regular expressions, so if you want to learn about them, I’ll leave you a link to a post where I explain them

Let's start to see the power of this command; let's look for all the times the text MΓ‘ximoFN appears inside the file 2021-02-11-Introduccion-a-Python.ipynb

	
< > Input
Python
terminal("cd /home/wallabot/Documentos/web/portafolio/posts/prueba")
Copied
	
< > Input
Python
terminal("grep MaximoFN 2021-02-11-Introduccion-a-Python.ipynb", max_lines_output=20)
Copied
>_ Output
			
"a = 'MaximoFN' ",
"'MaximoFN'"
"string = "MaximoFN" ",
"'MaximoFN'"
"string = 'MaximoFN' ",
"'MaximoFN'"
"Este es el blog de "MaximoFN" "
"print("Este es el blog de \"MaximoFN\"")"
"Este es el blog de 'MaximoFN' "
"print('Este es el blog de \'MaximoFN\'')"
"Este es el blog de \MaximoFN\ "
"print('Este es el blog de \\MaximoFN\\')"
"MaximoFN "
"print('Este es el blog de \nMaximoFN')"
"Este es el blog de MaximoFN "
"print('Esto no se imprimirΓ‘ \rEste es el blog de MaximoFN')"
"Este es el blog de MaximoFN "
"print('Este es el blog de \tMaximoFN')"
"Este es el blog deMaximoFN "
"print('Este es el blog de \bMaximoFN')"
...
"funcion2_del_modulo('MaximoFN')"
"MaximoFN ",
" print('MaximoFN') ",
" variable = 'MaximoFN' ",

However, if we do the same search for the text maximofn

	
< > Input
Python
!grep maximofn 2021-02-11-Introduccion-a-Python.ipynb
Copied

No results appear, this is because grep is case sensitive, that is, it looks for the text exactly as you entered it, distinguishing between uppercase and lowercase letters. If we do not want this, we have to add the -i flag

	
< > Input
Python
terminal("grep -i MaximoFN 2021-02-11-Introduccion-a-Python.ipynb", max_lines_output=20)
Copied
>_ Output
			
"a = 'MaximoFN' ",
"'MaximoFN'"
"string = "MaximoFN" ",
"'MaximoFN'"
"string = 'MaximoFN' ",
"'MaximoFN'"
"Este es el blog de "MaximoFN" "
"print("Este es el blog de \"MaximoFN\"")"
"Este es el blog de 'MaximoFN' "
"print('Este es el blog de \'MaximoFN\'')"
"Este es el blog de \MaximoFN\ "
"print('Este es el blog de \\MaximoFN\\')"
"MaximoFN "
"print('Este es el blog de \nMaximoFN')"
"Este es el blog de MaximoFN "
"print('Esto no se imprimirΓ‘ \rEste es el blog de MaximoFN')"
"Este es el blog de MaximoFN "
"print('Este es el blog de \tMaximoFN')"
"Este es el blog deMaximoFN "
"print('Este es el blog de \bMaximoFN')"
...
"funcion2_del_modulo('MaximoFN')"
"MaximoFN ",
" print('MaximoFN') ",
" variable = 'MaximoFN' ",

If what we want is for it to return the number of times it appears, we add the -c flag

	
< > Input
Python
!grep -c MaximoFN 2021-02-11-Introduccion-a-Python.ipynb
Copied
>_ Output
			
105

If we don’t care whether it appears in uppercase or lowercase, we can add the -i flag again, but there’s no need to add it separately from the -c flag; they can be used together.

	
< > Input
Python
!grep -ci MaximoFN 2021-02-11-Introduccion-a-Python.ipynb
Copied
>_ Output
			
105

If now we want all the times in which **not** the word MΓ‘ximoFN appears, we add the -v flag

	
< > Input
Python
!grep -cv MaximoFN 2021-02-11-Introduccion-a-Python.ipynb
Copied
>_ Output
			
11573

---

➑️ **Continue in Part 2: networking, compression and processes**, where you will learn how to move around the network and control system processes.

Full series

Continue reading

Last posts -->

Have you seen these projects?

Gymnasia

Gymnasia Gymnasia
React Native
Expo
TypeScript
FastAPI
Next.js
OpenAI
Anthropic

Mobile personal training app with AI assistant, exercise library, workout tracking, diet and body measurements

Horeca chatbot

Horeca chatbot Horeca chatbot
Python
LangChain
PostgreSQL
PGVector
React
Kubernetes
Docker
GitHub Actions

Chatbot conversational for cooks of hotels and restaurants. A cook, kitchen manager or room service of a hotel or restaurant can talk to the chatbot to get information about recipes and menus. But it also implements agents, with which it can edit or create new recipes or menus

View all projects -->
>_ Available for projects

Do you have an AI project?

Let's talk.

maximofn@gmail.com

Machine Learning and AI specialist. I develop solutions with generative AI, intelligent agents and custom models.

Do you want to watch any talk?

Last talks -->

Do you want to improve with these tips?

Last tips -->

Use this locally

Hugging Face spaces allow us to run models with very simple demos, but what if the demo breaks? Or if the user deletes it? That's why I've created docker containers with some interesting spaces, to be able to use them locally, whatever happens. In fact, if you click on any project view button, it may take you to a space that doesn't work.

Flow edit

Flow edit Flow edit

FLUX.1-RealismLora

FLUX.1-RealismLora FLUX.1-RealismLora
View all containers -->
>_ Available for projects

Do you have an AI project?

Let's talk.

maximofn@gmail.com

Machine Learning and AI specialist. I develop solutions with generative AI, intelligent agents and custom models.

Do you want to train your model with these datasets?

short-jokes-dataset

HuggingFace

Dataset with jokes in English

Use: Fine-tuning text generation models for humor

231K rows 2 columns 45 MB
View on HuggingFace β†’

opus100

HuggingFace

Dataset with translations from English to Spanish

Use: Training English-Spanish translation models

1M rows 2 columns 210 MB
View on HuggingFace β†’

netflix_titles

HuggingFace

Dataset with Netflix movies and series

Use: Netflix catalog analysis and recommendation systems

8.8K rows 12 columns 3.5 MB
View on HuggingFace β†’
View more datasets -->