Introducción a la terminal
Formato del post
Para no tener que estar poniendo imágenes de la consola en cada acción que haga, he creado la siguiente función que recibe el comando de la terminal que queramos ejecutar y devuelve la salida que nos daría la terminal.
Unas veces usaré esta función, y otras usaré !
antes de cada comando, que en notebooks quiere decir que vas a ejecutar un comando de la terminal.
import subprocessimport oslast_directory = ''def terminal(command, max_lines_output=None):global last_directorydebug = Falsestr = command.split()# Check if there are " or ' charactersfor i in range(len(str)):if debug: print(f"i = {i}, str[i] = {str[i]}")if len(str[i]) > 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 stringsstr = [x for x in str if x != ""]if debug:print(str)returnif 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_direlse: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)
Primeros comandos para moverse por la terminal
ls
(list directory)
El primer comando que vamos a ver es ls
(list directory) que sirve para listar todos los archivos de la carpeta en la que estemos.
import subprocessimport oslast_directory = ''def terminal(command, max_lines_output=None):global last_directorydebug = Falsestr = command.split()# Check if there are " or ' charactersfor i in range(len(str)):if debug: print(f"i = {i}, str[i] = {str[i]}")if len(str[i]) > 0:if str[i][0] == '"' or str[i][0] == "'":for j in range(i+1,len(str)):if debug: print(f"\t 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 stringsstr = [x for x in str if x != ""]if debug:print(str)returnif 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_direlse:result = subprocess.run(str, stdout=subprocess.PIPE).stdout.decode('utf-8')if max_lines_output is not None:result_split = result.split('\n')print('\n'.join(result_split[:max_lines_output]))print("\t ...")print('\n'.join(result_split[-5:]))else:print(result)terminal("ls")
2021-02-11-Introduccion-a-Python.ipynb2021-04-23-Calculo-matricial-con-Numpy.ipynb2021-06-15-Manejo-de-datos-con-Pandas.ipynb2022-09-12 Introduccion a la terminal.ipynb2022-09-12 Introduccion a la terminal.txtcommand-line-cheat-sheet.pdfCSS.ipynbDocker.htmlDocker.ipynbExpresiones regulares.htmlExpresiones regulares.ipynbhtml_fileshtml.ipynbintroduccion_pythonmovies.csvmovies.datnotebooks_translated__pycache__ssh.ipynbtest.htmltest.ipynb
Los comandos normalmente pueden recibir opciones (flags
), que se introducen con el carácter -
, por ejemplo veamos ls -l
que nos devuelve la lista de archivos del directorio en el que estamos, pero con más información
terminal('ls -l')
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.ipynbdrwxrwxr-x 2 wallabot wallabot 4096 nov 28 14:39 html_files-rw-rw-r-- 1 wallabot wallabot 14775 sep 18 03:29 html.ipynbdrwxrwxr-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.datdrwxrwxr-x 2 wallabot wallabot 4096 nov 28 14:39 notebooks_translateddrwxrwxr-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
Como vemos, tenemos cuántos bytes ocupa cada archivo, pero cuando tenemos archivos que ocupan mucho esto no es muy fácil de leer, así que podemos añadir la opción h
(human
) que nos da información más fácil de leer
terminal('ls -lh')
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.ipynbdrwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 html_files-rw-rw-r-- 1 wallabot wallabot 15K sep 18 03:29 html.ipynbdrwxrwxr-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.datdrwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 notebooks_translateddrwxrwxr-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
Si queremos ver los archivos ocultos podemos usar la opción a
, que nos mostrará todos los archivos de un directorio
terminal('ls -lha')
total 4,5Mdrwxrwxr-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.ipynbdrwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 html_files-rw-rw-r-- 1 wallabot wallabot 15K sep 18 03:29 html.ipynbdrwxrwxr-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.datdrwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 notebooks_translateddrwxrwxr-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
Si lo que queremos es que nos los ordene por tamaño, podemos usar la opción S
terminal('ls -lhS')
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.ipynbdrwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 html_filesdrwxrwxr-x 3 wallabot wallabot 4,0K nov 12 01:51 introduccion_pythondrwxrwxr-x 2 wallabot wallabot 4,0K nov 28 14:39 notebooks_translateddrwxrwxr-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
Si queremos que nos muestre los archivos ordenados alfabéticamente, pero al revés, debemos usar la opción -r
terminal('ls -lhr')
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.ipynbdrwxrwxr-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.csvdrwxrwxr-x 3 wallabot wallabot 4,0K nov 12 01:51 introduccion_python-rw-rw-r-- 1 wallabot wallabot 15K sep 18 03:29 html.ipynbdrwxrwxr-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)
El segundo comando será cd
(change directory) que nos permite cambiar de directorio
terminal('cd /home/wallabot/Documentos/')
Si ahora volvemos a usar ls
para ver los archivos que tenemos, vemos que cambian
terminal('cd /home/wallabot/Documentos/')terminal('ls')
aprendiendo-git.pdfbalena-etcher-electron-1.7.9-linux-x64camerasIPDocumentaciongstreamergstreamer_oldjetsonNanokaggleLibrosnerfprueba.txtpytorchwallabotweb
Si a cd
, en vez de darle el directorio al que nos queremos mover, le damos el carácter -
, volverá al anterior directorio donde estaba
terminal('cd -')
terminal('cd -')terminal('ls')
2021-02-11-Introduccion-a-Python.ipynb2021-04-23-Calculo-matricial-con-Numpy.ipynb2021-06-15-Manejo-de-datos-con-Pandas.ipynb2022-09-12 Introduccion a la terminal.ipynb2022-09-12 Introduccion a la terminal.txtcommand-line-cheat-sheet.pdfCSS.ipynbDocker.htmlDocker.ipynbExpresiones regulares.htmlExpresiones regulares.ipynbhtml_fileshtml.ipynbintroduccion_pythonmovies.csvmovies.datnotebooks_translated__pycache__ssh.ipynbtest.htmltest.ipynb
Si nos quisiéramos mover a la home
con introducir solamente cd
en la terminal nos llevará.
terminal('cd')
pwd
(print working directory)
Para obtener el directorio en el que estamos, podemos usar pwd
(print working directory)
terminal('cd')terminal('pwd')
/home/wallabot
Podemos movernos mediante el comando cd
mediante rutas relativas y mediante rutas absolutas. Por ejemplo, vamos a movernos a un directorio mediante una ruta absoluta.
terminal('cd /home/wallabot/Documentos/')
terminal('cd /home/wallabot/Documentos/')terminal('pwd')
/home/wallabot/Documentos
terminal('ls')
aprendiendo-git.pdfbalena-etcher-electron-1.7.9-linux-x64camerasIPDocumentaciongstreamergstreamer_oldjetsonNanokaggleLibrosnerfprueba.txtpytorchwallabotweb
Podemos movernos mediante rutas relativas si solo ponemos la dirección a partir del punto en que nos encontramos
terminal('cd web')
terminal('cd web')terminal('pwd')
/home/wallabot/Documentos/web
También mediante rutas relativas podemos ir un directorio arriba mediante ..
terminal('cd ..')
terminal('cd ..')terminal('pwd')
/home/wallabot/Documentos
Si en vez de ..
ponemos .
nos estamos refiriendo al directorio en el que nos encontramos ahora mismo, es decir, si ponemos cd .
no nos moveremos, ya que le estamos diciendo a la terminal que vaya al directorio en el que estamos.
terminal('cd .')
terminal('cd .')terminal('pwd')
/home/wallabot/Documentos
Vamos a movernos a una ruta en la que tengamos archivos para mostrar el siguiente comando
terminal('cd web/portafolio/posts/')
terminal('cd web/portafolio/posts/')terminal('ls')
2021-02-11-Introduccion-a-Python.ipynb2021-04-23-Calculo-matricial-con-Numpy.ipynb2021-06-15-Manejo-de-datos-con-Pandas.ipynb2022-09-12 Introduccion a la terminal.ipynb2022-09-12 Introduccion a la terminal.txtcommand-line-cheat-sheet.pdfCSS.ipynbDocker.htmlDocker.ipynbExpresiones regulares.htmlExpresiones regulares.ipynbhtml_fileshtml.ipynbintroduccion_pythonmovies.csvmovies.datnotebooks_translated__pycache__ssh.ipynbtest.htmltest.ipynb
Información de archivos con file
Si yo no sé qué tipo de archivo es alguno en particular, mediante el comando file
puedo obtener una descripción
terminal('file 2021-02-11-Introduccion-a-Python.ipynb')
2021-02-11-Introduccion-a-Python.ipynb: UTF-8 Unicode text, with very long lines
Manipulando archivos y directorios
Movámonos primero a la home.
terminal('cd /home/wallabot/Documentos/')
Árbol de directorios con tree
Podemos ver toda la estructura de la carpeta en la que estamos mediante el comando tree
terminal('cd /home/wallabot/Documentos/')terminal('tree', max_lines_output=20)
.├── 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.py873 directories, 119679 files
Pero a la salida tenemos demasiadas líneas, y esto es porque tree
es un comando que muestra todos los archivos desde la ruta en la que estamos, por lo que es un poco difícil de leer. Sin embargo, con la opción L
podemos indicarle en cuántos niveles queremos que profundice
terminal('tree -L 2')
.├── 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├── jetsonNano│ ├── apuntes-Jetson-Nano│ ├── deepstream_apps│ ├── deepstream_nano│ └── Digital zoom├── kaggle│ └── hubmap├── Libros│ └── aprendiendo-git.pdf├── nerf│ └── instant-ngp├── prueba.txt├── pytorch│ └── Curso_Pytorch├── wallabot│ ├── Microfono - Blue Yeti X│ ├── placa base - Asus prime x570-p│ └── Silla - Corsair T3 Rush└── web├── jupyter-to-html├── jupyter-translator├── portafolio└── wordpress_api_rest30 directories, 12 files
Podemos ver que muestra que hay 30 directorios y 12 archivos, mientras que antes indicaba 873 directorios, 119679 archivos
Crear carpetas con mkdir
(make directory)
Si queremos crear un nuevo directorio podemos usar el comando mkdir
(make directory) y un nombre
terminal("cd /home/wallabot/Documentos/web/portafolio/posts/")
terminal("cd /home/wallabot/Documentos/web/portafolio/posts/")terminal('mkdir prueba')
terminal('ls')
2021-02-11-Introduccion-a-Python.ipynb2021-04-23-Calculo-matricial-con-Numpy.ipynb2021-06-15-Manejo-de-datos-con-Pandas.ipynb2022-09-12 Introduccion a la terminal.ipynb2022-09-12 Introduccion a la terminal.txtcommand-line-cheat-sheet.pdfCSS.ipynbDocker.htmlDocker.ipynbExpresiones regulares.htmlExpresiones regulares.ipynbhtml_fileshtml.ipynbintroduccion_pythonmovies.csvmovies.datnotebooks_translatedprueba__pycache__ssh.ipynbtest.htmltest.ipynb
Si lo que queremos es crear un directorio con espacios en el nombre, tenemos que poner el nombre entre comillas.
terminal('mkdir "directorio prueba"')
terminal('ls')
2021-02-11-Introduccion-a-Python.ipynb2021-04-23-Calculo-matricial-con-Numpy.ipynb2021-06-15-Manejo-de-datos-con-Pandas.ipynb2022-09-12 Introduccion a la terminal.ipynb2022-09-12 Introduccion a la terminal.txtcommand-line-cheat-sheet.pdfCSS.ipynbdirectorio pruebaDocker.htmlDocker.ipynbExpresiones regulares.htmlExpresiones regulares.ipynbhtml_fileshtml.ipynbintroduccion_pythonmovies.csvmovies.datnotebooks_translatedprueba__pycache__ssh.ipynbtest.htmltest.ipynb
Vamos a meternos dentro de la carpeta prueba
que hemos creado, para seguir viendo allí la terminal
terminal("cd prueba")
Crear archivos con touch
En caso de que queramos crear un archivo, el comando que tenemos que usar es touch
terminal("cd prueba")terminal("touch prueba.txt")
terminal("ls")
prueba.txt
Copiar archivos con cp
(copy)
Si queremos copiar un archivo lo hacemos mediante el comando cp
(copy)
terminal("cp prueba.txt prueba_copy.txt")
terminal("ls")
prueba_copy.txtprueba.txt
Mover archivos con mv
(move)
Si lo que queremos es moverlo, lo que usamos es el comando mv
(move)
terminal("mv prueba.txt ../prueba.txt")
terminal("ls")
prueba_copy.txt
terminal("ls ../")
2021-02-11-Introduccion-a-Python.ipynb2021-04-23-Calculo-matricial-con-Numpy.ipynb2021-06-15-Manejo-de-datos-con-Pandas.ipynb2022-09-12 Introduccion a la terminal.ipynb2022-09-12 Introduccion a la terminal.txtcommand-line-cheat-sheet.pdfCSS.ipynbdirectorio pruebaDocker.htmlDocker.ipynbExpresiones regulares.htmlExpresiones regulares.ipynbhtml_fileshtml.ipynbintroduccion_pythonmovies.csvmovies.datnotebooks_translatedpruebaprueba.txt__pycache__ssh.ipynbtest.htmltest.ipynb
Renombrar archivos con mv
(move)
El comando mv
también nos sirve para renombrar ficheros, ya que si lo que hacemos es moverlo en el mismo directorio, pero dándole otro nombre, al final eso es renombrar el archivo.
terminal("mv prueba_copy.txt prueba_move.txt")
terminal("ls")
prueba_move.txt
Borrar archivos con rm
(remove)
Para borrar archivos o directorios usamos el comando rm
(remove)
terminal("rm prueba_move.txt")
terminal("ls")
Eliminar directorios con rm -r
(remove recursive)
Si lo que queremos es eliminar un directorio con archivos dentro, debemos usar el flag -r
.
terminal("cd ..")
terminal("cd ..")terminal('rm -r "directorio prueba"')
terminal("ls")
2021-02-11-Introduccion-a-Python.ipynb2021-04-23-Calculo-matricial-con-Numpy.ipynb2021-06-15-Manejo-de-datos-con-Pandas.ipynb2022-09-12 Introduccion a la terminal.ipynb2022-09-12 Introduccion a la terminal.txtcommand-line-cheat-sheet.pdfCSS.ipynbDocker.htmlDocker.ipynbExpresiones regulares.htmlExpresiones regulares.ipynbhtml_fileshtml.ipynbintroduccion_pythonmovies.csvmovies.datnotebooks_translatedpruebaprueba.txt__pycache__ssh.ipynbtest.htmltest.ipynb
Como puedes ver nunca pregunta si estamos seguros, para que pregunte hay que añadir el flag -i
(iteractive
)
terminal("rm -i prueba.txt")
rm: ¿borrar el fichero regular vacío 'prueba.txt'? (s/n) s
Sincronizar archivos mediante rsync
Hasta ahora hemos visto cómo copiar, mover y eliminar archivos, pero supongamos que tenemos una carpeta y copiamos esos archivos a otra. Ahora supongamos que modificamos un archivo de la primera carpeta y queremos que la segunda tenga los cambios. Tenemos dos opciones, volver a copiar todos los archivos, o hacer una sincronización mediante rsync
Primero vamos a crear una nueva carpeta en la que creemos varios archivos
!mkdir sourcefolder!touch sourcefolder/file1 sourcefolder/file2 sourcefolder/file3
Ahora creamos una segunda carpeta que es la que vamos a sincronizar con la primera
!mkdir sourcefolder!touch sourcefolder/file1 sourcefolder/file2 sourcefolder/file3!mkdir syncfolder
!mkdir sourcefolder!touch sourcefolder/file1 sourcefolder/file2 sourcefolder/file3!mkdir syncfolder!echo "ls sourcefolder:" && ls sourcefolder && echo "ls syncfolder:" && ls syncfolder
ls sourcefolder:file1 file2 file3ls syncfolder:
Sincronizamos las dos carpetas con rsync
, la primera vez solo copiará los archivos de la primera carpeta a la segunda. Para hacer esto, además debemos añadir el flag -r
(recursive)
!rsync -r sourcefolder/ syncfolder/
!rsync -r sourcefolder/ syncfolder/!echo "ls sourcefolder:" && ls sourcefolder && echo "ls syncfolder:" && ls syncfolder
ls sourcefolder:file1 file2 file3ls syncfolder:file1 file2 file3
Si ahora creo un nuevo archivo en sourcefolder
y vuelvo a sincronizar, se copia solo ese archivo en syncfolder
. Para ver que solo se copia un archivo podemos usar el flag -v
(verbose)
!touch sourcefolder/file4
!touch sourcefolder/file4!rsync -r -v sourcefolder/ syncfolder/
sending incremental file listfile1file2file3file4sent 269 bytes received 92 bytes 722.00 bytes/sectotal size is 0 speedup is 0.00
Pero parece que ha copiado todos los archivos, así que para que esto no pase y copie solo los que se han modificado hay que usar el flag -u
!touch sourcefolder/file5
!touch sourcefolder/file5!rsync -r -v -u sourcefolder/ syncfolder/
sending incremental file listfile5sent 165 bytes received 35 bytes 400.00 bytes/sectotal size is 0 speedup is 0.00
!echo "ls sourcefolder:" && ls sourcefolder && echo "ls syncfolder:" && ls syncfolder
ls sourcefolder:file1 file2 file3 file4 file5ls syncfolder:file1 file2 file3 file4 file5
¿Y qué pasa si creo un archivo nuevo en syncfolder
?
!touch syncfolder/file6
!touch syncfolder/file6!rsync -r -v -u sourcefolder/ syncfolder/
sending incremental file listsent 122 bytes received 12 bytes 268.00 bytes/sectotal size is 0 speedup is 0.00
!echo "ls sourcefolder:" && ls sourcefolder && echo "ls syncfolder:" && ls syncfolder
ls sourcefolder:file1 file2 file3 file4 file5ls syncfolder:file1 file2 file3 file4 file5 file6
No lo sincroniza, así que es importante tener esto en cuenta
Algunos flags importantes que hay que tener en cuenta son:
-a
: Este flag es un atajo para varias opciones, incluyendo-r
(recursivo),-l
(copiar enlaces simbólicos),-p
(mantener permisos),-t
(mantener la hora de modificación) y-g
(mantener grupo). Esta opción es útil para hacer una copia exacta de un directorio, incluyendo todas sus subcarpetas y archivos.-v
: Este flag activa la salida detallada, que muestra los archivos que se están copiando y el progreso de la operación.-r
: Este flag es utilizado para copiar de forma recursiva, lo que significa que copia todas las subcarpetas y archivos dentro de un directorio.-u
: Este flag es utilizado para copiar solo los archivos nuevos o modificados. Si un archivo ya existe en el destino y es más reciente que el archivo de origen, no se copia.-n
: Este flag se utiliza para hacer una prueba de copia, lo que significa que no se realizan cambios en el destino.--exclude
: Este flag se utiliza para excluir archivos o carpetas específicos de la operación de copia. Puedes especificar varios archivos o carpetas para excluir utilizando esta opción varias veces.-z
: Este flag se utiliza para comprimir los datos durante la transferencia, lo que reduce el ancho de banda utilizado y acelera la velocidad de transferencia.-h
: este flag se usa para mostrar la información en un formato más legible, especialmente cuando se trabaja con grandes cantidades de datos o tamaños de archivos grandes.
Borramos las dos carpetas creadas
!rm -r sourcefolder syncfolder
Explorando el contenido de los archivos
Para no tener que abrir un archivo desde una interfaz gráfica tenemos varias formas. Voy a copiar un archivo de texto en esta carpeta lo primero.
!rm -r sourcefolder syncfolderterminal("cd prueba")
!rm -r sourcefolder syncfolderterminal("cd prueba")terminal("cp ../2021-02-11-Introduccion-a-Python.ipynb .")
terminal("ls")
2021-02-11-Introduccion-a-Python.ipynb
Cabecera de archivos con head
El primer comando para poder ver dentro de un archivo de texto es head
, que nos permite ver las primeras 10 líneas de un archivo, pero si se le mete el flag -n
puedes indicar el número de líneas
terminal("head 2021-02-11-Introduccion-a-Python.ipynb")
{"cells": [{"cell_type": "markdown","metadata": {"id": "dsaKCKL0IxZl"},"source": ["# Introducción a Python"]
terminal("head -n 5 2021-02-11-Introduccion-a-Python.ipynb")
{"cells": [{"cell_type": "markdown","metadata": {
Cola de un archivo con tail
En caso de querer ver las últimas líneas usamos tail
terminal("tail 2021-02-11-Introduccion-a-Python.ipynb")
},"vscode": {"interpreter": {"hash": "d5745ab6aba164e1152437c779991855725055592b9f2bdb41a4825db7168d26"}}},"nbformat": 4,"nbformat_minor": 0}
terminal("tail -n 5 2021-02-11-Introduccion-a-Python.ipynb")
}},"nbformat": 4,"nbformat_minor": 0}
Si queremos ver continuamente las últimas líneas de un archivo, por ejemplo, queremos estar monitorizando continuamente un archivo de LOG para ver eventos, añadimos el flag -f
, esto hará que la terminal se quede continuamente comprobando el archivo, y cada vez que aparezca una nueva línea en él la mostrará
Por ejemplo si yo monitoreo el log de inicio de sesión en mi máquina
!tail -f /var/log/auth.log
Dec 1 16:27:22 wallabot gcr-prompter[1457]: Gcr: calling the PromptDone method on /org/gnome/keyring/Prompt/p2@:1.26, and ignoring replyDec 1 16:27:22 wallabot gnome-keyring-daemon[1178]: asked to register item /org/freedesktop/secrets/collection/login/10, but it's already registeredDec 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, quittingDec 1 16:27:33 wallabot gcr-prompter[1457]: Gcr: unregistering prompterDec 1 16:27:33 wallabot gcr-prompter[1457]: Gcr: disposing prompterDec 1 16:27:33 wallabot gcr-prompter[1457]: Gcr: finalizing prompterDec 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
Vemos en las dos últimas líneas mi inicio de sesión cuando he encendido hoy mi ordenador.
Ahora me conecto por SSH a mi propia máquina
!ssh localhost
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/advantage1 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
En la consola donde estaba monitorizando el inicio de sesión han aparecido dos nuevas líneas
Dec 1 16:32:23 wallabot sshd[25647]: Accepted password for wallabot from 127.0.0.1 port 54668 ssh2Dec 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.
Y cuando cierro la sesión SSH aparecen otras dos líneas nuevas
Dec 1 16:33:52 wallabot sshd[25647]: pam_unix(sshd:session): session closed for user wallabotDec 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.
El visor de archivos más potente: less
Uno de los comandos más potentes para ver dentro de los archivos es less
terminal("less 2021-02-11-Introduccion-a-Python.ipynb", max_lines_output=20)
{"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}
Al estar dentro de un cuaderno no se puede ver lo que ocurre realmente al usar less
, pero cuando lo usamos nos metemos en el documento, podemos movernos a través de él mediante las teclas, o con el ratón
Si queremos buscar algo dentro del documento, escribimos el carácter /
y lo que queramos buscar. Para cambiar entre las distintas instancias que ha encontrado pulsamos la tecla n
, y si queremos volver hacia atrás en las búsquedas pulsamos shift+n
Para salir solo hay que pulsar q
El visor cat
No te permite navegar por el archivo ni hacer búsquedas.
terminal("cat 2021-02-11-Introduccion-a-Python.ipynb", max_lines_output=20)
{"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}
Editor por defecto del sistema xdg-open
Si lo queremos abrir con el editor por defecto del archivo, tenemos que usar xdg-open
terminal("xdg-open 2021-02-11-Introducción-a-Python.ipynb")
Navegador de archivos nautilus
Si lo que queremos es abrir la carpeta en la que estamos, usamos nautilus
terminal("nautilus")
Y si lo que queremos es que se abra en una ruta determinada, se incluye la ruta
terminal("nautilus ~/")
Contador de palabras de un archivo con wc
(word count)
Por último, un comando muy útil es wc
(word count), que te muestra cuántas líneas, palabras y bytes tiene un archivo
terminal("wc 2021-02-11-Introduccion-a-Python.ipynb")
11678 25703 285898 2021-02-11-Introduccion-a-Python.ipynb
Como vemos, el archivo tiene 11678 líneas, 25703 palabras y ocupa 285898 bytes
Qué es un comando
Un comando puede ser cuatro cosas
- Un programa ejecutable, éstos normalmente se guardan en la ruta
/usr/bin
- Un comando de shell
- Una función de shell
- Un alias
Para ver a qué clase pertenece un comando usamos type
!type cd
cd is a shell builtin
!type mkdir
mkdir is /usr/bin/mkdir
!type ls
ls is /usr/bin/ls
¿Qué es un alias?
Un alias es un comando que definimos nosotros, este se define mediante el comando alias
. Por ejemplo, vamos a crear el alias l
que lo que haga sea ls -h
!alias l='ls -l'
Cuando ejecutamos l
nos muestra el resultado de ls -h
!alias l='ls -l'!l
2021-02-11-Introducción-a-Python.ipynb
Pero esto tiene el problema, que cuando cerremos la terminal desaparece el alias
. Más adelante aprenderemos a crear alias
permanentes
Ayuda de los comandos
Ayuda con help
Con muchos comandos de la shell, podemos obtener su ayuda mediante el comando help
!help cd
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 lavariable de shell HOME.La variable CDPATH define la ruta de búsqueda para el directorio quecontiene DIR. Los nombres alternativos de directorio en CDPATH seseparan con dos puntos (:). Un nombre de directorio nulo es igual queel 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 enlacessimbólicos en DIR después de procesar las instancias de ".."-P usa la estructura física de directorios sin seguir los enlacessimbólicos: resuelve los enlaces simbólicos en DIR antes de procesarlas instancias de ".."-e si se da la opción -P y el directorio actual de trabajo no sepuede determinar con éxito, termina con un estado diferente de cero.La acción por defecto es seguir los enlaces simbólicos, como si seespecificara "-L".".." se procesa quitando la componente del nombre de la ruta inmediatamenteanterior hasta una barra inclinada o el comienzo de DIR.Estado de Salida:Devuelve 0 si se cambia el directorio, y si $PWD está definido comocorrecto cuando se emplee -P; de otra forma es diferente a cero.
Manual con man
Otro comando es man
, que hace referencia al manual de usuario.
terminal("man ls", max_lines_output=20)
LS(1) User Commands LS(1)NAMEls - list directory contentsSYNOPSISls [OPTION]... [FILE]...DESCRIPTIONList 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 optionstoo.-a, --alldo not ignore entries starting with .-A, --almost-all...Full documentation at: <https://www.gnu.org/software/coreutils/ls>or available locally via: info '(coreutils) ls invocation'GNU coreutils 8.30 September 2019 LS(1)
Para salir, pulsar q
, ya que man
utiliza a less
como visualizador del manual
Información con info
Otro comando es info
terminal("info ls", max_lines_output=20)
File: coreutils.info, Node: ls invocation, Next: dir invocation, Up: Directory listing10.1 ‘ls’: List directory contents==================================The ‘ls’ program lists information about files (of any type, includingdirectories). Options and file arguments can be intermixed arbitrarily,as usual.For non-option command-line arguments that are directories, bydefault ‘ls’ lists the contents of directories, not recursively, andomitting files with names beginning with ‘.’. For other non-optionarguments, by default ‘ls’ lists just the file name. If no non-optionargument is specified, ‘ls’ operates on the current directory, acting asif it had been invoked with a single argument of ‘.’.By default, the output is sorted alphabetically, according to thelocale settings in effect.(1) If standard output is a terminal, theoutput is in columns (sorted vertically) and control characters areoutput as question marks; otherwise, the output is listed one per line...‘--show-control-chars’Print nongraphic characters as-is in file names. This is thedefault unless the output is a terminal and the program is ‘ls’.
Para salir, pulsar q
, ya que info
utiliza a less
como visualizador de la información
Información de un comando con whatis
Otro comando es whatis
terminal("whatis ls")
ls (1) - list directory contents
Wildcards
Las wildcards son caracteres especiales que nos sirven para realizar búsquedas especiales. Por ejemplo, si quiero buscar todos los archivos que terminen en .txt
. Vamos a crear unos cuantos archivos para verlas.
terminal("touch file.txt dot.txt dot2.txt index.html datos1 datos123 Abc")
terminal("ls")
2021-02-11-Introduccion-a-Python.ipynbAbcdatos1datos123dot2.txtdot.txtfile.txtindex.html
Todos los caracteres *
Vamos a buscar ahora todos los archivos .txt
!ls *.txt
dot2.txt dot.txt file.txt
Vamos ahora a buscar todos los que empiecen por la palabra datos
!ls datos*
datos1 datos123
Números ?
Pero qué pasa si en realidad lo que queremos es que nos muestre todos los archivos que empiecen por la palabra datos
pero seguido solo de un número, tenemos que poner un signo de interrogación ?
!ls datos?
datos1
Si lo que queremos es que tenga tres números, entonces tenemos que poner tres signos de interrogación ???
!ls datos???
datos123
Mayúsculas [[:upper:]]
Si queremos que busque los archivos que empiecen por mayúsculas
!ls [[:upper:]]*
Abc
Minúsculas [[:lower:]]
Para los archivos que empiecen con minúsculas.
!ls [[:lower:]]*
datos1 datos123 dot2.txt dot.txt file.txt index.html
Clases
Mediante el uso de corchetes podemos crear clases, así si queremos buscar los archivos que empiecen por las letras d
o f
seguido de cualquier carácter
!ls [df]*
datos1 datos123 dot2.txt dot.txt file.txt
Redirecciones: cómo funciona la shell
Un comando funciona de la siguiente manera
Tiene un standard input
, que por defecto es el texto que introducimos por teclado, un standard output
, que por defecto es el texto que sale por consola y un standard error
que también es por defecto un texto que sale por consola, pero que tiene otro formato
Redirección del standard output
Pero con el carácter >
podemos modificar el standard output
de un comando. Por ejemplo, si queremos listar con ls
los archivos de la carpeta en la que estamos, pero no queremos que el resultado se imprima por pantalla, sino que se guarde en un archivo, haríamos lo siguiente ls > lista.txt
, esto escribe la lista en lista.txt
, además si lista.txt
no existe, lo crea
!ls > lista.txt
Vemos que ha creado el archivo y vemos qué hay dentro
!ls > lista.txtterminal("ls")
2021-02-11-Introduccion-a-Python.ipynbAbcdatos1datos123dot2.txtdot.txtfile.txtindex.htmllista.txt
terminal("cat lista.txt")
2021-02-11-Introduccion-a-Python.ipynbAbcdatos1datos123dot2.txtdot.txtfile.txtindex.htmllista.txt
Vemos que dentro de lista.txt
aparece lista.txt
, eso es porque primero crea el archivo y luego ejecuta el comando
Hacemos lo mismo, pero con la carpeta padre
!ls ../ > lista.txt
Si volvemos a ver dentro de lista.txt
!ls ../ > lista.txtterminal("cat lista.txt")
2021-02-11-Introduccion-a-Python.ipynb2021-04-23-Calculo-matricial-con-Numpy.ipynb2021-06-15-Manejo-de-datos-con-Pandas.ipynb2022-09-12 Introduccion a la terminal.ipynb2022-09-12 Introduccion a la terminal.txtcommand-line-cheat-sheet.pdfCSS.ipynbDocker.htmlDocker.ipynbExpresiones regulares.htmlExpresiones regulares.ipynbhtml_fileshtml.ipynbintroduccion_pythonmovies.csvmovies.datnotebooks_translatedprueba__pycache__ssh.ipynbtest.htmltest.ipynb
Vemos que se sobreescribe el contenido
Si lo que queremos es que se concatene el contenido, debemos usar >>
!ls > lista.txt
!ls > lista.txt!ls ../ >> lista.txt
!ls > lista.txt!ls ../ >> lista.txtterminal("cat lista.txt")
2021-02-11-Introduccion-a-Python.ipynbAbcdatos1datos123dot2.txtdot.txtfile.txtindex.htmllista.txt2021-02-11-Introduccion-a-Python.ipynb2021-04-23-Calculo-matricial-con-Numpy.ipynb2021-06-15-Manejo-de-datos-con-Pandas.ipynb2022-09-12 Introduccion a la terminal.ipynb2022-09-12 Introduccion a la terminal.txtcommand-line-cheat-sheet.pdfCSS.ipynbDocker.htmlDocker.ipynbExpresiones regulares.htmlExpresiones regulares.ipynbhtml_fileshtml.ipynbintroduccion_pythonmovies.csvmovies.datnotebooks_translatedprueba__pycache__ssh.ipynbtest.htmltest.ipynb
Ahora sí se ha concatenado la información
Esto es muy útil para crear archivos de log
Redirección del standard error
Si realizamos una operación incorrecta obtenemos un error, veamos qué pasa al redireccionar un comando que da un error
!ls fjhdsalkfs > lista.txt
ls: no se puede acceder a 'fjhdsalkfs': No existe el archivo o el directorio
Como vemos, ha dado un error, pero si ahora vemos dentro de lista.txt
terminal("cat lista.txt")
Vemos que el archivo está vacío, eso es porque no hemos redireccionado el standard error
a lista.txt
, sino el standard output
. Como hemos visto en la imagen, hay dos standards de salida en un comando, el primero es el standard output
y el segundo el standard error
, por lo que para redireccionar el standard error hay que indicarlo mediante 2>
. Vamos ahora así
!ls kjhsfskjd 2> lista.txt
!ls kjhsfskjd 2> lista.txtterminal("cat lista.txt")
ls: no se puede acceder a 'kjhsfskjd': No existe el archivo o el directorio
Como vemos ahora sí se ha redireccionado
Redirección del standard output
y del standard error
Si queremos redirigir los dos usamos lo siguiente
!ls kjhsfskjd > lista.txt 2>&1
Veamos dentro de lista.txt
!ls kjhsfskjd > lista.txt 2>&1terminal("cat lista.txt")
ls: no se puede acceder a 'kjhsfskjd': No existe el archivo o el directorio
Si ahora ejecutamos un comando sin errores
!ls . >> lista.txt 2>&1
Veamos dentro de lista.txt
(ojo, ahora hemos concatenado)
!ls . >> lista.txt 2>&1terminal("cat lista.txt")
ls: no se puede acceder a 'kjhsfskjd': No existe el archivo o el directorio2021-02-11-Introduccion-a-Python.ipynbAbcdatos1datos123dot2.txtdot.txtfile.txtindex.htmllista.txt
Como se puede ver, se han redirigido, tanto el standard error
, como el standard output
al mismo archivo
Pipelines
Podemos crear pipelines haciendo que el standard output
de un comando se convierta en el standard input
de otro. Por ejemplo, vamos a hacer que la salida de ls -lha
sea la entrada de grep
, que lo veremos más adelante, pero es un comando para buscar.
!ls -lha | grep -i "txt"
-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
Como podemos ver, lo que hemos hecho ha sido llevar la salida de ls
a grep
con el que hemos buscado algún archivo con txt
en el nombre
Operadores de control - encadenar comandos
Comandos de manera secuencial
Una forma de encadenar comandos de forma secuencial es separarlos mediante ;
. Esto crea diferentes hilos para cada tarea
!ls; echo 'Hola'; cal
2021-02-11-Introduccion-a-Python.ipynb datos123 file.txtAbc dot2.txt index.htmldatos1 dot.txt lista.txtHolaDiciembre 2022do lu ma mi ju vi sá1 2 34 5 6 7 8 9 1011 12 13 14 15 16 1718 19 20 21 22 23 2425 26 27 28 29 30 31
Como podemos ver, primero se ha ejecutado el comando ls
, luego se ha impreso Hola gracias al comando echo "Hola"
y por último se ha impreso un calendario gracias al comando cal
Vamos ahora a hacer otro ejemplo para ver que se ejecutan de manera secuencial.
!echo "Before touch;"; ls -lha; touch secuential.txt; echo "After touch:"; ls -lha
Before touch;total 292Kdrwxrwxr-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.txtAfter touch:total 292Kdrwxrwxr-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
Como se puede ver, en el primer ls
no aparece secuential.txt
, mientras que en el segundo sí. Eso quiere decir que los comandos se han ejecutado en orden, uno detrás de otro
Comandos de manera paralela
Si lo que queremos es que los comandos se ejecuten de manera paralela hay que usar el operador &
, esto hará que se cree un nuevo proceso por cada comando
Veamos el ejemplo de antes
!rm secuential.txt
!rm secuential.txt!echo "Before touch;" & ls -lha & touch secuential.txt & echo "After touch:" & ls -lha
Before touch;After touch:total 292Kdrwxrwxr-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
Ahora se puede ver que no se han ejecutado secuencialmente, ya que primero se han ejecutado los echo
s, que serán los que menos tarden, y después el resto
Comandos de manera condicional
And
Utilizando el operador &&
, un comando se ejecutará cuando el anterior se haya ejecutado satisfactoriamente
!rm secuential.txt
!rm secuential.txt!echo "Before touch;" && ls -lha && touch secuential.txt && echo "After touch:" && ls -lha
Before touch;total 292Kdrwxrwxr-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.txtAfter touch:total 292Kdrwxrwxr-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
Aquí podemos ver cómo se ha ejecutado uno detrás de otro, es decir, un comando no empieza hasta que el anterior acaba
Pero entonces, ¿cuál es la diferencia entre ;
y &&
?
En el primero, el secuencial ;
, primero se ejecuta un comando y luego otro, pero para que se ejecute un comando da igual que el anterior se haya ejecutado satisfactoriamente
!rm prueba ; ls -lha
rm: no se puede borrar 'prueba': No existe el archivo o el directoriototal 292Kdrwxrwxr-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
Como se puede ver primero se ejecuta rm prueba
, da un error y aun así se ejecuta ls -lha prueba
En la manera condicional &&
, si un comando no se ejecuta satisfactoriamente, el siguiente no se ejecuta.
!rm prueba && ls -lha
rm: no se puede borrar 'prueba': No existe el archivo o el directorio
Como se puede ver ls -lha prueba
no se ejecuta ya que rm prueba
ha dado un error
Or
A diferencia del &&
, el 'or' ejecutará todos los procesos sea cual sea su resultado. Se ha de utilizar el operador ||
!rm prueba || ls -lha
rm: no se puede borrar 'prueba': No existe el archivo o el directoriototal 292Kdrwxrwxr-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
La diferencia entre este y ;
es que el ||
(or) no crea un nuevo hilo para cada comando
Cómo se manejan los permisos
Cuando se listan los archivos de un directorio con el flag -l
(long) aparecen unos símbolos al lado de cada archivo.
!mkdir subdirectorio
!mkdir subdirectorio!ls -l
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.txtdrwxrwxr-x 2 wallabot wallabot 4096 dic 6 01:10 subdirectorio
Esto nos da información de cada archivo
Primero veamos qué tipos de archivos hay
- -: Archivo normal
- d: Directorio
- l: Link simbólico
- b: Archivo de bloque especial. Son archivos que manejan la información de los bloques de datos como, por ejemplo, un USB
Después veremos los tipos de modo:
Dueño | Grupo | World | ||||||
---|---|---|---|---|---|---|---|---|
rwx | r-x | r-x | ||||||
1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 1 |
7 | 5 | 5 |
- r: read
- w: write
- x: execute
Modo simbólico:
- u: Solo para el usuario
- g: Sólo para el grupo
- o: Sólo para otros (world)
- a: Para todos
Modificando los permisos en la terminal
Creamos un nuevo archivo
terminal("cd subdirectorio")
terminal("cd subdirectorio")!echo "hola mundo" > mitexto.txt
terminal("cd subdirectorio")!echo "hola mundo" > mitexto.txt!cat mitexto.txt
hola mundo
Vamos a ver los permisos que tiene.
!ls -l
total 4-rw-rw-r-- 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt
Como vemos, tiene permisos de lectura y escritura para mi usuario y el grupo, y solo permisos de lectura para el resto (world)
Cambio de permisos con chmod
(change mode)
Para cambiar los permisos de un archivo usamos el comando chmod
(change mode), donde tenemos que poner en octal los permisos del usuario, luego los del grupo y por último los del resto.
!chmod 755 mitexto.txt
!chmod 755 mitexto.txt!ls -l
total 4-rwxr-xr-x 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt
Vemos que ahora mi usuario tiene permisos de lectura, escritura y ejecución, mientras que el grupo y el resto del mundo tiene permisos de lectura y ejecución
Vamos a quitar los permisos de lectura solo a mi usuario. Para cambiar solo los permisos de un usuario usamos el identificador simbólico, un +
si queremos agregar permisos o un -
si queremos quitarlos o un =
si queremos restablecerlos y seguido del tipo de permiso
!chmod u-r mitexto.txt
!chmod u-r mitexto.txt!ls -l
total 4--wxr-xr-x 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt
!cat mitexto.txt
cat: mitexto.txt: Permiso denegado
Como vemos, al quitar permisos de lectura para mi usuario, no podemos leer el archivo.
Le volvemos a poner el permiso de lectura
!chmod u+r mitexto.txt
!chmod u+r mitexto.txt!ls -l
total 4-rwxr-xr-x 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt
!cat mitexto.txt
hola mundo
Si queremos agregar o quitar permisos a más de un usuario, lo hacemos separando cada permiso por una ,
!chmod u-x,go=w mitexto.txt
!chmod u-x,go=w mitexto.txt!ls -l
total 4-rw--w--w- 1 wallabot wallabot 11 dic 6 01:10 mitexto.txt
Como se puede ver, se le ha quitado el permiso de ejecución al usuario y se ha establecido el permiso de solo escritura para el grupo y el resto del mundo.
Identificación de usuario con whoami
Para saber quiénes somos podemos usar el comando whoami
(who am I)
!whoami
wallabot
Información de usuario con id
Otra manera, que además da más información, es el comando id
!id
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)
Este comando nos dice que nuestro ID de usuario es el 1000, el ID de grupo es el 1000 y que pertenecemos a los grupos wallabot, adm, cdrom, sudo, dip, plugdev, lpadmin, lxd, sambashare y docker
Cambio de usuario con el comando su
(switch user)
Si queremos cambiar de usuario usamos el comando su
(switch user). Para según qué usuario hay que usar sudo
(superuser do)
!sudo su root
root@wallabot:/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio#
Como vemos cambia el prompt
y ahora indica que somos el usuario root
Vamos a la carpeta home
!cd
root@wallabot:~#
Pero en Linux hay una carpeta home por cada usuario, esto lo podemos ver si ejecutamos el comando pwd
!pwd
/root
Voy a crear un archivo en la carpeta donde antes he creado el archivo mitexto.txt
!touch /home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio/rootfile.txt
Vuelvo a cambiarme a mi usuario
!su wallabot
wallabot@wallabot:
Y me voy al directorio donde están los archivos que he creado.
!cd /home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio
Vemos los archivos que hay y sus permisos
!cd /home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio!ls -l
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
Como vemos, el usuario y el grupo del archivo rootfile.txt es el usuario root
Si yo, ahora que soy el usuario wallabot, intento borrar el archivo rootfile.txt
!rm rootfile.txt
rm: ¿borrar el fichero regular vacío 'rootfile.txt' protegido contra escritura? (s/n)
Como vemos, nos pregunta si lo queremos borrar, ya que pertenece a otro usuario.
Modificar la contraseña de un usuario
Si quiero modificar la contraseña del usuario que tengo actualmente activo, uso el comando passwd
(password)
Primero compruebo qué usuario soy
!whoami
wallabot
Y ahora probamos a cambiar la contraseña
!passwd
$ passwdCambiando la contraseña de wallabot.Contraseña actual de :Nueva contraseña:Vuelva a escribir la nueva contraseña
Como vemos, pide la actual contraseña para poder cambiarla
Links simbólicos
Podemos crear links simbólicos a una ruta determinada mediante el comando ln
(link) seguido del flag -s
(symbolic), el directorio y el nombre del link
!ln -s /home/wallabot/Documentos/web web
Si ahora listamos los archivos
!ln -s /home/wallabot/Documentos/web web!ls -l
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.txtlrwxrwxrwx 1 wallabot wallabot 29 dic 6 01:28 web -> /home/wallabot/Documentos/web
Vemos el link simbólico web
que apunta a /home/wallabot/Documentos/web:
Yo ahora me puedo ir a web
terminal("cd web")
terminal("cd web")!pwd
/home/wallabot/Documentos/web
Configurar las variables de entorno
Ver las variables de entorno con printenv
Con el comando printenv
podemos ver todas las variables de entorno
!printenv
GJS_DEBUG_TOPICS=JS ERROR;JS LOGVSCODE_CWD=/home/wallabotLESSOPEN=| /usr/bin/lesspipe %sCONDA_PROMPT_MODIFIER=(base)PYTHONIOENCODING=utf-8USER=wallabotVSCODE_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=trueMPLBACKEND=module://ipykernel.pylab.backend_inlineSSH_AGENT_PID=1373XDG_SESSION_TYPE=x11SHLVL=0HOME=/home/wallabotCHROME_DESKTOP=code-url-handler.desktopCONDA_SHLVL=1DESKTOP_SESSION=ubuntuGIO_LAUNCHED_DESKTOP_FILE=/usr/share/applications/code.desktopVSCODE_IPC_HOOK=/run/user/1000/vscode-26527400-1.73.1-main.sockPYTHONUNBUFFERED=1GTK_MODULES=gail:atk-bridgeGNOME_SHELL_SESSION_MODE=ubuntuAPPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL=truePAGER=catMANAGERPID=1153DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/busGIO_LAUNCHED_DESKTOP_FILE_PID=3897_CE_M=IM_CONFIG_PHASE=1LOGNAME=wallabot_=/home/wallabot/anaconda3/bin/pythonJOURNAL_STREAM=8:52662XDG_SESSION_CLASS=userUSERNAME=wallabotTERM=xterm-colorGNOME_DESKTOP_SESSION_ID=this-is-deprecated_CE_CONDA=WINDOWPATH=2PATH=/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/binSESSION_MANAGER=local/wallabot:@/tmp/.ICE-unix/1410,unix/wallabot:/tmp/.ICE-unix/1410INVOCATION_ID=73bba2d15f2e492fa6c16538996a2556VSCODE_AMD_ENTRYPOINT=vs/workbench/api/node/extensionHostProcessXDG_RUNTIME_DIR=/run/user/1000XDG_MENU_PREFIX=gnome-GDK_BACKEND=x11DISPLAY=:0LANG=es_ES.UTF-8XDG_CURRENT_DESKTOP=UnityXAUTHORITY=/run/user/1000/gdm/XauthorityXDG_SESSION_DESKTOP=ubuntuXMODIFIERS=@im=ibusLS_COLORS=SSH_AUTH_SOCK=/run/user/1000/keyring/sshORIGINAL_XDG_CURRENT_DESKTOP=ubuntu:GNOMECONDA_PYTHON_EXE=/home/wallabot/anaconda3/bin/pythonSHELL=/bin/bashELECTRON_RUN_AS_NODE=1QT_ACCESSIBILITY=1GDMSESSION=ubuntuLESSCLOSE=/usr/bin/lesspipe %s %sCONDA_DEFAULT_ENV=basePYDEVD_IPYTHON_COMPATIBLE_DEBUGGING=1GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1GJS_DEBUG_OUTPUT=stderrQT_IM_MODULE=ibusGIT_PAGER=catPWD=/home/wallabot/Documentos/webCLICOLOR=1XDG_DATA_DIRS=/usr/share/ubuntu:/usr/local/share/:/usr/share/:/var/lib/snapd/desktopXDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdgVSCODE_CODE_CACHE_PATH=/home/wallabot/.config/Code/CachedData/6261075646f055b99068d3688932416f2346dd3bCONDA_EXE=/home/wallabot/anaconda3/bin/condaCONDA_PREFIX=/home/wallabot/anaconda3VSCODE_PID=3897
Ver una variable de entorno con el comando echo
Para ver una variable de entorno en concreto podemos hacerlo mediante el comando echo
seguido del símbolo $
y el nombre de la variable
!echo $HOME
/home/wallabot
Modificar una variable de entorno para una sesión de terminal
Podemos modificar una variable de entorno para la sesión activa de terminal, por ejemplo, vamos a agregar una nueva ruta a la variable PATH
. Primero vemos qué hay en ella
!echo $PATH
/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
Ahora añadimos un nuevo directorio
!PATH=$PATH:"subdirectorio
Volvemos a ver qué hay dentro de PATH
!echo $PATH
/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
Vemos que se ha añadido el directorio subdirectorio
.
El problema de este método es que cuando abramos una nueva terminal no se mantendrá este cambio en PATH
Modificar una variable de entorno para todas las sesiones de terminal
Nos vamos a la carpeta home
terminal("cd /home/wallabot")
Aquí en el home listamos todos los archivos con el flag -a
(all)
terminal("cd /home/wallabot")!ls -a
. .eclipse .pki.. Escritorio Plantillas.afirma .gitconfig .platformioanaconda3 .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 .vscodeDescargas .mozilla .wget-hsts.docker MúsicaDocumentos .nv
Vemos que hay un archivo que se llama .bashrc
, este archivo es el archivo que tiene la configuración de nuestro bash
terminal("cat .bashrc", max_lines_output=3)
# ~/.bashrc: executed by bash(1) for non-login shells.# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)# for examples...fiunset __conda_setup# <<< conda initialize <<<
Este archivo es el que configura la terminal cada vez que se abre una nueva, por lo que si en él editamos la variable PATH
, este cambio se mantendrá para todas las ventanas nuevas de terminal que abramos
Para modificar la variable PATH
dentro del archivo de configuración tenemos que agregar la siguiente línea al archivo
PATH=$PATH:"subdirectorio"
Crear alias para todas las sesiones
Ya vimos cómo crear alias de comandos, pero también pasaba que se perdían cada vez que cerrábamos una sesión de terminal, para que esto no pase, los añadimos también al archivo de configuración .bashrc
. Por ejemplo, en mi caso he añadido las siguientes líneas
alias ll='ls -l'
alias la='ls -a'
alias lh='ls -h'
alias lha='ls -lha'
Comandos de búsqueda
Búsqueda de binarios con which
El primer comando de búsqueda que vamos a ver es which
que nos permite encontrar la ruta de los binarios
!which python
/home/wallabot/anaconda3/bin/python
Sin embargo, si buscamos algo que no esté en alguna de las rutas del PATH, which
no será capaz de decirnos la ruta
!which cd
Búsqueda de archivos con find
Para buscar un archivo con find tenemos que indicarle desde qué ruta queremos buscar el archivo, seguido del flag -name
y el nombre del archivo que queremos buscar.
!which cd!find ~ -name "2021-02-11-Introduccion-a-Python.ipynb"
/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
Como vemos, está en su directorio más la copia que he creado en este notebook y la he guardado en la carpeta prueba
Una cosa muy poderosa de find
es que podemos usar wildcards
, por ejemplo si quiero buscar todos los archivos de texto de mi carpeta web
.
!find ~/Documentos/web/ -name *.txt
/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
Si no queremos que distinga entre mayúsculas y minúsculas debemos usar el flag -iname
, por ejemplo si buscamos todos los archivos que contengan el texto FILE
, pero usando el flag -iname
!find ~/Documentos/web/ -iname *FILE*
/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
Vemos que todos los resultados contienen file
y no FILE
, es decir, no ha hecho distinción entre mayúsculas y minúsculas
Podemos especificar el tipo de archivo con el flag -type
. Solo admite dos tipos f
para archivos y d
para directorios
!find ~/Documentos/nerf -name image*
/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
!find ~/Documentos/nerf -name image* -type d
/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
!find ~/Documentos/nerf -name image* -type f
/home/wallabot/Documentos/nerf/instant-ngp/dependencies/tiny-cuda-nn/dependencies/fmt/doc/bootstrap/mixins/image.less
Si queremos filtrar por el tamaño del archivo podemos usar el flag -size
, por ejemplo, si queremos buscar todos los archivos de más de 200 MB
!find ~/Documentos/ -type f -size +200M
/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
Si queremos realizar operaciones tras la búsqueda, usamos el flag -exec
Por ejemplo, voy a buscar todas las carpetas con el nombre subdirectorio
!find ~/ -name subdirectorio -type d
/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio
Puedo hacer que se borren con el flag -exec
!find ~/ -name subdirectorio -type d -exec rm -r {} ;
rm: ¿borrar el fichero regular vacío '/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio/rootfile.txt' protegido contra escritura? (s/n) sfind: ‘/home/wallabot/Documentos/web/portafolio/posts/prueba/subdirectorio’: No existe el archivo o el directorio
!find ~/ -name subdirectorio -type d
Por último, si usamos el carácter !
estaremos indicando que encuentre todo lo que no coincide con lo que hemos especificado
!find ~/ -name subdirectorio -type d!find ~/Documentos/web/portafolio/posts/prueba ! -name *.txt
/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
Como vemos, ha encontrado todo lo que no es un .txt
Comando de búsqueda grep
grep
es un comando de búsqueda muy potente, por eso le dedicamos un apartado a él solo. El comando grep
utiliza las expresiones regulares, por lo que si quieres aprender de ellas te dejo un enlace a un post donde las explico
Vamos a empezar a ver la potencia de este comando, vamos a buscar todas las veces que aparece el texto MaximoFN
dentro del archivo 2021-02-11-Introduccion-a-Python.ipynb
terminal("cd /home/wallabot/Documentos/web/portafolio/posts/prueba")
terminal("cd /home/wallabot/Documentos/web/portafolio/posts/prueba")terminal("grep MaximoFN 2021-02-11-Introduccion-a-Python.ipynb", max_lines_output=20)
"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\\n""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' ",
Sin embargo, si hacemos la misma búsqueda para el texto maximofn
!grep maximofn 2021-02-11-Introduccion-a-Python.ipynb
No aparece ningún resultado, esto es porque grep
es case sensitive
, es decir, busca el texto tal cual se lo has introducido, diferenciando mayúsculas y minúsculas. Si no queremos esto, tenemos que introducir el flag -i
!grep maximofn 2021-02-11-Introduccion-a-Python.ipynbterminal("grep -i MaximoFN 2021-02-11-Introduccion-a-Python.ipynb", max_lines_output=20)
"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\\n""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' ",
Si lo que queremos es que nos devuelva el número de veces que aparece, introducimos el flag -c
!grep -c MaximoFN 2021-02-11-Introduccion-a-Python.ipynb
105
Si nos da igual si aparece con mayúscula o minúscula, podemos volver a agregar el flag -i
, pero no hace falta meterlo separado del flag -c
, se pueden introducir juntos
!grep -ci MaximoFN 2021-02-11-Introduccion-a-Python.ipynb
105
Si ahora queremos todas las veces en las que no aparece la palabra MáximoFN
introducimos el flag -v
!grep -cv MaximoFN 2021-02-11-Introduccion-a-Python.ipynb
11573
Utilidades de red
Información de las interfaces de red con ifconfig
El primer comando va a ser ifconfig
que nos muestra información de nuestras interfaces de red.
!ifconfig
br-470e52ae2708: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255ether 02:42:ac:d0:b9:eb txqueuelen 0 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255ether 02:42:5d:15:1c:e9 txqueuelen 0 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0enp6s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.1.144 netmask 255.255.255.0 broadcast 192.168.1.255inet6 fe80::7dc2:6944:3fbe:c18e prefixlen 64 scopeid 0x20<link>ether 24:4b:fe:5c:f6:59 txqueuelen 1000 (Ethernet)RX packets 144369 bytes 123807349 (123.8 MB)RX errors 0 dropped 2056 overruns 0 frame 0TX packets 100672 bytes 55678042 (55.6 MB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 1000 (Bucle local)RX packets 10748 bytes 1832545 (1.8 MB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 10748 bytes 1832545 (1.8 MB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0wlp5s0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500ether 4c:77:cb:1d:66:cc txqueuelen 1000 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Como vemos tenemos la información de todas las interfaces de red de mi ordenador, pero si quiero saber solo la de una, se especifica añadiendo su nombre
!ifconfig enp6s0
enp6s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.1.144 netmask 255.255.255.0 broadcast 192.168.1.255inet6 fe80::7dc2:6944:3fbe:c18e prefixlen 64 scopeid 0x20<link>ether 24:4b:fe:5c:f6:59 txqueuelen 1000 (Ethernet)RX packets 144467 bytes 123842258 (123.8 MB)RX errors 0 dropped 2060 overruns 0 frame 0TX packets 100786 bytes 55749109 (55.7 MB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Información de las interfaces de red con ip
Otra manera de obtener la información de nuestras interfaces de red es mediante el comando ip
, añadiendo a
nos da la información de todas las interfaces
!ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever2: enp6s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 24:4b:fe:5c:f6:59 brd ff:ff:ff:ff:ff:ffinet 192.168.1.144/24 brd 192.168.1.255 scope global dynamic noprefixroute enp6s0valid_lft 80218sec preferred_lft 80218secinet6 fe80::7dc2:6944:3fbe:c18e/64 scope link noprefixroutevalid_lft forever preferred_lft forever3: wlp5s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000link/ether 4c:77:cb:1d:66:cc brd ff:ff:ff:ff:ff:ff4: br-470e52ae2708: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group defaultlink/ether 02:42:ac:d0:b9:eb brd ff:ff:ff:ff:ff:ffinet 172.18.0.1/16 brd 172.18.255.255 scope global br-470e52ae2708valid_lft forever preferred_lft forever5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group defaultlink/ether 02:42:5d:15:1c:e9 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft forever
Test de comunicaciones con ping
Otro comando útil es ping
, que nos puede servir para ver si tenemos conexión con una determinada IP
. Por ejemplo, la IP
de Google es 142.250.200.78
, por lo que le hacemos ping
a ver si nos contesta. El comando ping
en Linux hace ping
s sin parar, por lo que nunca termina hasta que no lo paramos, para que no pase eso añadimos el flag -c
y el número de intentos
!ping 142.250.200.132 -c 4
PING 142.250.200.132 (142.250.200.132) 56(84) bytes of data.64 bytes from 142.250.200.132: icmp_seq=1 ttl=117 time=3.46 ms64 bytes from 142.250.200.132: icmp_seq=2 ttl=117 time=3.77 ms64 bytes from 142.250.200.132: icmp_seq=3 ttl=117 time=2.81 ms64 bytes from 142.250.200.132: icmp_seq=4 ttl=117 time=2.86 ms--- 142.250.200.132 ping statistics ---4 packets transmitted, 4 received, 0% packet loss, time 3004msrtt min/avg/max/mdev = 2.812/3.227/3.773/0.405 ms
Lo mismo hubiera pasado si lo hubiéramos hecho directamente sobre google.com
!ping www.google.com -c 4
PING www.google.com (142.250.200.132) 56(84) bytes of data.64 bytes from mad41s14-in-f4.1e100.net (142.250.200.132): icmp_seq=1 ttl=117 time=2.74 ms64 bytes from mad41s14-in-f4.1e100.net (142.250.200.132): icmp_seq=2 ttl=117 time=3.96 ms64 bytes from mad41s14-in-f4.1e100.net (142.250.200.132): icmp_seq=3 ttl=117 time=3.56 ms64 bytes from mad41s14-in-f4.1e100.net (142.250.200.132): icmp_seq=4 ttl=117 time=2.87 ms--- www.google.com ping statistics ---4 packets transmitted, 4 received, 0% packet loss, time 3003msrtt min/avg/max/mdev = 2.741/3.283/3.962/0.499 ms
Descargar archivos fuente con curl
Podemos obtener un archivo de texto de una dirección dada mediante el comando curl
, por ejemplo, nos podemos descargar el html de Google
!curl https://www.google.com
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="es"><head><meta content="Google.es permite acceder a la informaci�n mundial en castellano, catal�n, gallego, euskara e ingl�s." name="description"><meta content="noodp" name="robots"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>Google</title><script nonce="zXcc4tMJWBRoE7q_o_Z2fQ">(function(){window.google={kEI:'M5GOY6PeLr-jkdUP1pir0AE',kEXPI:'0,1359409,6059,206,4804,2316,383,246,5,5367,1123753,1197713,688,380089,16115,28684,22430,1362,12312,17587,4998,13228,3847,10622,22741,5081,1593,1279,2742,149,1103,840,1983,214,4100,3514,606,2023,2297,14670,3227,2845,7,4773,28997,1850,15757,3,346,230,6459,149,13975,4,1528,2304,7039,27731,7357,13658,4437,16786,5815,2542,4094,4052,3,3541,1,14262,27892,2,14022,6248,19490,5680,1021,2380,28741,4569,6255,23421,1252,5835,14967,4333,7484,11406,15676,8155,7381,15970,873,14804,1,4828,7,1922,5784,12208,10330,587,12192,4832,26504,5796,3,14433,3890,751,13384,1499,3,679,1622,1779,1886,338,1627,1119,6,8909,80,243,458,3438,1763,722,1020,813,91,1133,10,280,2306,44,77,1420,3,562,402,314,275,2095,440,399,138,384,1033,334,2667,2,723,444,79,403,501,929,3,785,2,240,78,2022,284,196,732,175,342,244,617,335,1,841,1275,14,979,57,857,446,2,1900,838,251,227,50,21,8,3,442,57,40,936,697,773,95,121,643,1502,163,355,702,195,1,452,50,334,687,109,1,19,109,134,546,80,5,36,124,68,135,131,415,47,27,266,563,48,231,742,15,527,2,6,495,1,495,5,62,1627,441,262,5,3,648,3,6,4,13,39,538,792,337,9,115,98,180,148,308,401,1240,2,726,243,2044,5286450,84,19,32,115,11,70,5995534,2803414,3311,141,795,19735,1,1,346,1755,1004,41,342,1,189,14,1,10,8,1,5,4,2,1,3,2,2,1,3,1,3,1,4,3,1,3,2,2,23947076,511,21,11,4041599,1964,1007,2087,13579,3102,303,5595,11,3835,3637,2623,9,136,1524825',kBL:'p9Xv'};google.sn='webhp';google.kHL='es';})();(function(){var f=this||self;var h,k=[];function l(a){for(var b;a&&(!a.getAttribute||!(b=a.getAttribute("eid")));)a=a.parentNode;return b||h}function m(a){for(var b=null;a&&(!a.getAttribute||!(b=a.getAttribute("leid")));)a=a.parentNode;return b}function n(a,b,c,d,g){var e="";c||-1!==b.search("&ei=")||(e="&ei="+l(d),-1===b.search("&lei=")&&(d=m(d))&&(e+="&lei="+d));d="";!c&&f._cshid&&-1===b.search("&cshid=")&&"slh"!==a&&(d="&cshid="+f._cshid);c=c||"/"+(g||"gen_204")+"?atyp=i&ct="+a+"&cad="+b+e+"&zx="+Date.now()+d;/^http:/i.test(c)&&"https:"===window.location.protocol&&(google.ml&&google.ml(Error("a"),!1,{src:c,glmm:1}),c="");return c};h=google.kEI;google.getEI=l;google.getLEI=m;google.ml=function(){return null};google.log=function(a,b,c,d,g){if(c=n(a,b,c,d,g)){a=new Image;var e=k.length;k[e]=a;a.onerror=a.onload=a.onabort=function(){delete k[e]};a.src=c}};google.logUrl=n;}).call(this);(function(){google.y={};google.sy=[];google.x=function(a,b){if(a)var c=a.id;else{do c=Math.random();while(google.y[c])}google.y[c]=[a,b];return!1};google.sx=function(a){google.sy.push(a)};google.lm=[];google.plm=function(a){google.lm.push.apply(google.lm,a)};google.lq=[];google.load=function(a,b,c){google.lq.push([[a],b,c])};google.loadAll=function(a,b){google.lq.push([a,b])};google.bx=!1;google.lx=function(){};}).call(this);google.f={};(function(){document.documentElement.addEventListener("submit",function(b){var a;if(a=b.target){var c=a.getAttribute("data-submitfalse");a="1"===c||"q"===c&&!a.elements.q.value?!0:!1}else a=!1;a&&(b.preventDefault(),b.stopPropagation())},!0);document.documentElement.addEventListener("click",function(b){var a;a:{for(a=b.target;a&&a!==document.documentElement;a=a.parentElement)if("A"===a.tagName){a="1"===a.getAttribute("data-nohref");break a}a=!1}a&&b.preventDefault()},!0);}).call(this);</script><style>#gbar,#guser{font-size:13px;padding-top:1px !important;}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb4{color:#00c !important}.gbi .gb4{color:#dd8e27 !important}.gbf .gb4{color:#900 !important}</style><style>body,td,a,p,.h{font-family:arial,sans-serif}body{margin:0;overflow-y:scroll}#gog{padding:3px 8px 0}td{line-height:.8em}.gac_m td{line-height:17px}form{margin-bottom:20px}.h{color:#1558d6}em{font-weight:bold;font-style:normal}.lst{height:25px;width:496px}.gsfi,.lst{font:18px arial,sans-serif}.gsfs{font:17px arial,sans-serif}.ds{display:inline-box;display:inline-block;margin:3px 0 4px;margin-left:4px}input{font-family:inherit}body{background:#fff;color:#000}a{color:#4b11a8;text-decoration:none}a:hover,a:active{text-decoration:underline}.fl a{color:#1558d6}a:visited{color:#4b11a8}.sblc{padding-top:5px}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px}.lsbb{background:#f8f9fa;border:solid 1px;border-color:#dadce0 #70757a #70757a #dadce0;height:30px}.lsbb{display:block}#WqQANb a{display:inline-block;margin:0 12px}.lsb{background:url(/images/nav_logo229.png) 0 -261px repeat-x;border:none;color:#000;cursor:pointer;height:30px;margin:0;outline:0;font:15px arial,sans-serif;vertical-align:top}.lsb:active{background:#dadce0}.lst:focus{outline:none}</style><script nonce="zXcc4tMJWBRoE7q_o_Z2fQ">(function(){window.google.erd={jsr:1,bv:1698,de:true};var h=this||self;var k,l=null!=(k=h.mei)?k:1,n,p=null!=(n=h.sdo)?n:!0,q=0,r,t=google.erd,v=t.jsr;google.ml=function(a,b,d,m,e){e=void 0===e?2:e;b&&(r=a&&a.message);if(google.dl)return google.dl(a,e,d),null;if(0>v){window.console&&console.error(a,d);if(-2===v)throw a;b=!1}else b=!a||!a.message||"Error loading script"===a.message||q>=l&&!m?!1:!0;if(!b)return null;q++;d=d||{};b=encodeURIComponent;var c="/gen_204?atyp=i&ei="+b(google.kEI);google.kEXPI&&(c+="&jexpid="+b(google.kEXPI));c+="&srcpg="+b(google.sn)+"&jsr="+b(t.jsr)+"&bver="+b(t.bv);var f=a.lineNumber;void 0!==f&&(c+="&line="+f);var g=a.fileName;g&&(0<g.indexOf("-extension:/")&&(e=3),c+="&script="+b(g),f&&g===window.location.href&&(f=document.documentElement.outerHTML.split(" ")[f],c+="&cad="+b(f?f.substring(0,300):"No script found.")));c+="&jsel="+e;for(var u in d)c+="&",c+=b(u),c+="=",c+=b(d[u]);c=c+"&emsg="+b(a.name+": "+a.message);c=c+"&jsst="+b(a.stack||"N/A");12288<=c.length&&(c=c.substr(0,12288));a=c;m||google.log(0,"",a);return a};window.onerror=function(a,b,d,m,e){r!==a&&(a=e instanceof Error?e:Error(a),void 0===d||"lineNumber"in a||(a.lineNumber=d),void 0===b||"fileName"in a||(a.fileName=b),google.ml(a,!1,void 0,!1,"SyntaxError"===a.name||"SyntaxError"===a.message.substring(0,11)||-1!==a.message.indexOf("Script error")?3:0));r=null;p&&q>=l&&(window.onerror=null)};})();</script></head><body bgcolor="#fff"><script nonce="zXcc4tMJWBRoE7q_o_Z2fQ">(function(){var src='/images/nav_logo229.png';var iesg=false;document.body.onload = function(){window.n && window.n();if (document.images){new Image().src=src;}if (!iesg){document.f&&document.f.q.focus();document.gbqf&&document.gbqf.q.focus();}}})();</script><div id="mngb"><div id=gbar><nobr><b class=gb1>B�squeda</b> <a class=gb1 href="https://www.google.es/imghp?hl=es&tab=wi">Im�genes</a> <a class=gb1 href="https://maps.google.es/maps?hl=es&tab=wl">Maps</a> <a class=gb1 href="https://play.google.com/?hl=es&tab=w8">Play</a> <a class=gb1 href="https://www.youtube.com/?tab=w1">YouTube</a> <a class=gb1 href="https://news.google.com/?tab=wn">Noticias</a> <a class=gb1 href="https://mail.google.com/mail/?tab=wm">Gmail</a> <a class=gb1 href="https://drive.google.com/?tab=wo">Drive</a> <a class=gb1 style="text-decoration:none" href="https://www.google.es/intl/es/about/products?tab=wh"><u>M�s</u> »</a></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe></span><a href="http://www.google.es/history/optout?hl=es" class=gb4>Historial web</a> | <a href="/preferences?hl=es" class=gb4>Ajustes</a> | <a target=_top id=gb_70 href="https://accounts.google.com/ServiceLogin?hl=es&passive=true&continue=https://www.google.com/&ec=GAZAAQ" class=gb4>Iniciar sesi�n</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div></div><center><br clear="all" id="lgpd"><div id="lga"><img alt="Google" height="92" src="/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png" style="padding:28px 0 14px" width="272" id="hplogo"><br><br></div><form action="/search" name="f"><table cellpadding="0" cellspacing="0"><tr valign="top"><td width="25%"> </td><td align="center" nowrap=""><input name="ie" value="ISO-8859-1" type="hidden"><input value="es" name="hl" type="hidden"><input name="source" type="hidden" value="hp"><input name="biw" type="hidden"><input name="bih" type="hidden"><div class="ds" style="height:32px;margin:4px 0"><input class="lst" style="margin:0;padding:5px 8px 0 6px;vertical-align:top;color:#000" autocomplete="off" value="" title="Buscar con Google" maxlength="2048" name="q" size="57"></div><br style="line-height:0"><span class="ds"><span class="lsbb"><input class="lsb" value="Buscar con Google" name="btnG" type="submit"></span></span><span class="ds"><span class="lsbb"><input class="lsb" id="tsuid_1" value="Voy a tener suerte" name="btnI" type="submit"><script nonce="zXcc4tMJWBRoE7q_o_Z2fQ">(function(){var id='tsuid_1';document.getElementById(id).onclick = function(){if (this.form.q.value){this.checked = 1;if (this.form.iflsig)this.form.iflsig.disabled = false;}else top.location='/doodles/';};})();</script><input value="AJiK0e8AAAAAY46fQwdyVrbrgW6gkEtVkGfp2nyO0ZXL" name="iflsig" type="hidden"></span></span></td><td class="fl sblc" align="left" nowrap="" width="25%"><a href="/advanced_search?hl=es&authuser=0">B�squeda avanzada</a></td></tr></table><input id="gbv" name="gbv" type="hidden" value="1"><script nonce="zXcc4tMJWBRoE7q_o_Z2fQ">(function(){var a,b="1";if(document&&document.getElementById)if("undefined"!=typeof XMLHttpRequest)b="2";else if("undefined"!=typeof ActiveXObject){var c,d,e=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];for(c=0;d=e[c++];)try{new ActiveXObject(d),b="2"}catch(h){}}a=b;if("2"==a&&-1==location.search.indexOf("&gbv=2")){var f=google.gbvu,g=document.getElementById("gbv");g&&(g.value=a);f&&window.setTimeout(function(){location.href=f},0)};}).call(this);</script></form><div id="gac_scont"></div><div style="font-size:83%;min-height:3.5em"><br><div id="gws-output-pages-elements-homepage_additional_languages__als"><style>#gws-output-pages-elements-homepage_additional_languages__als{font-size:small;margin-bottom:24px}#SIvCob{color:#3c4043;display:inline-block;line-height:28px;}#SIvCob a{padding:0 3px;}.H6sW5{display:inline-block;margin:0 2px;white-space:nowrap}.z4hgWe{display:inline-block;margin:0 2px}</style><div id="SIvCob">Ofrecido por Google en: <a href="https://www.google.com/setprefs?sig=0_vwUKUD2Xhro4NnrueK1hCfItt30%3D&hl=ca&source=homepage&sa=X&ved=0ahUKEwjjw_C44uP7AhW_UaQEHVbMChoQ2ZgBCAU">catal�</a> <a href="https://www.google.com/setprefs?sig=0_vwUKUD2Xhro4NnrueK1hCfItt30%3D&hl=gl&source=homepage&sa=X&ved=0ahUKEwjjw_C44uP7AhW_UaQEHVbMChoQ2ZgBCAY">galego</a> <a href="https://www.google.com/setprefs?sig=0_vwUKUD2Xhro4NnrueK1hCfItt30%3D&hl=eu&source=homepage&sa=X&ved=0ahUKEwjjw_C44uP7AhW_UaQEHVbMChoQ2ZgBCAc">euskara</a> </div></div></div><span id="footer"><div style="font-size:10pt"><div style="margin:19px auto;text-align:center" id="WqQANb"><a href="http://www.google.es/intl/es/services/">Soluciones Empresariales</a><a href="/intl/es/about.html">Todo acerca de Google</a><a href="https://www.google.com/setprefdomain?prefdom=ES&prev=https://www.google.es/&sig=K_a2UXepORMQOw5-SHU8h4noB_VWk%3D">Google.es</a></div></div><p style="font-size:8pt;color:#70757a">© 2022 - <a href="/intl/es/policies/privacy/">Privacidad</a> - <a href="/intl/es/policies/terms/">T�rminos</a></p></span></center><script nonce="zXcc4tMJWBRoE7q_o_Z2fQ">(function(){window.google.cdo={height:757,width:1440};(function(){var a=window.innerWidth,b=window.innerHeight;if(!a||!b){var c=window.document,d="CSS1Compat"==c.compatMode?c.documentElement:c.body;a=d.clientWidth;b=d.clientHeight}a&&b&&(a!=google.cdo.width||b!=google.cdo.height)&&google.log("","","/client_204?&atyp=i&biw="+a+"&bih="+b+"&ei="+google.kEI);}).call(this);})();</script> <script nonce="zXcc4tMJWBRoE7q_o_Z2fQ">(function(){google.xjs={ck:'xjs.hp.oxai9SxkIQY.L.X.O',cs:'ACT90oEGh-_ImDfBjn6aD_ABGaOlD2MqVw',excm:[]};})();</script> <script nonce="zXcc4tMJWBRoE7q_o_Z2fQ">(function(){var u='/xjs/_/js/k=xjs.hp.en.9b-uVUIpJU8.O/am=AADoBABQAGAB/d=1/ed=1/rs=ACT90oG-6KYVksw4jxVvNcwan406xE6qVw/m=sb_he,d';var amd=0;var d=this||self,e=function(a){return a};var g;var l=function(a,b){this.g=b===h?a:""};l.prototype.toString=function(){return this.g+""};var h={};function m(){var a=u;google.lx=function(){p(a);google.lx=function(){}};google.bx||google.lx()}function p(a){google.timers&&google.timers.load&&google.tick&&google.tick("load","xjsls");var b=document;var c="SCRIPT";"application/xhtml+xml"===b.contentType&&(c=c.toLowerCase());c=b.createElement(c);if(void 0===g){b=null;var k=d.trustedTypes;if(k&&k.createPolicy){try{b=k.createPolicy("goog#html",{createHTML:e,createScript:e,createScriptURL:e})}catch(q){d.console&&d.console.error(q.message)}g=b}else g=b}a=(b=g)?b.createScriptURL(a):a;a=new l(a,h);c.src=a instanceof l&&a.constructor===l?a.g:"type_error:TrustedResourceUrl";var f,n;(f=(a=null==(n=(f=(c.ownerDocument&&c.ownerDocument.defaultView||window).document).querySelector)?void 0:n.call(f,"script[nonce]"))?a.nonce||a.getAttribute("nonce")||"":"")&&c.setAttribute("nonce",f);document.body.appendChild(c);google.psa=!0};google.xjsu=u;setTimeout(function(){0<amd?google.caft(function(){return m()},amd):m()},0);})();function _DumpException(e){throw e;}function _F_installCss(c){}(function(){google.jl={blt:'none',chnk:0,dw:false,dwu:true,emtn:0,end:0,ico:false,ikb:0,ine:false,injs:'none',injt:0,injth:0,injv2:false,lls:'default',pdt:0,rep:0,snet:true,strt:0,ubm:false,uwp:true};})();(function(){var pmc='{"d":{},"sb_he":{"agen":true,"cgen":true,"client":"heirloom-hp","dh":true,"ds":"","fl":true,"host":"google.com","jsonp":true,"lm":true,"msgs":{"cibl":"Borrar b�squeda","dym":"Quiz�s quisiste decir:","lcky":"Voy a tener suerte","lml":"M�s informaci�n","psrc":"Esta b�squeda se ha eliminado de tu \u003Ca href=\"/history\"\u003Ehistorial web\u003C/a\u003E.","psrl":"Eliminar","sbit":"Buscar por imagen","srch":"Buscar con Google"},"ovr":{},"pq":"","rfs":[],"sbas":"0 3px 8px 0 rgba(0,0,0,0.2),0 0 0 1px rgba(0,0,0,0.08)","stok":"gh8wSanWNWQy8f-PH0wGTjDkvYQ"}}';google.pmc=JSON.parse(pmc);})();</script> </body></html>
También podemos hacer un pipeline para guardarlo en un archivo
!curl https://www.google.com > google.html
% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed100 15168 0 15168 0 0 135k 0 --:--:-- --:--:-- --:--:-- 137k
Ahora podemos ver si se ha guardado bien
!cat google.html
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="es"><head><meta content="Google.es permite acceder a la informaci�n mundial en castellano, catal�n, gallego, euskara e ingl�s." name="description"><meta content="noodp" name="robots"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>Google</title><script nonce="Jo7WFU6XWWwu6NrdwaRyIw">(function(){window.google={kEI:'R5GOY-LZHLegkdUP_IqzoAE',kEXPI:'0,1359409,6059,206,4804,2316,383,246,5,5367,1123753,1197777,380713,16115,28684,22430,1362,283,12036,17580,4998,13228,516,3331,10622,22741,5081,1593,1279,2742,149,1103,840,1983,4,210,4100,3514,606,2023,2299,14668,3229,2843,7,4773,826,23475,4696,1851,15756,3,346,230,6459,149,13975,4,1528,2304,7039,20309,7422,7357,13658,4437,16786,5812,2545,4094,4052,3,3541,1,11943,30211,2,8984,1,5037,6249,19490,5679,1020,2378,28745,4568,6258,23418,1252,5835,14967,4333,4239,3245,27082,239,7916,7381,15969,874,19633,6,1923,5784,3995,21779,1120,8423,4832,26080,423,107,5690,3,14433,3890,751,14879,3,683,217,1405,1779,1854,31,1966,1119,6,8909,323,5659,1741,814,1224,10,280,2346,82,1419,3,565,401,519,68,970,1125,440,398,156,367,1034,333,3392,526,396,3,1431,3,785,2,312,2312,196,907,342,244,618,314,1,293,568,171,1104,14,89,891,56,857,306,14,509,154,246,1110,219,628,249,229,49,8,8,3,55,4,399,55,39,1072,49,43,2,468,782,83,123,641,1502,166,350,707,195,5,140,358,329,692,109,1,20,108,134,547,67,5,49,93,31,77,124,79,355,160,27,829,236,764,12,35,118,98,803,1,65,436,5,5,54,2065,262,5,3,647,3,8,2,14,39,65,380,80,14,790,346,115,99,1323,4,711,242,2,723,2286,5280608,12,5934,147,81,8798948,3311,141,795,19735,1,1,346,1755,1004,41,342,1,189,14,9,4,6,3,3,4,1,2,2,3,2,2,2,1,2,5,2,2,1,2,2,2,23947077,512,18,13,2737921,1303678,1964,3094,13579,3405,5595,11,3835,1923,3208,1069,1480676,40778',kBL:'p9Xv'};google.sn='webhp';google.kHL='es';})();(function(){var f=this||self;var h,k=[];function l(a){for(var b;a&&(!a.getAttribute||!(b=a.getAttribute("eid")));)a=a.parentNode;return b||h}function m(a){for(var b=null;a&&(!a.getAttribute||!(b=a.getAttribute("leid")));)a=a.parentNode;return b}function n(a,b,c,d,g){var e="";c||-1!==b.search("&ei=")||(e="&ei="+l(d),-1===b.search("&lei=")&&(d=m(d))&&(e+="&lei="+d));d="";!c&&f._cshid&&-1===b.search("&cshid=")&&"slh"!==a&&(d="&cshid="+f._cshid);c=c||"/"+(g||"gen_204")+"?atyp=i&ct="+a+"&cad="+b+e+"&zx="+Date.now()+d;/^http:/i.test(c)&&"https:"===window.location.protocol&&(google.ml&&google.ml(Error("a"),!1,{src:c,glmm:1}),c="");return c};h=google.kEI;google.getEI=l;google.getLEI=m;google.ml=function(){return null};google.log=function(a,b,c,d,g){if(c=n(a,b,c,d,g)){a=new Image;var e=k.length;k[e]=a;a.onerror=a.onload=a.onabort=function(){delete k[e]};a.src=c}};google.logUrl=n;}).call(this);(function(){google.y={};google.sy=[];google.x=function(a,b){if(a)var c=a.id;else{do c=Math.random();while(google.y[c])}google.y[c]=[a,b];return!1};google.sx=function(a){google.sy.push(a)};google.lm=[];google.plm=function(a){google.lm.push.apply(google.lm,a)};google.lq=[];google.load=function(a,b,c){google.lq.push([[a],b,c])};google.loadAll=function(a,b){google.lq.push([a,b])};google.bx=!1;google.lx=function(){};}).call(this);google.f={};(function(){document.documentElement.addEventListener("submit",function(b){var a;if(a=b.target){var c=a.getAttribute("data-submitfalse");a="1"===c||"q"===c&&!a.elements.q.value?!0:!1}else a=!1;a&&(b.preventDefault(),b.stopPropagation())},!0);document.documentElement.addEventListener("click",function(b){var a;a:{for(a=b.target;a&&a!==document.documentElement;a=a.parentElement)if("A"===a.tagName){a="1"===a.getAttribute("data-nohref");break a}a=!1}a&&b.preventDefault()},!0);}).call(this);</script><style>#gbar,#guser{font-size:13px;padding-top:1px !important;}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb4{color:#00c !important}.gbi .gb4{color:#dd8e27 !important}.gbf .gb4{color:#900 !important}</style><style>body,td,a,p,.h{font-family:arial,sans-serif}body{margin:0;overflow-y:scroll}#gog{padding:3px 8px 0}td{line-height:.8em}.gac_m td{line-height:17px}form{margin-bottom:20px}.h{color:#1558d6}em{font-weight:bold;font-style:normal}.lst{height:25px;width:496px}.gsfi,.lst{font:18px arial,sans-serif}.gsfs{font:17px arial,sans-serif}.ds{display:inline-box;display:inline-block;margin:3px 0 4px;margin-left:4px}input{font-family:inherit}body{background:#fff;color:#000}a{color:#4b11a8;text-decoration:none}a:hover,a:active{text-decoration:underline}.fl a{color:#1558d6}a:visited{color:#4b11a8}.sblc{padding-top:5px}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px}.lsbb{background:#f8f9fa;border:solid 1px;border-color:#dadce0 #70757a #70757a #dadce0;height:30px}.lsbb{display:block}#WqQANb a{display:inline-block;margin:0 12px}.lsb{background:url(/images/nav_logo229.png) 0 -261px repeat-x;border:none;color:#000;cursor:pointer;height:30px;margin:0;outline:0;font:15px arial,sans-serif;vertical-align:top}.lsb:active{background:#dadce0}.lst:focus{outline:none}</style><script nonce="Jo7WFU6XWWwu6NrdwaRyIw">(function(){window.google.erd={jsr:1,bv:1698,de:true};var h=this||self;var k,l=null!=(k=h.mei)?k:1,n,p=null!=(n=h.sdo)?n:!0,q=0,r,t=google.erd,v=t.jsr;google.ml=function(a,b,d,m,e){e=void 0===e?2:e;b&&(r=a&&a.message);if(google.dl)return google.dl(a,e,d),null;if(0>v){window.console&&console.error(a,d);if(-2===v)throw a;b=!1}else b=!a||!a.message||"Error loading script"===a.message||q>=l&&!m?!1:!0;if(!b)return null;q++;d=d||{};b=encodeURIComponent;var c="/gen_204?atyp=i&ei="+b(google.kEI);google.kEXPI&&(c+="&jexpid="+b(google.kEXPI));c+="&srcpg="+b(google.sn)+"&jsr="+b(t.jsr)+"&bver="+b(t.bv);var f=a.lineNumber;void 0!==f&&(c+="&line="+f);var g=a.fileName;g&&(0<g.indexOf("-extension:/")&&(e=3),c+="&script="+b(g),f&&g===window.location.href&&(f=document.documentElement.outerHTML.split(" ")[f],c+="&cad="+b(f?f.substring(0,300):"No script found.")));c+="&jsel="+e;for(var u in d)c+="&",c+=b(u),c+="=",c+=b(d[u]);c=c+"&emsg="+b(a.name+": "+a.message);c=c+"&jsst="+b(a.stack||"N/A");12288<=c.length&&(c=c.substr(0,12288));a=c;m||google.log(0,"",a);return a};window.onerror=function(a,b,d,m,e){r!==a&&(a=e instanceof Error?e:Error(a),void 0===d||"lineNumber"in a||(a.lineNumber=d),void 0===b||"fileName"in a||(a.fileName=b),google.ml(a,!1,void 0,!1,"SyntaxError"===a.name||"SyntaxError"===a.message.substring(0,11)||-1!==a.message.indexOf("Script error")?3:0));r=null;p&&q>=l&&(window.onerror=null)};})();</script></head><body bgcolor="#fff"><script nonce="Jo7WFU6XWWwu6NrdwaRyIw">(function(){var src='/images/nav_logo229.png';var iesg=false;document.body.onload = function(){window.n && window.n();if (document.images){new Image().src=src;}if (!iesg){document.f&&document.f.q.focus();document.gbqf&&document.gbqf.q.focus();}}})();</script><div id="mngb"><div id=gbar><nobr><b class=gb1>B�squeda</b> <a class=gb1 href="https://www.google.es/imghp?hl=es&tab=wi">Im�genes</a> <a class=gb1 href="https://maps.google.es/maps?hl=es&tab=wl">Maps</a> <a class=gb1 href="https://play.google.com/?hl=es&tab=w8">Play</a> <a class=gb1 href="https://www.youtube.com/?tab=w1">YouTube</a> <a class=gb1 href="https://news.google.com/?tab=wn">Noticias</a> <a class=gb1 href="https://mail.google.com/mail/?tab=wm">Gmail</a> <a class=gb1 href="https://drive.google.com/?tab=wo">Drive</a> <a class=gb1 style="text-decoration:none" href="https://www.google.es/intl/es/about/products?tab=wh"><u>M�s</u> »</a></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe></span><a href="http://www.google.es/history/optout?hl=es" class=gb4>Historial web</a> | <a href="/preferences?hl=es" class=gb4>Ajustes</a> | <a target=_top id=gb_70 href="https://accounts.google.com/ServiceLogin?hl=es&passive=true&continue=https://www.google.com/&ec=GAZAAQ" class=gb4>Iniciar sesi�n</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div></div><center><br clear="all" id="lgpd"><div id="lga"><img alt="Google" height="92" src="/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png" style="padding:28px 0 14px" width="272" id="hplogo"><br><br></div><form action="/search" name="f"><table cellpadding="0" cellspacing="0"><tr valign="top"><td width="25%"> </td><td align="center" nowrap=""><input name="ie" value="ISO-8859-1" type="hidden"><input value="es" name="hl" type="hidden"><input name="source" type="hidden" value="hp"><input name="biw" type="hidden"><input name="bih" type="hidden"><div class="ds" style="height:32px;margin:4px 0"><input class="lst" style="margin:0;padding:5px 8px 0 6px;vertical-align:top;color:#000" autocomplete="off" value="" title="Buscar con Google" maxlength="2048" name="q" size="57"></div><br style="line-height:0"><span class="ds"><span class="lsbb"><input class="lsb" value="Buscar con Google" name="btnG" type="submit"></span></span><span class="ds"><span class="lsbb"><input class="lsb" id="tsuid_1" value="Voy a tener suerte" name="btnI" type="submit"><script nonce="Jo7WFU6XWWwu6NrdwaRyIw">(function(){var id='tsuid_1';document.getElementById(id).onclick = function(){if (this.form.q.value){this.checked = 1;if (this.form.iflsig)this.form.iflsig.disabled = false;}else top.location='/doodles/';};})();</script><input value="AJiK0e8AAAAAY46fV7gpXBHCT6KAebFZAqGv1l-4BtIR" name="iflsig" type="hidden"></span></span></td><td class="fl sblc" align="left" nowrap="" width="25%"><a href="/advanced_search?hl=es&authuser=0">B�squeda avanzada</a></td></tr></table><input id="gbv" name="gbv" type="hidden" value="1"><script nonce="Jo7WFU6XWWwu6NrdwaRyIw">(function(){var a,b="1";if(document&&document.getElementById)if("undefined"!=typeof XMLHttpRequest)b="2";else if("undefined"!=typeof ActiveXObject){var c,d,e=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];for(c=0;d=e[c++];)try{new ActiveXObject(d),b="2"}catch(h){}}a=b;if("2"==a&&-1==location.search.indexOf("&gbv=2")){var f=google.gbvu,g=document.getElementById("gbv");g&&(g.value=a);f&&window.setTimeout(function(){location.href=f},0)};}).call(this);</script></form><div id="gac_scont"></div><div style="font-size:83%;min-height:3.5em"><br><div id="gws-output-pages-elements-homepage_additional_languages__als"><style>#gws-output-pages-elements-homepage_additional_languages__als{font-size:small;margin-bottom:24px}#SIvCob{color:#3c4043;display:inline-block;line-height:28px;}#SIvCob a{padding:0 3px;}.H6sW5{display:inline-block;margin:0 2px;white-space:nowrap}.z4hgWe{display:inline-block;margin:0 2px}</style><div id="SIvCob">Ofrecido por Google en: <a href="https://www.google.com/setprefs?sig=0_HljXEzVisqsnlJP1S5dx0Fao0Lw%3D&hl=ca&source=homepage&sa=X&ved=0ahUKEwiimaPC4uP7AhU3UKQEHXzFDBQQ2ZgBCAU">catal�</a> <a href="https://www.google.com/setprefs?sig=0_HljXEzVisqsnlJP1S5dx0Fao0Lw%3D&hl=gl&source=homepage&sa=X&ved=0ahUKEwiimaPC4uP7AhU3UKQEHXzFDBQQ2ZgBCAY">galego</a> <a href="https://www.google.com/setprefs?sig=0_HljXEzVisqsnlJP1S5dx0Fao0Lw%3D&hl=eu&source=homepage&sa=X&ved=0ahUKEwiimaPC4uP7AhU3UKQEHXzFDBQQ2ZgBCAc">euskara</a> </div></div></div><span id="footer"><div style="font-size:10pt"><div style="margin:19px auto;text-align:center" id="WqQANb"><a href="http://www.google.es/intl/es/services/">Soluciones Empresariales</a><a href="/intl/es/about.html">Todo acerca de Google</a><a href="https://www.google.com/setprefdomain?prefdom=ES&prev=https://www.google.es/&sig=K_8O8QHBmoai9DOT5YZxMWevJK8VI%3D">Google.es</a></div></div><p style="font-size:8pt;color:#70757a">© 2022 - <a href="/intl/es/policies/privacy/">Privacidad</a> - <a href="/intl/es/policies/terms/">T�rminos</a></p></span></center><script nonce="Jo7WFU6XWWwu6NrdwaRyIw">(function(){window.google.cdo={height:757,width:1440};(function(){var a=window.innerWidth,b=window.innerHeight;if(!a||!b){var c=window.document,d="CSS1Compat"==c.compatMode?c.documentElement:c.body;a=d.clientWidth;b=d.clientHeight}a&&b&&(a!=google.cdo.width||b!=google.cdo.height)&&google.log("","","/client_204?&atyp=i&biw="+a+"&bih="+b+"&ei="+google.kEI);}).call(this);})();</script> <script nonce="Jo7WFU6XWWwu6NrdwaRyIw">(function(){google.xjs={ck:'xjs.hp.oxai9SxkIQY.L.X.O',cs:'ACT90oEGh-_ImDfBjn6aD_ABGaOlD2MqVw',excm:[]};})();</script> <script nonce="Jo7WFU6XWWwu6NrdwaRyIw">(function(){var u='/xjs/_/js/k=xjs.hp.en.9b-uVUIpJU8.O/am=AADoBABQAGAB/d=1/ed=1/rs=ACT90oG-6KYVksw4jxVvNcwan406xE6qVw/m=sb_he,d';var amd=0;var d=this||self,e=function(a){return a};var g;var l=function(a,b){this.g=b===h?a:""};l.prototype.toString=function(){return this.g+""};var h={};function m(){var a=u;google.lx=function(){p(a);google.lx=function(){}};google.bx||google.lx()}function p(a){google.timers&&google.timers.load&&google.tick&&google.tick("load","xjsls");var b=document;var c="SCRIPT";"application/xhtml+xml"===b.contentType&&(c=c.toLowerCase());c=b.createElement(c);if(void 0===g){b=null;var k=d.trustedTypes;if(k&&k.createPolicy){try{b=k.createPolicy("goog#html",{createHTML:e,createScript:e,createScriptURL:e})}catch(q){d.console&&d.console.error(q.message)}g=b}else g=b}a=(b=g)?b.createScriptURL(a):a;a=new l(a,h);c.src=a instanceof l&&a.constructor===l?a.g:"type_error:TrustedResourceUrl";var f,n;(f=(a=null==(n=(f=(c.ownerDocument&&c.ownerDocument.defaultView||window).document).querySelector)?void 0:n.call(f,"script[nonce]"))?a.nonce||a.getAttribute("nonce")||"":"")&&c.setAttribute("nonce",f);document.body.appendChild(c);google.psa=!0};google.xjsu=u;setTimeout(function(){0<amd?google.caft(function(){return m()},amd):m()},0);})();function _DumpException(e){throw e;}function _F_installCss(c){}(function(){google.jl={blt:'none',chnk:0,dw:false,dwu:true,emtn:0,end:0,ico:false,ikb:0,ine:false,injs:'none',injt:0,injth:0,injv2:false,lls:'default',pdt:0,rep:0,snet:true,strt:0,ubm:false,uwp:true};})();(function(){var pmc='{"d":{},"sb_he":{"agen":true,"cgen":true,"client":"heirloom-hp","dh":true,"ds":"","fl":true,"host":"google.com","jsonp":true,"lm":true,"msgs":{"cibl":"Borrar b�squeda","dym":"Quiz�s quisiste decir:","lcky":"Voy a tener suerte","lml":"M�s informaci�n","psrc":"Esta b�squeda se ha eliminado de tu \u003Ca href=\"/history\"\u003Ehistorial web\u003C/a\u003E.","psrl":"Eliminar","sbit":"Buscar por imagen","srch":"Buscar con Google"},"ovr":{},"pq":"","rfs":[],"sbas":"0 3px 8px 0 rgba(0,0,0,0.2),0 0 0 1px rgba(0,0,0,0.08)","stok":"GYSMF2y7hymT0L3W0W4RPVIsSrU"}}';google.pmc=JSON.parse(pmc);})();</script> </body></html>
Descargar archivos con wget
Otro comando parecido es wget
, sin embargo, a diferencia de curl
, wget
descarga el archivo directamente
!wget https://www.google.com
--2022-12-06 01:49:19-- https://www.google.com/Resolviendo www.google.com (www.google.com)... 142.250.200.68, 2a00:1450:4003:80c::2004Conectando con www.google.com (www.google.com)[142.250.200.68]:443... conectado.Petición HTTP enviada, esperando respuesta... 200 OKLongitud: no especificado [text/html]Guardando como: “index.html.1”index.html.1 [ <=> ] 14,76K --.-KB/s en 0,002s2022-12-06 01:49:19 (7,17 MB/s) - “index.html.1” guardado [15117]
!ls -l
total 316-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 15168 dic 6 01:48 google.html-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html-rw-rw-r-- 1 wallabot wallabot 15117 dic 6 01:49 index.html.1-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
Vemos que lo ha guardado como index.html
, que es como Google lo tiene nombrado
Si queremos que se guarde con un nombre específico podemos usar el flag -O
!wget https://www.google.com -O google2.html
--2022-12-06 01:49:37-- https://www.google.com/Resolviendo www.google.com (www.google.com)... 142.250.200.68, 2a00:1450:4003:80c::2004Conectando con www.google.com (www.google.com)[142.250.200.68]:443... conectado.Petición HTTP enviada, esperando respuesta... 200 OKLongitud: no especificado [text/html]Guardando como: “google2.html”google2.html [ <=> ] 14,78K --.-KB/s en 0,003s2022-12-06 01:49:37 (5,27 MB/s) - “google2.html” guardado [15131]
!ls -l
total 332-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 15131 dic 6 01:49 google2.html-rw-rw-r-- 1 wallabot wallabot 15168 dic 6 01:48 google.html-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html-rw-rw-r-- 1 wallabot wallabot 15117 dic 6 01:49 index.html.1-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
Depuración de la ruta con traceroute
Un comando muy útil es ver la ruta hasta un destino, para ello usamos traceroute
, por ejemplo vamos a ver todos los sitios por los que tengo que pasar para conectarme a Google
!traceroute www.google.com
traceroute to www.google.com (142.250.200.68), 64 hops max1 192.168.1.1 0,435ms 0,154ms 0,133ms2 188.127.176.1 3,979ms 2,914ms 3,397ms3 10.15.0.77 3,600ms 3,914ms 2,669ms4 10.15.246.6 3,567ms 3,713ms 2,926ms5 * * *6 72.14.209.84 3,981ms 2,914ms 2,993ms7 * * *8 142.251.54.148 3,856ms 2,916ms 2,905ms9 142.250.200.68 2,908ms 2,949ms 3,037ms
Depuración de la ruta con mtr
Otra herramienta de depuración es mtr
, que es una versión mejorada de traceroute
. Ofrece información de cada salto, como el tiempo de respuesta, el porcentaje de paquetes perdidos, etc.
!mtr -n maximofn.com
wallabot (192.168.178.144)Keys: Help Display mode Restart statistics Order of fields quitPackets PingsHost Loss% Snt Last Avg Best Wrst StDev1. 192.168.178.1 0.0% 345 0.3 0.3 0.3 0.3 0.02. 192.168.0.1 0.0% 344 0.8 1.1 1.1 1.1 0.03. (waiting for reply)4. 10.183.52.41 0.0% 344 2.8 2.5 2.5 2.5 0.05. 172.29.0.161 47.7% 344 2.3 3.1 3.1 23.1 0.06. (waiting for reply)7. 193.149.1.97 0.0% 344 3.6 3.6 3.6 38.6 0.08. (waiting for reply)9. 185.125.78.197 2.9% 344 6.9 6.9 6.9 6.9 0.0
Como se puede ver en el salto 5 se pierde casi el 50 % de los paquetes, por lo que me serviría para llamar a mi compañía de teléfono y decirle que me intente enrutar por otro lado
Nombre de nuestra máquina con hostname
Si queremos saber el nombre de nuestro equipo podemos usar hostname
, lo cual es útil si queremos conectarnos a nuestra máquina desde otra.
!hostname
wallabot
Información de enlace de puerta predeterminada con route -n
Si queremos conocer nuestra puerta de enlace predeterminada usamos el comando route -n
!route -n
Tabla de rutas IP del núcleoDestino Pasarela Genmask Indic Métric Ref Uso Interfaz0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 enp6s0169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 enp6s0172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-470e52ae2708192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 enp6s0
Información de la IP de un dominio con nslookup
Si queremos saber la IP de algún dominio, lo podemos saber mediante el comando nslookup
!nslookup google.com
Server: 127.0.0.53Address: 127.0.0.53#53Non-authoritative answer:Name: google.comAddress: 142.250.185.14Name: google.comAddress: 2a00:1450:4003:808::200e
Esto nos dice que la IPv4 de Google es 172.217.168.174 y su IPv6 es 2a00:1450:4003:803::200e
Información de nuestra red con netstats
El último comando de utilidad es netstats
, este comando nos da el estado de nuestra red, además con el flag -i
nos devuelve nuestras interfaces de red
!netstat -i
Tabla de la interfaz del núcleoIface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flgbr-470e5 1500 0 0 0 0 0 0 0 0 BMUdocker0 1500 0 0 0 0 0 0 0 0 BMUenp6s0 1500 148385 0 2182 0 106135 0 0 0 BMRUlo 65536 11674 0 0 0 11674 0 0 0 LRUwlp5s0 1500 0 0 0 0 0 0 0 0 BMU
Consultas DNS con dig
Con el comando dig <dominio>
podemos hacer consultas DNS, por ejemplo, vamos a hacer una consulta a Google
!dig google.com
; <<>> DiG 9.16.1-Ubuntu <<>> google.com;; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20527;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1;; OPT PSEUDOSECTION:; EDNS: version: 0, flags:; udp: 65494;; QUESTION SECTION:;google.com. IN A;; ANSWER SECTION:google.com. 283 IN A 142.250.184.14;; Query time: 8 msec;; SERVER: 127.0.0.53#53(127.0.0.53);; WHEN: dom sep 24 01:32:07 CEST 2023;; MSG SIZE rcvd: 55
Se puede ver
;; ANSWER SECTION:
google.com. 283 IN A 142.250.184.14
Por lo que la consulta nos ha dado la IP de Google
Podemos hacerle la consulta a un servidor DNS en particular con dig @<servidor DNS> <dominio>
!dig @1.1.1.1 google.com
; <<>> DiG 9.16.1-Ubuntu <<>> @1.1.1.1 google.com; (1 server found);; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15633;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0;; QUESTION SECTION:;google.com. IN A;; ANSWER SECTION:google.com. 190 IN A 142.250.184.14;; Query time: 8 msec;; SERVER: 1.1.1.1#53(1.1.1.1);; WHEN: dom sep 24 01:33:40 CEST 2023;; MSG SIZE rcvd: 44
Hemos hecho la misma consulta, pero se la hemos hecho al DNS de Cloudflare
Comprimiendo archivos
Antes de comprimir y descomprimir vamos a ver qué vamos a comprimir, primero imprimimos nuestra ruta y listamos los archivos.
!pwd; ls -l
/home/wallabot/Documentos/web/portafolio/posts/pruebatotal 332-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 15131 dic 6 01:49 google2.html-rw-rw-r-- 1 wallabot wallabot 15168 dic 6 01:48 google.html-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html-rw-rw-r-- 1 wallabot wallabot 15117 dic 6 01:49 index.html.1-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
Vamos a crear una nueva carpeta y a copiar todo lo que está dentro de la actual carpeta en ella
!mkdir tocompress; cp * tocompress; ls -l
cp: -r not specified; omitting directory 'tocompress'total 336-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 15131 dic 6 01:49 google2.html-rw-rw-r-- 1 wallabot wallabot 15168 dic 6 01:48 google.html-rw-rw-r-- 1 wallabot wallabot 0 dic 6 00:56 index.html-rw-rw-r-- 1 wallabot wallabot 15117 dic 6 01:49 index.html.1-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.txtdrwxrwxr-x 2 wallabot wallabot 4096 dic 6 01:52 tocompress
Como vemos se ha copiado todo menos la propia carpeta tocompress
ya que no hemos puesto el flag -r
en el comando cp
. Pero lo que ha pasado es lo que queríamos
Comprimir con tar
El primer comando que vamos a usar para comprimir es tar
al que vamos a añadir el flag -c
de compress, -v
de verbose, para que nos vaya sacando qué está haciendo y el flag -f
de file, y a continuación el nombre que queremos que tenga el archivo comprimido y el nombre del archivo que queremos comprimir
!tar -cvf tocompress.tar tocompress
tocompress/tocompress/lista.txttocompress/dot.txttocompress/google.htmltocompress/index.htmltocompress/Abctocompress/google2.htmltocompress/dot2.txttocompress/secuential.txttocompress/index.html.1tocompress/file.txttocompress/datos1tocompress/2021-02-11-Introduccion-a-Python.ipynbtocompress/datos123
!ls -l