terminal
(→Conceptos básicos) |
|||
(No se muestran 38 ediciones intermedias realizadas por 2 usuarios) | |||
Línea 1: | Línea 1: | ||
− | La mayoría de usuari.x.s GNU/linux trabajan directamente des de la terminal. Básicamante, su uso facilita y accelera el trabajo. |
+ | La terminal es una interfaz de línea de comando que permite interactuar con la computadora. Al igual que cualquier GUI (por Graphical User Interface) con la que hayamos trabajado en Windows o Linux, la terminal nos permite acceder a directorios (carpetas) y archivos, generar nuevos archivos y moverlos a otras ubicaciones entre otro millón de cosas. |
− | = Terminal = |
+ | Entonces, ¿porqué "complicarnos" con la terminal si puedo hacer lo mismo con un par de clicks del mouse? Cuando queremos interactuar con la computadora de manera compleja, hacer tareas repetitivas o por ejemplo conectarnos de manera remota con otras computadoras, necesitamos saber usar la terminal. |
− | La terminal otorga una interfaz al usuari.x. mediante la cuál se acceden a los fichero y aplicaciones. |
||
− | [[File:Terminal.png]] |
+ | = ¿Cómo funciona? = |
+ | |||
+ | Al abrir la terminal nos encontramos con una pantalla negra y en la primera linea algo como lo siguiente: |
||
+ | |||
+ | [[Archivo:terminal.png]] |
||
+ | |||
+ | Esto va a ser <code>usuario@nombredelacomputadora:~$</code>. Acá el <code>~</code> indica el directorio raíz y el <code>$</code> o '''prompt''' indica que la shell está esperando instrucciones. |
||
+ | |||
+ | La '''shell''' es un programa que interpreta nuestras ordenes y las traduce en lenguaje computadora. A travez de la shell podemos hacer cosas tan simples como copiar un archivo con un simple comando hasta correr un modelo de simulación numérica. |
||
+ | |||
+ | == Herramientras básicas == |
||
+ | |||
+ | Las herramientas básicas vienen pre-instaladas con el sistema operativo en en el paquete [https://wiki.debian.org/coreutils coreutils] (o GNU Core Utilities). Por ejemplo: |
||
+ | |||
+ | <PRE style="shell"> |
||
+ | $ ls |
||
+ | |||
+ | Desktop Downloads Pictures Test |
||
+ | Documents Music terminal.png |
||
− | == Ideas básicas == |
||
− | El sistema operativo se configura a través de unas variables de sistema generales |
||
− | * <CODE>$HOME:</CODE> Ubicación inicial al abrir una terminal cómo usuarix (<CODE>/home/[usuarix]</CODE>) |
||
− | * <CODE>$PATH:</CODE> Directorios que ya están cargados automáticamente al abrir un terminal. Suelen ser directorios con aplicaciones, así no hace falta saber dónde se encuentran las aplicaciones. Por ejemplo: |
||
− | <PRE> |
||
− | /home/lluis/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games |
||
</PRE> |
</PRE> |
||
− | * <CODE>$LD_LIBRARY_PATH:</CODE> Librerias cargadas en el sistema |
||
− | == coreutils == |
+ | Este comando lista el contenido dentro del directorio actual. Y su nombre viene de "list". Se puede extender las capacidades de los comandos con '''flags''' usando la siguiente sintaxis: |
− | Las [https://wiki.debian.org/coreutils coreutils] son pequeñas herramientas instaladas por defecto con el sistema, que hacen muy eficientemente operaciones muy sencillas. Hay de distinto tipos: <I>ficheros</I>, <I>shell</I> y <I>texto</I> |
||
− | === Instrucciones básicas === |
+ | <PRE style="shell"> |
− | Las herramientas del <code>coreutils</code>, se utilizan mediante <I>'flags'</I> (normalmente '-flag') que regulan la ejecución de la herramienta |
+ | $ [comando] -flags |
− | <PRE> |
||
− | $ [herramienta] -flag1 -flag2 ... |
||
</PRE> |
</PRE> |
||
− | Se accede a la ayuda de la herramienta con: <code>-h --h -help --help</code> (en función de la herramienta) |
+ | Por ejemplo, si quisiéramos más información sobre los archivos y directorios que están en el directorio actual usamos: |
− | <PRE> |
+ | |
− | $ [herramienta] --h |
+ | <PRE style="shell"> |
+ | $ ls -l |
||
+ | drwxr-xr-x 2 pao pao 4,0K may 19 15:24 Desktop |
||
+ | drwxr-xr-x 17 pao pao 4,0K mar 16 13:52 Documents |
||
+ | drwxr-xr-x 10 pao pao 16K jun 9 16:38 Downloads |
||
+ | drwxr-xr-x 2 pao pao 4,0K ene 19 2018 Music |
||
+ | drwxr-xr-x 19 pao pao 4,0K jun 8 18:35 Pictures |
||
+ | -rw-r--r-- 1 pao pao 11132 jun 9 16:38 terminal.png |
||
+ | drwxr-xr-x 2 pao pao 4096 jun 9 17:54 Test |
||
</PRE> |
</PRE> |
||
− | O bien en un formato texto con <code>man</code> (sólo aparecerá si se ha instalado la documentación de la aplicación) |
+ | Existen una infinidad de comandos, cada uno con sus flags y a diferencia de una interfaz gráfica donde tenemos botones, al trabajar en la terminal es necesario conocerlos. Esto se aprende con práctica pero también googleando aquello que queremos resolver. |
− | <PRE> |
+ | |
− | $ man [herramienta] |
+ | |
+ | == Navegando entre directorios == |
||
+ | |||
+ | Lo primero es saber donde estamos parados dentro de la computadora, para eso existe el comando <code>pwd</code> (que viene de "print working directory"): |
||
+ | |||
+ | <PRE style="shell"> |
||
+ | $ pwd |
||
+ | /home/pao |
||
</PRE> |
</PRE> |
||
− | Distintos comandos básicos... (normalmentes nombre fruto de una abreviación...) |
+ | En este caso estamos parados en el '''home'''. La respuesta de este comando puede ser distinta dependiendo del sistema operativo, pero dentro del mundo de linux no debería variar mucho. |
− | * <code>ls</code>: <I>'list'</I>, lista el contenido de un directorio (un directorio es el equivalente de 'carpeta' de Windows) |
+ | El home es la carpeta principal del usuario, donde se guardará todo. Pero por encima hay toda una estructura de archivos que organizan los programas instalados, las herramientas de sistema y los ''"homes"'' de otros usuarios dentro de la misma computadora. |
− | <PRE> |
+ | |
− | $ ls |
+ | Otra manera de ver donde estamos, es revisando el contenido del directorio con <code>ls</code> y reconoceer así el directorio. |
− | 20160324_bash.pdf install.inf prueba.bash Terminal.png test.bash |
+ | |
− | $ ls -l |
+ | Si queremos "movernos" dentro de la computadora hacia otro directorio, el comando indicado es <code>cd</code> (que vienen de ''"change directory"'', para esta altura seguro ya descubrieron el patrón). |
− | total 244 |
+ | |
− | -rw-r--r-- 1 lluis lluis 221654 Jun 6 10:49 20160324_bash.pdf |
+ | Por ejemplo queremos movernos al directorio "Test" (ojo, shell es case sensitive, las mayusculas y minusculas no son intercambiables!): |
− | -rw-rw-r-- 1 lluis lluis 328 Apr 25 14:53 install.inf |
+ | |
− | -rwxr--r-- 1 lluis lluis 114 Jun 6 11:27 prueba.bash |
+ | <PRE style="shell"> |
− | -rw-r--r-- 1 lluis lluis 11172 Apr 11 16:27 Terminal.png |
+ | $ cd Test |
− | -rw-r--r-- 1 lluis lluis 4056 Jun 6 10:49 test.bash |
||
</PRE> |
</PRE> |
||
− | * <code>mkdir</code>: <I>'makedirectoy'</I>, creación de un directorio |
+ | Este comando no devuelve nada pero si usamos <code>pwd</code>, veremos que ahora estamos en un nuevo directorio. |
− | <PRE> |
+ | |
− | $ mkdir parTUXza |
+ | Para volver al directorio anterior usamos <code>..</code>, es un "directorio especial" que representa el directorio previo o parent directory. También existe un <code>.</code> que representa el directorio actual. Pueden verlos usando <code>$ ls -a</code> para mostrar todos ("all") los elementos en el directorio actual |
+ | |||
+ | <PRE style="shell"> |
||
+ | $ cd .. |
||
+ | </PRE> |
||
+ | |||
+ | === Path absolutos y relativos === |
||
+ | |||
+ | En el ejemplo anterior usamos <code>cd</code> para movernos y el nombre del directorio al cual queremos ir. Cómo el directorio Test estaba adentro del directorio de trabajo accedimos sin problemas pero si hubiéramos estado en otro lado nos hubiera dicho que no existe un directorio Test. Esto es así porque le estamos dando el <CODE>path</CODE> relativo (relativo al directorio donde estamos parados). Pero <code>cd</code> también puede interpretar la ubicación exacta o absoluta de un directorio. Por ejemplo: |
||
+ | |||
+ | <PRE style="shell"> |
||
+ | $ cd /home/pao/Test |
||
+ | </PRE> |
||
+ | |||
+ | === Algunos trucos === |
||
+ | |||
+ | Muchas veces escribimos mal el nombre de un directorio o archivo, a veces son super largos o el path absoluto es enorme. Existen varios atajos para hacernos la vida más simple: |
||
+ | |||
+ | * <code>Tab</code>: La tecla Tab completa el nombre del archivo o directorio. Basta con escribir las primeras letras del nombre y luego con la tecla tab se termina de escribir automáticamente el nombre. |
||
+ | [[Archivo:tabKey.png]] |
||
+ | * <code>Ctrl + a</code>: Principio de línea. Se manda el cursos al principio de la línea de comando. También funciona la tecla Inicio. |
||
+ | * <code>Ctrl + e</code>: Final de línea. Se manda el cursos al final de la línea de comando. O también la tecla Fin. |
||
+ | |||
+ | == Manipulando archivos y directoios == |
||
+ | |||
+ | * <code>mkdir</code>: Para crear directorios usamos el comando <code>mkdir</code> (por supuesto de ''"make directory"''): |
||
+ | |||
+ | <PRE style="shell"> |
||
+ | $ mkdir Test2 |
||
$ ls |
$ ls |
||
− | 20160324_bash.pdf install.inf parTUXza prueba.bash Terminal.png test.bash |
+ | Desktop Downloads Pictures Test |
− | $ ls parTUXza |
+ | Documents Music terminal.png Test2 |
$ |
$ |
||
</PRE> |
</PRE> |
||
− | * <code>cp</code>: <I>'copy'</I>, copiar fichero |
+ | La ubicación del nuevo directorio dependerá de la ubicación relativa o absoluta que le dimos. En este caso, se creará en el directorio donde estamos trabajando. |
− | <PRE> |
+ | |
+ | * <code>cp</code>: si quisiéramos copiar un archivo en otra ubicación usamos <code>cp</code> (de ''"copy"''). Este comando necesita saber que copiar y donde copiarlo: <code>cp [origen] [destino]</code>, por ejemplo: |
||
+ | |||
+ | <PRE style="shell"> |
||
$ cp [origen] [destino] |
$ cp [origen] [destino] |
||
− | $ cp Terminal.png parTUXza |
+ | $ cp terminal.png Test |
− | $ ls parTUXza |
+ | $ ls Test |
− | $ Terminal.png |
+ | $ terminal.png |
</PRE> |
</PRE> |
||
− | * <code>mv</code>: <I>'move'</I>, mover un fichero y/o cambiar el nombre |
+ | <code>cp</code> tiene una flag <code>-r</code> que permite copiar recursivamente un directorio y su contenido. |
− | <PRE> |
+ | |
+ | * <code>mv</code>: el comando <code>mv</code> (''"move"'') permite mover un archivo (parecido al <code>ctrl+C</code> y <code>ctrl+V</code> en una interfáz gráfica). Pero también permite cambiarle el nombre a un archivo si los "movemos" en el mismo lugar: |
||
+ | |||
+ | <PRE style="shell"> |
||
$ mv [origen] [destino] |
$ mv [origen] [destino] |
||
− | $ mv parTUXza/Terminal.png parTUXza/Terminal2.png |
+ | $ mv Test/terminal.png Test/terminal2.png |
− | $ ls parTUXza |
+ | $ ls Test |
− | Terminal2.png |
+ | terminal2.png |
</PRE> |
</PRE> |
||
− | * <code>rm</code>: <I>'remove'</I>, borrar fichero, directorio... |
+ | * <code>rm</code>: si queremos borrar un archivo usamos <code>rm</code> (de ''"remove"''). Para borrar directorios podemos agregar una flag. Pero cuidado esta acción es irreversible. La terminal no tiene papelera y no existe el <code>Ctrl+z</code>, cuidado con con lo borran! |
− | <PRE> |
+ | |
+ | <PRE style="shell"> |
||
$ rm [fichero] |
$ rm [fichero] |
||
− | $ rm parTUXza/Terminal2.png |
+ | $ rm Test/terminal2.png |
− | $ ls parTUXza |
+ | $ ls Test |
− | $ |
+ | |
</PRE> |
</PRE> |
||
+ | '''NOTA:''' para borrar directorios y todo su contenido es necesario añadirle el flag '-r' (''recursive''). Si nos da apuro, existe <CODE>rmdir</CODE> pero sólo borra directorios vacíos. |
||
+ | <PRE style="shell"> |
||
+ | $ rm Test |
||
+ | rm: cannot remove 'Test': Is a directory |
||
+ | $ rm -r Test |
||
− | * <code>rmdir</code>: <I>'removedirectory'</I>, borra directorio vacío... |
||
− | <PRE> |
||
− | $ cp Terminal.png parTUXza |
||
− | $ rmdir parTUXza |
||
− | rmdir: failed to remove 'parTUXza/': Directory not empty |
||
</PRE> |
</PRE> |
||
− | * <code>date</code>: manejo de fechas |
+ | |
+ | * <code>ls</code>: <I>'list'</I>, lista el contenido de un directorio (un directorio es el equivalente de 'carpeta' de Windows) |
||
<PRE> |
<PRE> |
||
− | $ date |
+ | $ ls |
− | Wed Jun 6 12:27:16 -03 2018 |
+ | 20160324_bash.pdf install.inf prueba.bash Terminal.png test.bash |
− | $ date "+%Y/%m/%d %H:%M:%S" |
+ | $ ls -l |
− | 2018/06/06 12:27:21 |
+ | total 244 |
− | $ date -d"35 days" |
+ | -rw-r--r-- 1 lluis lluis 221654 Jun 6 10:49 20160324_bash.pdf |
− | Wed Jul 11 12:27:27 -03 2018 |
+ | -rw-rw-r-- 1 lluis lluis 328 Apr 25 14:53 install.inf |
− | $ date -d"35 days ago" |
+ | -rwxr--r-- 1 lluis lluis 114 Jun 6 11:27 prueba.bash |
− | Wed May 2 12:27:32 -03 2018 |
+ | -rw-r--r-- 1 lluis lluis 11172 Apr 11 16:27 Terminal.png |
+ | -rw-r--r-- 1 lluis lluis 4056 Jun 6 10:49 test.bash |
||
</PRE> |
</PRE> |
||
− | === Atributos fichero === |
||
− | Al hacer un list con <code>-l</code>, nos aparecen la lista de atributos del fichero: |
||
− | * <code>ls</code>: <I>'list'</I>, lista el contenido de un directorio (un directorio es el equivalente de 'carpeta' de Windows) |
+ | === Atributos de un archivo === |
+ | Al hacer un list con <code>ls -l</code>, nos aparecen la lista de elementos en el directorio con sus atributos: |
||
+ | |||
+ | * <code>ls</code>: lista el contenido de un directorio |
||
+ | |||
<PRE> |
<PRE> |
||
$ ls -l |
$ ls -l |
||
Línea 111: | Línea 102: | ||
-rwxr--r-- 1 lluis lluis 4056 Jun 6 10:49 test.bash |
-rwxr--r-- 1 lluis lluis 4056 Jun 6 10:49 test.bash |
||
</PRE> |
</PRE> |
||
+ | |||
+ | Por ejemplo, el archivo pdf 20160324_bash.pdf tiene los siguientes atributos: |
||
* <code>-rw-r--r-- 1 lluis lluis 221654 Jun 6 10:49 20160324_bash.pdf</code>, fichero pdf |
* <code>-rw-r--r-- 1 lluis lluis 221654 Jun 6 10:49 20160324_bash.pdf</code>, fichero pdf |
||
− | ** <I>-rw-</I>: Dueño sólo puede leerlo y modificarlo |
+ | |
+ | ** <I>-rw-</I>: El dueño del archivo sólo puede leerlo y modificarlo. |
||
** <I>r--</I>: El grupo sólo puede leerlo |
** <I>r--</I>: El grupo sólo puede leerlo |
||
** <I>r--</I>: Todo el mundo sólo puede leerlo |
** <I>r--</I>: Todo el mundo sólo puede leerlo |
||
− | ** <I>lluis</I>: dueño del fichero |
+ | ** <I>lluis</I>: Dueño del archivo |
− | ** <I>lluis</I>: grupo del fichero |
+ | ** <I>lluis</I>: Grupo del archivo |
− | ** <I>221654</I>: Tamaño en bytes del fichero |
+ | ** <I>221654</I>: Tamaño en bytes del archivo |
− | ** <I>Jun 6 10:49</I>: fecha del fichero |
+ | ** <I>Jun 6 10:49</I>: fecha de la última modificación del archivo |
− | * <code>-rwxr--r-- 1 lluis lluis 4056 Jun 6 10:49 test.bash</code>: script de shell, sólo el dueñx puede ejecutarlo <code>-rwx</code> |
+ | |
− | * <code>drwxr-xr-x 2 lluis lluis 4096 Jun 6 12:25 parTUXza</code>: directorio (<code>drwx</code>), para linux, los directorios son ejectuables para todxs! |
+ | Otros archivos tiene permisos de ejecución, por ejemplo: |
+ | |||
+ | * <code>-rwxr--r-- 1 lluis lluis 4056 Jun 6 10:49 test.bash</code>: script de shell, <code>-rwx</code> indica que sólo el dueño puede ejecutarlo. |
||
+ | * <code>drwxr-xr-x 2 lluis lluis 4096 Jun 6 12:25 parTUXza</code>: directorio (<code>drwx</code>), para linux, los directorios son ejectuables para todos! |
||
+ | |||
+ | === Comodines === |
||
+ | |||
+ | Los comodines son símbolos o expresiones que actual básicamente como cómodines y te permiten ahorrar tiempo. Por ejemplo <code>*</code> funcionan como cualquier cantidad de caracteres: |
||
+ | |||
+ | <PRE style="shell"> |
||
+ | $ cp *.png Test/ |
||
+ | </PRE> |
||
+ | |||
+ | En este caso todos los archivos que terminen con ".png" serán copiados a la carpeta Test, sin importar que nombre tengan antes del .png. |
||
+ | |||
+ | Hay muchos otros, por ejemplo <code>?</code> es como el <code>*</code> pero solo para un carácter. No es necesario aprenderlos a todos, es cuestión de práctica y a medida que los necesitamos. |
||
+ | |||
+ | === Más recursos === |
||
+ | |||
+ | Parte de este material está inspirado en la clase [https://swcarpentry.github.io/shell-novice/ The Unix Shell] de The Carpentries donde hay muchos ejemplos, ejercicios y clases más avanzadas. Es recomendable darle una mirada. |
||
+ | |||
+ | == Ayuda == |
||
+ | |||
+ | Es posible acceder a la ayuda de un comando con una flag específica <code>-h --h --help</code> (esto depende del comando). O en algunos casos, también está disponible la documentación completa a la que se accede con `man`. |
||
+ | |||
+ | <PRE style="shell"> |
||
+ | $ [comando] --h |
||
+ | $ |
||
+ | $ man [comando] |
||
+ | $ |
||
+ | </PRE> |
||
+ | |||
+ | == Variables de sistema == |
||
+ | El sistema operativo se configura a través de unas variables de sistema generales |
||
+ | * <CODE>$HOME:</CODE> Ubicación inicial al abrir una terminal cómo usuarie (<CODE>/home/[usuarix]</CODE>) |
||
+ | * <CODE>$PATH:</CODE> Directorios que ya están cargados automáticamente al abrir un terminal. Suelen ser directorios con aplicaciones, así no hace falta saber dónde se encuentran las aplicaciones. Por ejemplo: |
||
+ | <PRE style="shell"> |
||
+ | /home/lluis/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games |
||
+ | </PRE> |
||
+ | * <CODE>$LD_LIBRARY_PATH:</CODE> Librerias cargadas en el sistema |
||
= Shell scripting = |
= Shell scripting = |
||
− | La shell es la envolvente del ''hardware'' y el kernel del ordenador. El usari.x. accede al kernel y a las componentes del ordenador a través de ella. |
+ | La shell es un programa que interpreta nuestras ordenes y las traduce en lenguaje computadora. Les usuaries acceden al ''kernel'' y a las componentes de la computadora a través de ella. |
− | Esta shell permite la ejecución de '''scripts''' para automatizar esas tareas que sean repetitivas. Estas '''scripts''' se pueden programar en distintas shells. En esta introducción se dan detalles de la <code>bash: bourn-again Shell</code> (hay distitnas shells: csh, sh, ksh, ...). En estas shells se pueden utilizar todos los <I>coreutils</I>. Estas scripts constituyen un lenguajde de programación interpreatado que es masivamente utilizando dentro del entorno linux |
+ | Esta shell permite la ejecución de '''scripts''' para automatizar esas tareas que sean repetitivas. Estos '''scripts''' se pueden programar en distintas ''shell''s. En esta introducción se dan detalles de <code>bash:</code> ''bourn-again Shell'' (hay distitnas shells: csh, sh, ksh, ...). En estas shells se pueden utilizar todos los <I>coreutils</I>. Los scripts constituyen un lenguajde de programación interpreatado que es masivamente utilizando dentro del entorno linux |
− | Estas scripts de shell son programas ejecutables interpretados por el kernel. Así que tienen que tener permiso de ejecución. Se realiza con la aplicación <code>chmod</code> (<I>change mode</I>, cambiar el modo): |
+ | Los scripts de shell son programas ejecutables interpretados por el kernel. Deben tener permiso de ejecución para poder correr. Para cambiar los permisos u modos de un archivo o directorio se utiliza el comando <code>chmod</code> ("change mode" o cambiar modo): |
− | <PRE> |
+ | <PRE style="shell"> |
$ chmod u+x [ScriptShell] |
$ chmod u+x [ScriptShell] |
||
</PRE> |
</PRE> |
||
− | O bien directamente al llamar <ode>bash</code> (si el script es de bash) |
+ | O bien directamente al llamar <code>bash</code> (si el script es de bash) |
<PRE> |
<PRE> |
||
$ bash [ScriptShell] |
$ bash [ScriptShell] |
||
</PRE> |
</PRE> |
||
− | El ejemplo más senzillo de script, con nombre <code>hola.bash</code> (se elige la extensión <code>.bash</code>, pero no es obligatorio) |
+ | Este es el ejemplo más sencillo de script, con nombre <code>hola.bash</code> (se elige la extensión <code>.bash</code>, pero no es obligatorio) |
− | <PRE> |
+ | <PRE style="shell"> |
#!/bin/bash |
#!/bin/bash |
||
echo "Hola mundo!!" |
echo "Hola mundo!!" |
||
</PRE> |
</PRE> |
||
+ | |||
+ | La primera línea indica que tipo de shell vamos a usar, al incluir esto no va a ser necesario usar el comando <code>bash</code>. |
||
+ | |||
* Al ejecutarse: |
* Al ejecutarse: |
||
− | <PRE> |
+ | <PRE style="shell"> |
$ ./hola.bash |
$ ./hola.bash |
||
Hola mundo!! |
Hola mundo!! |
||
</PRE> |
</PRE> |
||
− | * En la primera línea se dice que se va a ejecutar con <code>bash</code> |
+ | * Shell va a interpretar que queremos ejecutar el archivo porque usamos <code>./</code> seguido del nombre del archivo. |
== Conceptos básicos == |
== Conceptos básicos == |
||
− | Utilizando un script test llamado <code>test.bash</code> |
||
− | * <code>echo</code>: impresión en la terminal |
||
− | * Variables: Se utilizan cómo <code>$[NombreVariable]</code> o <code>${[NombreVariable]}</code>. Se asignan con <code>'='</Code> (sin espacios!!!) |
+ | Un script es básicamente un archivo de texto con sentencias u órdenes a ser interpretadas por una computadora. Pueden contener cualquier instrucción que ejecutaríamos manualmente nosotros (ej. python, modelos, ....). |
− | <PRE> |
+ | |
+ | Estos son algunos elementos básicos: |
||
+ | * <code>#</code>: carácter para comentarios, todo lo que va a la derecha no va a ser tenido en cuenta por la computadora. |
||
+ | * <code>;</code>: carácter para concatenar líneas de código |
||
+ | * <code>echo</code>: permite mostrar en la terminal cualquier cosa que pongamos a la derecha del comando. |
||
+ | * <code>></code>: captura la salida de un comando para dirigirla a algún destino (ej. archivo) creándolo si no existe |
||
+ | * <code>>></code>: captura la salida de un comando para dirigirla al final de algún destino (ej. archivo) |
||
+ | * <code>|</code>: concatenación de comandos |
||
+ | * <code>`</code>: permite capturar la ejecución de un comando |
||
+ | * <code>$</code>: indicación de variable |
||
+ | |||
+ | === variables === |
||
+ | Se utilizan cómo <code>$[NombreVariable]</code> o <code>${[NombreVariable]}</code>. Se asignan con <code>'='</Code> (sin espacios!!!) |
||
+ | <PRE style="shell"> |
||
#!/bin/bash |
#!/bin/bash |
||
− | number=3 |
+ | number=3 #nueva variable |
− | echo "Numero: "${number} |
+ | echo "Numero: "${number} #quiero mostrar en la terminar el valor de "number" |
</PRE> |
</PRE> |
||
− | ** Ejecutando |
+ | |
− | <PRE> |
+ | Ejecutando |
+ | <PRE style="shell"> |
||
$ chmod u+x test.bash |
$ chmod u+x test.bash |
||
$ ./test.bash |
$ ./test.bash |
||
Numero: 3 |
Numero: 3 |
||
</PRE> |
</PRE> |
||
− | ** Asignación de un valor después de ejecutar un comando (con <code>``</code>) |
+ | |
− | <PRE> |
+ | === Asignación de valores === |
− | fecha=`date "+%Y/%m/%d"` |
+ | Asignación de un valor después de ejecutar un comando (con <code>``</code>) |
− | echo "HOY: "${fecha} |
+ | <PRE style="shell"> |
+ | fecha=`date "+%Y/%m/%d"` #date permite manipular fechas y horas. |
||
+ | echo "HOY: "${fecha} |
||
</PRE> |
</PRE> |
||
− | ** Ejecutando |
+ | |
− | <PRE> |
+ | Ejecutando |
+ | <PRE style="shell"> |
||
HOY: 2018/06/06 |
HOY: 2018/06/06 |
||
</PRE> |
</PRE> |
||
− | * IF: Condición |
+ | |
+ | === if: Condiciones === |
||
+ | Al igual que otros lenguajes, bash permite usar control de flujo. Por ejemplo <code>if</code> permite incluir una condición: |
||
+ | <PRE style="shell"> |
||
+ | valor='Hola' |
||
+ | |||
+ | if test ${valor} == 'Hola'; then |
||
+ | echo "Hello !" |
||
+ | else |
||
+ | echo "Goodbye" |
||
+ | fi |
||
+ | </PRE> |
||
+ | |||
+ | Ejecutando |
||
+ | <PRE style="shell"> |
||
+ | Hello |
||
+ | </PRE> |
||
+ | |||
+ | Por ejemplo, se puede usar para ver si existe un archivos |
||
+ | <PRE style="shell"> |
||
+ | if test ! -f ArchivoTest.txt; then |
||
+ | echo "El archivo 'ArchivoTest.txt' no existe, creandolo !!" |
||
+ | echo "Hola, test" > ArchivoTest.txt |
||
+ | else |
||
+ | echo "El archivo 'ArchivoTest.txt' existe" |
||
+ | fi |
||
+ | </PRE> |
||
+ | siendo cada flag <code>!</code>: contrario, <code>-f</code>: es archivo |
||
+ | |||
+ | ejecutando |
||
+ | <PRE style="shell"> |
||
+ | El archivo 'ArchivoTest.txt' no existe, creandolo !! |
||
+ | </PRE> |
||
+ | |||
+ | === while do: bucles === |
||
+ | permite repetir un determinado número de veces una instrucción mientras se cumpla una determinada condición: |
||
+ | <PRE style="shell"> |
||
+ | hoy=`date +%Y%m%d` |
||
+ | |||
+ | echo "hoy: "${hoy} |
||
+ | |||
+ | i=0 |
||
+ | while test $i -le 10; do |
||
+ | nuevodia=`date +%Y%m%d -d"${hoy} $i days"` |
||
+ | echo "i: "$i" fecha:"${nuevodia} |
||
+ | i=`expr $i + 1` |
||
+ | done |
||
+ | </PRE> |
||
+ | Ejecutando |
||
+ | |||
+ | <PRE style="shell"> |
||
+ | hoy: 20180611 |
||
+ | i: 0 fecha:20180611 |
||
+ | i: 1 fecha:20180612 |
||
+ | i: 2 fecha:20180613 |
||
+ | i: 3 fecha:20180614 |
||
+ | i: 4 fecha:20180615 |
||
+ | i: 5 fecha:20180616 |
||
+ | i: 6 fecha:20180617 |
||
+ | i: 7 fecha:20180618 |
||
+ | i: 8 fecha:20180619 |
||
+ | i: 9 fecha:20180620 |
||
+ | i: 10 fecha:20180621 |
||
+ | </PRE> |
||
+ | |||
+ | === ejecución de un comando === |
||
+ | Con la variable <code>$?</code> podemos saber el estado de ejecución de un comando, si no es 0, es que el comando anterior se ejecutó mal. |
||
+ | <PRE style="shell"> |
||
+ | $ ls |
||
+ | ArchivoTest.txt nuevoArchivo.txt |
||
+ | $ echo $? |
||
+ | 0 |
||
+ | |||
+ | $ ls nuevoarchivo.txt |
||
+ | ls: cannot access 'nuevoarchivo.txt': No such file or directory |
||
+ | $ echo $? |
||
+ | 2 |
||
+ | </PRE> |
||
+ | |||
+ | == date: manejo del tiempo == |
||
+ | El comando <CODE>date</CODE> nos permite manejar el tiempo y sus componentes |
||
+ | |||
+ | Impresión de hoy como año(4 dígitos)/mes(2 dígitos)/día(2 dígitos) |
||
+ | <PRE style="shell"> |
||
+ | $ date "+%Y"/"%m"/"%d" |
||
+ | 2024/06/03 |
||
+ | </PRE> |
||
+ | |||
+ | Restar 124 horas al 1 de enero del 1982 |
||
+ | <PRE style="shell"> |
||
+ | $ date -d"19820101 124 hours ago" |
||
+ | Sat 26 Dec 1981 08:00:00 PM -03 |
||
+ | </PRE> |
||
+ | |||
+ | == expr: cálculos == |
||
+ | El comando <CODE>exp</CODE> permite hacer operaciones matemáticas (muy limitado sólo enteros, más potente AWK, más adelante) |
||
+ | <PRE STYLE="shell"> |
||
+ | $ expr 2 + 5 |
||
+ | 7 |
||
+ | $ expr 2 - 5 |
||
+ | -3 |
||
+ | $ expr 2 '*' 5 |
||
+ | 10 |
||
+ | $ expr 2 / 5 |
||
+ | 0 |
||
+ | $ expr 5 % 2 |
||
+ | 1 |
||
+ | </PRE> |
||
+ | |||
+ | == cat: consulta de archivos == |
||
+ | El comando <CODE>cat</CODE> es muy útil y versátil a la hora de manejar archivos de texto. |
||
+ | |||
+ | === Creación de un archivo === |
||
+ | Se puede crear un archivo con contendio desde una script de la siguiente manera: |
||
+ | <PRE> |
||
+ | num=3 |
||
+ | cat << EOF > nuevoArchivo.txt |
||
+ | Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' |
||
+ | El valor de num es ${num} |
||
+ | EOF |
||
+ | </PRE> |
||
+ | |||
+ | === Volcado del contenido de un archivo === |
||
+ | No vuelca del contenido del archivo en la terminal |
||
+ | <PRE style="Shell"> |
||
+ | $ cat nuevoArchivo.txt |
||
+ | Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' |
||
+ | El valor de num es 3 |
||
+ | </PRE> |
||
+ | |||
+ | == grep: búsqueda de patrones == |
||
+ | El comando <CODE>grep</CODE> nos permite buscar patrones dentro de archivos y devuelve la línea que coincide |
||
+ | <PRE style="Shell"> |
||
+ | $ grep valor nuevoArchivo.txt |
||
+ | El valor de num es 3 |
||
+ | </PRE> |
||
+ | |||
+ | con el ''flag'' <code>-i</CODE> no distingue entre minúsculas/mayúsculas |
||
+ | <PRE style="Shell"> |
||
+ | $ grep A nuevoArchivo.txt |
||
+ | Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' |
||
+ | |||
+ | $ grep -i A nuevoArchivo.txt |
||
+ | Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' |
||
+ | El valor de num es 3 |
||
+ | </PRE> |
||
+ | |||
+ | == concatenación de comandos == |
||
+ | El carácter <CODE>|</CODE> se usa para concatenar comandos |
||
+ | <PRE style="shell"> |
||
+ | cat nuevoArchivo.txt | grep -i A |
||
+ | Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' |
||
+ | El valor de num es 3 |
||
+ | </PRE> |
||
+ | |||
+ | == tr: remplazo de caracteres == |
||
+ | El comando <CODER>TR</CODE> nos permite reemplazar caracteres |
||
+ | <PRE style="shell"> |
||
+ | echo "1:2:3:4:5:" | tr ':' '@' |
||
+ | 1@2@3@4@5@ |
||
+ | </PRE> |
||
+ | |||
+ | == AWK: lenguaje de programación == |
||
+ | El lenguaje [https://es.wikipedia.org/wiki/AWK AWK] sirve para procesar datos en archivos de texto |
||
+ | |||
+ | Por ejemplo, sumarle un tercio al valor de num (que es la sexta palabra en la línea donde aparece 'num') |
||
+ | <PRE style="shell"> |
||
+ | $ cat nuevoArchivo.txt | grep num | awk '{print $6 + 1 / 3}' |
||
+ | 3.33333 |
||
+ | </PRE> |
||
+ | |||
+ | == bucles complejos == |
||
+ | Se pueden crear bucles que tomen valores de una lista |
||
+ | <PRE style="shell"> |
||
+ | valores="0@primero:1@segundo:1@tercero:2@cuarto:3@quinto:5@sexto:8@septimo:13@octavo:21@noveno" |
||
+ | vals=`echo ${valores} | tr ':' ' '` |
||
+ | i=1 |
||
+ | for vv in ${vals}; do |
||
+ | numfib=`echo ${vv} | tr '@' ' ' | awk '{print $1}'` |
||
+ | numeral=`echo ${vv} | tr '@' ' ' | awk '{print $2}'` |
||
+ | echo "El ${numeral} valor '${i}', de la serie de Fibonacci es: "${numfib} |
||
+ | i=`expr ${i} + 1` |
||
+ | done |
||
+ | El primero valor '1', de la serie de Fibonacci es: 0 |
||
+ | El segundo valor '2', de la serie de Fibonacci es: 1 |
||
+ | El tercero valor '3', de la serie de Fibonacci es: 1 |
||
+ | El cuarto valor '4', de la serie de Fibonacci es: 2 |
||
+ | El quinto valor '5', de la serie de Fibonacci es: 3 |
||
+ | El sexto valor '6', de la serie de Fibonacci es: 5 |
||
+ | El septimo valor '7', de la serie de Fibonacci es: 8 |
||
+ | El octavo valor '8', de la serie de Fibonacci es: 13 |
||
+ | El noveno valor '9', de la serie de Fibonacci es: 21 |
||
+ | </PRE> |
||
= Entorno servidores/clústers = |
= Entorno servidores/clústers = |
||
+ | |||
+ | Los servidores y clúster de computación, son otras máquinas, con sus usuarios y entorno linux. Normalmente se encuentran conectadas a internet y se accede a estas máquinas de manera remota desde otra computadora o llamada "local" |
||
+ | |||
+ | Para acceder de manera remota es necesario tener un usuario y conocer el nombre de la máquina y su dominio. |
||
+ | |||
+ | == Acceso == |
||
+ | El acceso a los clúster de computación (HPC del Inglés) o servidores se realiza en la mayoría de los casos via <code>ssh</code> |
||
+ | |||
+ | <PRE> |
||
+ | $ ssh [NombreUsuarioenServidor]@[nombreServidor].[domino] |
||
+ | </PRE> |
||
+ | |||
+ | Por ejemplo, el CIMA dispone de un clúster de computación llamado <I>hydra</I> y con el domino <code>cima.fcen.uba.ar</code>. Si Juan Perez quiere acceder a Hydra usa el siguiente comando (al apretar enter, el sistema te pide la clave pero no aparece ningún cursor): |
||
+ | <PRE> |
||
+ | $ ssh juan.perez@hhydra.cima.fcen.uba.ar |
||
+ | juan.perez@hydra.cima.fcen.uba.ar's password: |
||
+ | [juan.perez@hydra ~]$ |
||
+ | </PRE> |
||
+ | * Una vex en el servidor/clúster le usuarie tiene un entorno linux estándard. Al trabajar en un espacio compartido es necesario tener cuidado ya que los cambios podrían afectar a otras personas. |
||
+ | * Para salir, se usa la instrucción <code>exit</code> |
||
+ | <PRE> |
||
+ | [juan.perez@hydra ~]$ exit |
||
+ | $ |
||
+ | </PRE> |
||
+ | |||
+ | == Copiado de ficheros == |
||
+ | Para copiar archivos guardados en servidores se puede utilizar herramientas gráficas, pero la experiencia recomienda hacerlo desdel terminal. Para tal caso, existen las instrucciones <code>scp</code> y <code>rsync</code> (más potente y muy útil para sincronizar copias): |
||
+ | <PRE> |
||
+ | $ rsync [NombreUsuarixOrig]@[origen]:[fichero/directorio] [NombreUsuarixDest]@[destino]:[directorio] |
||
+ | </PRE> |
||
+ | * <code>[NombreUsuarixOrig]</code>: Nombre del usuarix en la máquina donde se encuentra el fichero o directorio a copiar |
||
+ | * <code>[origen]</code>: nombre de la máquina y su doiminio (<code>[NombreMaquina].[dominio]</code>) donde se encuentra el fichero o directorio |
||
+ | * <code>[fichero/directorio]</code>: fichero o directorio a copiar |
||
+ | * <code>[NombreUsuarixDest]</code>: Nombre del usuarix en la máquina donde se quiere copiar el fichero o directorio |
||
+ | * <code>[destino]</code>: nombre de la máquina y dominio (<code>[NombreMaquina].[dominio]</code>) a la cuál se quiere hacer la copia |
||
+ | * <code>[directorio]</code>: nombre de directorio en la máquina destino donde se quiere hacer la copia |
||
+ | |||
+ | Cuando se quiere copiar, siempre nos pedirá la clave de acceso de la máquina remota. |
||
+ | El destino o el origen no pueden ser los dos remotos. Uno tiene que ser una máquina local. Cuando es la máqiuna local, no se indica <code>[NombreUsuarx]@[maquina]</code> |
||
+ | Si no se indica destino de la copia, se copia directamente en el <code>${HOME}</code> |
||
+ | |||
+ | * Copia de un fichero local al $HOME de hydra |
||
+ | <PRE> |
||
+ | $ rsync documento.txt juan.perez@hydra.cima.fcen.uba.ar: |
||
+ | </PRE> |
||
+ | * Copia de un fichero de hydra del directorio <code>${HOME}/experimentos/WRFsensSFC/run/</code> a la máquina en local al directorio <code>${HOME}/estudios/WRFsensSFC/simulacion/control</code> |
||
+ | <PRE> |
||
+ | $ rsync juan.perez@hydra.cima.fcen.uba.ar:experimentos/WRFsensSFC/run/wrfout_d01_2002-12-01_00:00:00 estudios/WRFsensSFC/si |
||
+ | mulacion/control |
||
+ | </PRE> |
||
+ | |||
+ | = Ejemplos = |
||
+ | Pueden encontrar más ejemplos en [https://forge.ipsl.jussieu.fr/igcmg_doc/wiki/DocKexterntools#BootCampIPSLpresentations-documentations- |
||
+ | handsonsessions IPSL boot camp] [[File:20160324_bash.pdf]] y sus ejemplos [[File:test_bash.doc]] (antes de utilizar, renombrar cómo <code>test.bash</code> y darle atributos de ejecución) |
||
+ | |||
+ | También hay disponible un repositorio con una colección de scripts reales de Lluís Fita (CIMA): |
||
+ | <PRE style="shell"> |
||
+ | $ git clone https://git.cima.fcen.uba.ar/lluis.fita/ShellScripts |
||
+ | </PRE> |
Última revisión de 10:51 2 jun 2024
La terminal es una interfaz de línea de comando que permite interactuar con la computadora. Al igual que cualquier GUI (por Graphical User Interface) con la que hayamos trabajado en Windows o Linux, la terminal nos permite acceder a directorios (carpetas) y archivos, generar nuevos archivos y moverlos a otras ubicaciones entre otro millón de cosas.
Entonces, ¿porqué "complicarnos" con la terminal si puedo hacer lo mismo con un par de clicks del mouse? Cuando queremos interactuar con la computadora de manera compleja, hacer tareas repetitivas o por ejemplo conectarnos de manera remota con otras computadoras, necesitamos saber usar la terminal.
Contenido
|
[editar] ¿Cómo funciona?
Al abrir la terminal nos encontramos con una pantalla negra y en la primera linea algo como lo siguiente:
Esto va a ser usuario@nombredelacomputadora:~$
. Acá el ~
indica el directorio raíz y el $
o prompt indica que la shell está esperando instrucciones.
La shell es un programa que interpreta nuestras ordenes y las traduce en lenguaje computadora. A travez de la shell podemos hacer cosas tan simples como copiar un archivo con un simple comando hasta correr un modelo de simulación numérica.
[editar] Herramientras básicas
Las herramientas básicas vienen pre-instaladas con el sistema operativo en en el paquete coreutils (o GNU Core Utilities). Por ejemplo:
$ ls Desktop Downloads Pictures Test Documents Music terminal.png
Este comando lista el contenido dentro del directorio actual. Y su nombre viene de "list". Se puede extender las capacidades de los comandos con flags usando la siguiente sintaxis:
$ [comando] -flags
Por ejemplo, si quisiéramos más información sobre los archivos y directorios que están en el directorio actual usamos:
$ ls -l drwxr-xr-x 2 pao pao 4,0K may 19 15:24 Desktop drwxr-xr-x 17 pao pao 4,0K mar 16 13:52 Documents drwxr-xr-x 10 pao pao 16K jun 9 16:38 Downloads drwxr-xr-x 2 pao pao 4,0K ene 19 2018 Music drwxr-xr-x 19 pao pao 4,0K jun 8 18:35 Pictures -rw-r--r-- 1 pao pao 11132 jun 9 16:38 terminal.png drwxr-xr-x 2 pao pao 4096 jun 9 17:54 Test
Existen una infinidad de comandos, cada uno con sus flags y a diferencia de una interfaz gráfica donde tenemos botones, al trabajar en la terminal es necesario conocerlos. Esto se aprende con práctica pero también googleando aquello que queremos resolver.
[editar]
Lo primero es saber donde estamos parados dentro de la computadora, para eso existe el comando pwd
(que viene de "print working directory"):
$ pwd /home/pao
En este caso estamos parados en el home. La respuesta de este comando puede ser distinta dependiendo del sistema operativo, pero dentro del mundo de linux no debería variar mucho.
El home es la carpeta principal del usuario, donde se guardará todo. Pero por encima hay toda una estructura de archivos que organizan los programas instalados, las herramientas de sistema y los "homes" de otros usuarios dentro de la misma computadora.
Otra manera de ver donde estamos, es revisando el contenido del directorio con ls
y reconoceer así el directorio.
Si queremos "movernos" dentro de la computadora hacia otro directorio, el comando indicado es cd
(que vienen de "change directory", para esta altura seguro ya descubrieron el patrón).
Por ejemplo queremos movernos al directorio "Test" (ojo, shell es case sensitive, las mayusculas y minusculas no son intercambiables!):
$ cd Test
Este comando no devuelve nada pero si usamos pwd
, veremos que ahora estamos en un nuevo directorio.
Para volver al directorio anterior usamos ..
, es un "directorio especial" que representa el directorio previo o parent directory. También existe un .
que representa el directorio actual. Pueden verlos usando $ ls -a
para mostrar todos ("all") los elementos en el directorio actual
$ cd ..
[editar] Path absolutos y relativos
En el ejemplo anterior usamos cd
para movernos y el nombre del directorio al cual queremos ir. Cómo el directorio Test estaba adentro del directorio de trabajo accedimos sin problemas pero si hubiéramos estado en otro lado nos hubiera dicho que no existe un directorio Test. Esto es así porque le estamos dando el path
relativo (relativo al directorio donde estamos parados). Pero cd
también puede interpretar la ubicación exacta o absoluta de un directorio. Por ejemplo:
$ cd /home/pao/Test
[editar] Algunos trucos
Muchas veces escribimos mal el nombre de un directorio o archivo, a veces son super largos o el path absoluto es enorme. Existen varios atajos para hacernos la vida más simple:
-
Tab
: La tecla Tab completa el nombre del archivo o directorio. Basta con escribir las primeras letras del nombre y luego con la tecla tab se termina de escribir automáticamente el nombre.
-
Ctrl + a
: Principio de línea. Se manda el cursos al principio de la línea de comando. También funciona la tecla Inicio. -
Ctrl + e
: Final de línea. Se manda el cursos al final de la línea de comando. O también la tecla Fin.
[editar] Manipulando archivos y directoios
-
mkdir
: Para crear directorios usamos el comandomkdir
(por supuesto de "make directory"):
$ mkdir Test2 $ ls Desktop Downloads Pictures Test Documents Music terminal.png Test2 $
La ubicación del nuevo directorio dependerá de la ubicación relativa o absoluta que le dimos. En este caso, se creará en el directorio donde estamos trabajando.
-
cp
: si quisiéramos copiar un archivo en otra ubicación usamoscp
(de "copy"). Este comando necesita saber que copiar y donde copiarlo:cp [origen] [destino]
, por ejemplo:
$ cp [origen] [destino] $ cp terminal.png Test $ ls Test $ terminal.png
cp
tiene una flag -r
que permite copiar recursivamente un directorio y su contenido.
-
mv
: el comandomv
("move") permite mover un archivo (parecido alctrl+C
yctrl+V
en una interfáz gráfica). Pero también permite cambiarle el nombre a un archivo si los "movemos" en el mismo lugar:
$ mv [origen] [destino] $ mv Test/terminal.png Test/terminal2.png $ ls Test terminal2.png
-
rm
: si queremos borrar un archivo usamosrm
(de "remove"). Para borrar directorios podemos agregar una flag. Pero cuidado esta acción es irreversible. La terminal no tiene papelera y no existe elCtrl+z
, cuidado con con lo borran!
$ rm [fichero] $ rm Test/terminal2.png $ ls Test
NOTA: para borrar directorios y todo su contenido es necesario añadirle el flag '-r' (recursive). Si nos da apuro, existe rmdir
pero sólo borra directorios vacíos.
$ rm Test rm: cannot remove 'Test': Is a directory $ rm -r Test
-
ls
: 'list', lista el contenido de un directorio (un directorio es el equivalente de 'carpeta' de Windows)
$ ls 20160324_bash.pdf install.inf prueba.bash Terminal.png test.bash $ ls -l total 244 -rw-r--r-- 1 lluis lluis 221654 Jun 6 10:49 20160324_bash.pdf -rw-rw-r-- 1 lluis lluis 328 Apr 25 14:53 install.inf -rwxr--r-- 1 lluis lluis 114 Jun 6 11:27 prueba.bash -rw-r--r-- 1 lluis lluis 11172 Apr 11 16:27 Terminal.png -rw-r--r-- 1 lluis lluis 4056 Jun 6 10:49 test.bash
[editar] Atributos de un archivo
Al hacer un list con ls -l
, nos aparecen la lista de elementos en el directorio con sus atributos:
-
ls
: lista el contenido de un directorio
$ ls -l [AtributosDueñx][AtributosGrupo][AtributosTodxs] [ID] [Dueñx] [Grupo] [Tamaño] [Fecha] [NombreFichero] total 244 -rw-r--r-- 1 lluis lluis 221654 Jun 6 10:49 20160324_bash.pdf -rw-rw-r-- 1 lluis lluis 328 Apr 25 14:53 install.inf -rwxr--r-- 1 lluis lluis 114 Jun 6 11:27 prueba.bash drwxr-xr-x 2 lluis lluis 4096 Jun 6 12:25 parTUXza -rw-r--r-- 1 lluis lluis 11172 Apr 11 16:27 Terminal.png -rwxr--r-- 1 lluis lluis 4056 Jun 6 10:49 test.bash
Por ejemplo, el archivo pdf 20160324_bash.pdf tiene los siguientes atributos:
-
-rw-r--r-- 1 lluis lluis 221654 Jun 6 10:49 20160324_bash.pdf
, fichero pdf
- -rw-: El dueño del archivo sólo puede leerlo y modificarlo.
- r--: El grupo sólo puede leerlo
- r--: Todo el mundo sólo puede leerlo
- lluis: Dueño del archivo
- lluis: Grupo del archivo
- 221654: Tamaño en bytes del archivo
- Jun 6 10:49: fecha de la última modificación del archivo
Otros archivos tiene permisos de ejecución, por ejemplo:
-
-rwxr--r-- 1 lluis lluis 4056 Jun 6 10:49 test.bash
: script de shell,-rwx
indica que sólo el dueño puede ejecutarlo. -
drwxr-xr-x 2 lluis lluis 4096 Jun 6 12:25 parTUXza
: directorio (drwx
), para linux, los directorios son ejectuables para todos!
[editar] Comodines
Los comodines son símbolos o expresiones que actual básicamente como cómodines y te permiten ahorrar tiempo. Por ejemplo *
funcionan como cualquier cantidad de caracteres:
$ cp *.png Test/
En este caso todos los archivos que terminen con ".png" serán copiados a la carpeta Test, sin importar que nombre tengan antes del .png.
Hay muchos otros, por ejemplo ?
es como el *
pero solo para un carácter. No es necesario aprenderlos a todos, es cuestión de práctica y a medida que los necesitamos.
[editar] Más recursos
Parte de este material está inspirado en la clase The Unix Shell de The Carpentries donde hay muchos ejemplos, ejercicios y clases más avanzadas. Es recomendable darle una mirada.
[editar] Ayuda
Es posible acceder a la ayuda de un comando con una flag específica -h --h --help
(esto depende del comando). O en algunos casos, también está disponible la documentación completa a la que se accede con `man`.
$ [comando] --h $ $ man [comando] $
[editar] Variables de sistema
El sistema operativo se configura a través de unas variables de sistema generales
-
$HOME:
Ubicación inicial al abrir una terminal cómo usuarie (/home/[usuarix]
) -
$PATH:
Directorios que ya están cargados automáticamente al abrir un terminal. Suelen ser directorios con aplicaciones, así no hace falta saber dónde se encuentran las aplicaciones. Por ejemplo:
/home/lluis/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
-
$LD_LIBRARY_PATH:
Librerias cargadas en el sistema
[editar] Shell scripting
La shell es un programa que interpreta nuestras ordenes y las traduce en lenguaje computadora. Les usuaries acceden al kernel y a las componentes de la computadora a través de ella.
Esta shell permite la ejecución de scripts para automatizar esas tareas que sean repetitivas. Estos scripts se pueden programar en distintas shells. En esta introducción se dan detalles de bash:
bourn-again Shell (hay distitnas shells: csh, sh, ksh, ...). En estas shells se pueden utilizar todos los coreutils. Los scripts constituyen un lenguajde de programación interpreatado que es masivamente utilizando dentro del entorno linux
Los scripts de shell son programas ejecutables interpretados por el kernel. Deben tener permiso de ejecución para poder correr. Para cambiar los permisos u modos de un archivo o directorio se utiliza el comando chmod
("change mode" o cambiar modo):
$ chmod u+x [ScriptShell]
O bien directamente al llamar bash
(si el script es de bash)
$ bash [ScriptShell]
Este es el ejemplo más sencillo de script, con nombre hola.bash
(se elige la extensión .bash
, pero no es obligatorio)
#!/bin/bash echo "Hola mundo!!"
La primera línea indica que tipo de shell vamos a usar, al incluir esto no va a ser necesario usar el comando bash
.
- Al ejecutarse:
$ ./hola.bash Hola mundo!!
- Shell va a interpretar que queremos ejecutar el archivo porque usamos
./
seguido del nombre del archivo.
[editar] Conceptos básicos
Un script es básicamente un archivo de texto con sentencias u órdenes a ser interpretadas por una computadora. Pueden contener cualquier instrucción que ejecutaríamos manualmente nosotros (ej. python, modelos, ....).
Estos son algunos elementos básicos:
-
#
: carácter para comentarios, todo lo que va a la derecha no va a ser tenido en cuenta por la computadora. -
;
: carácter para concatenar líneas de código -
echo
: permite mostrar en la terminal cualquier cosa que pongamos a la derecha del comando. -
>
: captura la salida de un comando para dirigirla a algún destino (ej. archivo) creándolo si no existe -
>>
: captura la salida de un comando para dirigirla al final de algún destino (ej. archivo) -
|
: concatenación de comandos -
`
: permite capturar la ejecución de un comando -
$
: indicación de variable
[editar] variables
Se utilizan cómo $[NombreVariable]
o ${[NombreVariable]}
. Se asignan con '='
(sin espacios!!!)
#!/bin/bash number=3 #nueva variable echo "Numero: "${number} #quiero mostrar en la terminar el valor de "number"
Ejecutando
$ chmod u+x test.bash $ ./test.bash Numero: 3
[editar] Asignación de valores
Asignación de un valor después de ejecutar un comando (con ``
)
fecha=`date "+%Y/%m/%d"` #date permite manipular fechas y horas. echo "HOY: "${fecha}
Ejecutando
HOY: 2018/06/06
[editar] if: Condiciones
Al igual que otros lenguajes, bash permite usar control de flujo. Por ejemplo if
permite incluir una condición:
valor='Hola' if test ${valor} == 'Hola'; then echo "Hello !" else echo "Goodbye" fi
Ejecutando
Hello
Por ejemplo, se puede usar para ver si existe un archivos
if test ! -f ArchivoTest.txt; then echo "El archivo 'ArchivoTest.txt' no existe, creandolo !!" echo "Hola, test" > ArchivoTest.txt else echo "El archivo 'ArchivoTest.txt' existe" fi
siendo cada flag !
: contrario, -f
: es archivo
ejecutando
El archivo 'ArchivoTest.txt' no existe, creandolo !!
[editar] while do: bucles
permite repetir un determinado número de veces una instrucción mientras se cumpla una determinada condición:
hoy=`date +%Y%m%d` echo "hoy: "${hoy} i=0 while test $i -le 10; do nuevodia=`date +%Y%m%d -d"${hoy} $i days"` echo "i: "$i" fecha:"${nuevodia} i=`expr $i + 1` done
Ejecutando
hoy: 20180611 i: 0 fecha:20180611 i: 1 fecha:20180612 i: 2 fecha:20180613 i: 3 fecha:20180614 i: 4 fecha:20180615 i: 5 fecha:20180616 i: 6 fecha:20180617 i: 7 fecha:20180618 i: 8 fecha:20180619 i: 9 fecha:20180620 i: 10 fecha:20180621
[editar] ejecución de un comando
Con la variable $?
podemos saber el estado de ejecución de un comando, si no es 0, es que el comando anterior se ejecutó mal.
$ ls ArchivoTest.txt nuevoArchivo.txt $ echo $? 0 $ ls nuevoarchivo.txt ls: cannot access 'nuevoarchivo.txt': No such file or directory $ echo $? 2
[editar] date: manejo del tiempo
El comando date
nos permite manejar el tiempo y sus componentes
Impresión de hoy como año(4 dígitos)/mes(2 dígitos)/día(2 dígitos)
$ date "+%Y"/"%m"/"%d" 2024/06/03
Restar 124 horas al 1 de enero del 1982
$ date -d"19820101 124 hours ago" Sat 26 Dec 1981 08:00:00 PM -03
[editar] expr: cálculos
El comando exp
permite hacer operaciones matemáticas (muy limitado sólo enteros, más potente AWK, más adelante)
$ expr 2 + 5 7 $ expr 2 - 5 -3 $ expr 2 '*' 5 10 $ expr 2 / 5 0 $ expr 5 % 2 1
[editar] cat: consulta de archivos
El comando cat
es muy útil y versátil a la hora de manejar archivos de texto.
[editar] Creación de un archivo
Se puede crear un archivo con contendio desde una script de la siguiente manera:
num=3 cat << EOF > nuevoArchivo.txt Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' El valor de num es ${num} EOF
[editar] Volcado del contenido de un archivo
No vuelca del contenido del archivo en la terminal
$ cat nuevoArchivo.txt Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' El valor de num es 3
[editar] grep: búsqueda de patrones
El comando grep
nos permite buscar patrones dentro de archivos y devuelve la línea que coincide
$ grep valor nuevoArchivo.txt El valor de num es 3
con el flag -i
no distingue entre minúsculas/mayúsculas
$ grep A nuevoArchivo.txt Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' $ grep -i A nuevoArchivo.txt Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' El valor de num es 3
[editar] concatenación de comandos
El carácter |
se usa para concatenar comandos
cat nuevoArchivo.txt | grep -i A Todo lo que ese dentro antes de E O F sera escrito dentro de 'nuevoArchivo.txt' El valor de num es 3
[editar] tr: remplazo de caracteres
El comando <CODER>TR</CODE> nos permite reemplazar caracteres
echo "1:2:3:4:5:" | tr ':' '@' 1@2@3@4@5@
[editar] AWK: lenguaje de programación
El lenguaje AWK sirve para procesar datos en archivos de texto
Por ejemplo, sumarle un tercio al valor de num (que es la sexta palabra en la línea donde aparece 'num')
$ cat nuevoArchivo.txt | grep num | awk '{print $6 + 1 / 3}' 3.33333
[editar] bucles complejos
Se pueden crear bucles que tomen valores de una lista
valores="0@primero:1@segundo:1@tercero:2@cuarto:3@quinto:5@sexto:8@septimo:13@octavo:21@noveno" vals=`echo ${valores} | tr ':' ' '` i=1 for vv in ${vals}; do numfib=`echo ${vv} | tr '@' ' ' | awk '{print $1}'` numeral=`echo ${vv} | tr '@' ' ' | awk '{print $2}'` echo "El ${numeral} valor '${i}', de la serie de Fibonacci es: "${numfib} i=`expr ${i} + 1` done El primero valor '1', de la serie de Fibonacci es: 0 El segundo valor '2', de la serie de Fibonacci es: 1 El tercero valor '3', de la serie de Fibonacci es: 1 El cuarto valor '4', de la serie de Fibonacci es: 2 El quinto valor '5', de la serie de Fibonacci es: 3 El sexto valor '6', de la serie de Fibonacci es: 5 El septimo valor '7', de la serie de Fibonacci es: 8 El octavo valor '8', de la serie de Fibonacci es: 13 El noveno valor '9', de la serie de Fibonacci es: 21
[editar] Entorno servidores/clústers
Los servidores y clúster de computación, son otras máquinas, con sus usuarios y entorno linux. Normalmente se encuentran conectadas a internet y se accede a estas máquinas de manera remota desde otra computadora o llamada "local"
Para acceder de manera remota es necesario tener un usuario y conocer el nombre de la máquina y su dominio.
[editar] Acceso
El acceso a los clúster de computación (HPC del Inglés) o servidores se realiza en la mayoría de los casos via ssh
$ ssh [NombreUsuarioenServidor]@[nombreServidor].[domino]
Por ejemplo, el CIMA dispone de un clúster de computación llamado hydra y con el domino cima.fcen.uba.ar
. Si Juan Perez quiere acceder a Hydra usa el siguiente comando (al apretar enter, el sistema te pide la clave pero no aparece ningún cursor):
$ ssh juan.perez@hhydra.cima.fcen.uba.ar juan.perez@hydra.cima.fcen.uba.ar's password: [juan.perez@hydra ~]$
- Una vex en el servidor/clúster le usuarie tiene un entorno linux estándard. Al trabajar en un espacio compartido es necesario tener cuidado ya que los cambios podrían afectar a otras personas.
- Para salir, se usa la instrucción
exit
[juan.perez@hydra ~]$ exit $
[editar] Copiado de ficheros
Para copiar archivos guardados en servidores se puede utilizar herramientas gráficas, pero la experiencia recomienda hacerlo desdel terminal. Para tal caso, existen las instrucciones scp
y rsync
(más potente y muy útil para sincronizar copias):
$ rsync [NombreUsuarixOrig]@[origen]:[fichero/directorio] [NombreUsuarixDest]@[destino]:[directorio]
-
[NombreUsuarixOrig]
: Nombre del usuarix en la máquina donde se encuentra el fichero o directorio a copiar -
[origen]
: nombre de la máquina y su doiminio ([NombreMaquina].[dominio]
) donde se encuentra el fichero o directorio -
[fichero/directorio]
: fichero o directorio a copiar -
[NombreUsuarixDest]
: Nombre del usuarix en la máquina donde se quiere copiar el fichero o directorio -
[destino]
: nombre de la máquina y dominio ([NombreMaquina].[dominio]
) a la cuál se quiere hacer la copia -
[directorio]
: nombre de directorio en la máquina destino donde se quiere hacer la copia
Cuando se quiere copiar, siempre nos pedirá la clave de acceso de la máquina remota.
El destino o el origen no pueden ser los dos remotos. Uno tiene que ser una máquina local. Cuando es la máqiuna local, no se indica [NombreUsuarx]@[maquina]
Si no se indica destino de la copia, se copia directamente en el ${HOME}
- Copia de un fichero local al $HOME de hydra
$ rsync documento.txt juan.perez@hydra.cima.fcen.uba.ar:
- Copia de un fichero de hydra del directorio
${HOME}/experimentos/WRFsensSFC/run/
a la máquina en local al directorio${HOME}/estudios/WRFsensSFC/simulacion/control
$ rsync juan.perez@hydra.cima.fcen.uba.ar:experimentos/WRFsensSFC/run/wrfout_d01_2002-12-01_00:00:00 estudios/WRFsensSFC/si mulacion/control
[editar] Ejemplos
Pueden encontrar más ejemplos en [https://forge.ipsl.jussieu.fr/igcmg_doc/wiki/DocKexterntools#BootCampIPSLpresentations-documentations-
handsonsessions IPSL boot camp] Archivo:20160324 bash.pdf y sus ejemplos Archivo:test bash.doc (antes de utilizar, renombrar cómo test.bash
y darle atributos de ejecución)
También hay disponible un repositorio con una colección de scripts reales de Lluís Fita (CIMA):
$ git clone https://git.cima.fcen.uba.ar/lluis.fita/ShellScripts