acemu:articulos:articulos_tecnicos:software:introduccion_a_gnu-linux:linux_inicio:terminal
Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
acemu:articulos:articulos_tecnicos:software:introduccion_a_gnu-linux:linux_inicio:terminal [2012/01/07 13:54] – [Ver también] luis | acemu:articulos:articulos_tecnicos:software:introduccion_a_gnu-linux:linux_inicio:terminal [2012/01/15 12:07] (actual) – [Estructuras de control de flujo] luis | ||
---|---|---|---|
Línea 1: | Línea 1: | ||
====== Terminal o Intérprete de Órdenes ====== | ====== Terminal o Intérprete de Órdenes ====== | ||
- | Como todos los sistemas operativos derivados de Unix, GNU/Linux dispone de un **''' | + | Como todos los sistemas operativos derivados de Unix, GNU/Linux dispone de un **''' |
+ | |||
+ | Existen varios intérpretes de comandos del shell, **sh** (Bourne Shell, predecesor del **BASH**), el **csh** o **tcsh** (C Shell), **ksh** (Korn Shell), | ||
\\ | \\ | ||
Línea 9: | Línea 11: | ||
Un terminal es una forma de acceder al sistema sin utilizar la interfaz gráfica, es decir, realizar todo tipo de tareas en formato texto. La forma de utilizar el sistema de este modo es mediante órdenes. | Un terminal es una forma de acceder al sistema sin utilizar la interfaz gráfica, es decir, realizar todo tipo de tareas en formato texto. La forma de utilizar el sistema de este modo es mediante órdenes. | ||
- | El terminal muestra en pantalla un indicador de línea de órdenes (en inglés se utiliza la palabra **'' | + | El terminal muestra en pantalla un indicador de línea de órdenes (en inglés se utiliza la palabra **'' |
Este indicador finaliza generalmente por un caracter **''' | Este indicador finaliza generalmente por un caracter **''' | ||
Línea 18: | Línea 20: | ||
/ | / | ||
</ | </ | ||
+ | |||
+ | Lo típico, cuando corren los comandos UNIX en general, es que no devuelvan nada en pantalla. Por lo tanto, la única manera de saber que un programa o comando terminó de ejecutar, es cuando vuelve a aparecer en pantalla el prompt ((**Kenneth Irving**.- De hecho, si se ejecuta un comando simplemente escribiendo el nombre y dándole ENTER, el prompt no aparece hasta que termina el programa que se está ejecutando.\\ Eso corresponde a una ejecución en " | ||
Para acceder a una terminal se puede hacer de dos formas, una es con una aplicación como el terminal de [[http:// | Para acceder a una terminal se puede hacer de dos formas, una es con una aplicación como el terminal de [[http:// | ||
+ | Mostramos a continuación una imágen de la GUI o emulador de terminal en interfaz gráfica, en este caso, el escritorio de GNOME. | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | \\ | ||
Otra forma es salirse del entorno gráfico y acceder a un entorno completamente en modo texto, algo así como entrar en sólo símbolo de sistema en [[http:// | Otra forma es salirse del entorno gráfico y acceder a un entorno completamente en modo texto, algo así como entrar en sólo símbolo de sistema en [[http:// | ||
+ | |||
+ | La interfase de línea de comandos o CLI, accedemos a ella a través de la **Barra de Herramientas-> | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | \\ | ||
+ | Linux tiene al menos 2 interfases para comunicarse con el usuario la **CLI** (Command line interfase - interfase de línea de comandos) y la **GUI** (interfase de modo " | ||
+ | |||
+ | La diferencia entre ambas, es que con la primera (**CLI**), se pueden hacer muchas cosas preestablecidas, | ||
\\ | \\ | ||
Línea 48: | Línea 66: | ||
Antes de que se ejecute una orden, es posible redirigir cualquiera de sus archivos de salida, es la ''' | Antes de que se ejecute una orden, es posible redirigir cualquiera de sus archivos de salida, es la ''' | ||
- | == Redirección de la entrada estándar == | + | == Redirección de la entrada estándar |
Cuando se quiere redirigir la entrada estándar de una orden a un archivo, es necesario utilizar el operador de redirección '''< | Cuando se quiere redirigir la entrada estándar de una orden a un archivo, es necesario utilizar el operador de redirección '''< | ||
- | == Redirección de la salida estándar == | + | == Redirección de la salida estándar |
La salida por defecto de cualquier orden dada en el bash es el monitor. Por ejemplo; si utilizas la orden cal, te mostrará un calendario en la pantalla. Sin embargo puedes hacer que te envíe esos datos a un documento de texto por ejemplo escribiendo lo siguiente: | La salida por defecto de cualquier orden dada en el bash es el monitor. Por ejemplo; si utilizas la orden cal, te mostrará un calendario en la pantalla. Sin embargo puedes hacer que te envíe esos datos a un documento de texto por ejemplo escribiendo lo siguiente: | ||
Línea 61: | Línea 79: | ||
vemos como se utiliza el operador ''' | vemos como se utiliza el operador ''' | ||
- | == Redirección del error estándar == | + | == Redirección del error estándar |
Cuando se quiere redirigir el error estándar de una orden a un archivo, es necesario utilizar el operador de redirección ''' | Cuando se quiere redirigir el error estándar de una orden a un archivo, es necesario utilizar el operador de redirección ''' | ||
Línea 77: | Línea 95: | ||
El error ahora no se muestra por pantalla, como si nada pasara; se guarda en el archivo '' | El error ahora no se muestra por pantalla, como si nada pasara; se guarda en el archivo '' | ||
+ | |||
+ | == Uniendo las salidas == | ||
+ | |||
+ | Utilizando Bash ((**Kenneth Irving** - aporte de))se puede usar **> | ||
+ | |||
+ | Pero si hacemos: | ||
+ | |||
+ | < | ||
+ | comando> | ||
+ | </ | ||
+ | |||
+ | las salidas de error van a parar al archivo **err.txt**. | ||
+ | |||
+ | Ahora bien, si hacemos: | ||
+ | |||
+ | < | ||
+ | comando> | ||
+ | </ | ||
+ | |||
+ | entonces todos los mensajes que salen por **stdout** como por **stderr**, van a parar a **out.txt**\\ | ||
+ | Con **2>& | ||
+ | |||
+ | Las salidas también se pueden bifurcar (comando **tee**), o se pueden encadenar utilizando **tuberías** o **pipes**, como se explica en el apartado [[#Archivos de órdenes o '' | ||
+ | |||
\\ | \\ | ||
Línea 111: | Línea 153: | ||
< | < | ||
NOTA : | NOTA : | ||
- | Como se puede observar para poder asignar la cadena a la variable | + | Como se puede observar para poder asignar la cadena a la variable '' |
hemos tenido que utilizar las dobles comillas. | hemos tenido que utilizar las dobles comillas. | ||
- | Si no lo hubiésemos hecho (escribiendo | + | Si no lo hubiésemos hecho (escribiendo '' |
habríamos obtenido un error ya que el intérprete de órdenes sólo habría asignado | habríamos obtenido un error ya que el intérprete de órdenes sólo habría asignado | ||
- | '' | + | '' |
</ | </ | ||
Línea 160: | Línea 202: | ||
* **''' | * **''' | ||
+ | |||
+ | Debemos((idem)) dejar claro que las variables de entorno son propias del entorno en el que estamos, por lo tanto quedan, son propias del entorno. | ||
+ | |||
+ | Ahora bien, hay un tema muy importante y sutil, que es el alcance de las variables de entorno.\\ | ||
+ | Hay dos tipos de variables de entorno : | ||
+ | * las que podríamos definir como **locales** | ||
+ | * y las que podríamos definir como **globales** | ||
+ | |||
+ | Las **locales** solo son accesibles a los comandos que se ejecutan en el shell local, o el shell que nos está atendiendo.\\ | ||
+ | Las **globales** se trasmiten de padres a hijos... | ||
+ | |||
+ | |||
+ | En realidad cuando nos referimos a procesos hijos en LINUX, nos referimos a los procesos que son resultado de otro proceso del cual se genera. | ||
+ | |||
+ | Por ejemplo, si corro un comando **ls**, el shell es el proceso padre y el ls es el proceso hijo, de hecho, lo que en realidad ocurrió internamente es un **fork**(bifurcación). Lo que hace LINUX cuando larga a correr un programa, es lo siguiente : | ||
+ | |||
+ | Primero duplica el proceso que está ejecutando, por ejemplo, si es un shell, lo duplica ejecutando la función **fork()** del sistema, y luego el proceso hijo realiza un **exec()** con lo cual se transforma en el comando **ls** que es lo que queríamos ejecutar. | ||
+ | |||
+ | Al ejecutar un **fork()**, el proceso original se duplica, pero cada uno sabe si es padre o es hijo; y es el hijo el que finalmente se transforma en el nuevo proceso que se quería ejecutar. | ||
+ | |||
+ | En el proceso de ejecución del **fork()**, se trasmiten sólo las variables **globales** que son las variables que propiamente uno dice que son las variables de entorno. | ||
+ | |||
+ | Para que una variable sea de entorno, uno debe exportarla. Uno puede primero crear la variable | ||
+ | |||
+ | < | ||
+ | pepe=123 | ||
+ | </ | ||
+ | |||
+ | y luego exportarla, | ||
+ | |||
+ | < | ||
+ | export pepe | ||
+ | </ | ||
+ | |||
+ | o se pueden hacer las dos cosas juntas, | ||
+ | |||
+ | < | ||
+ | export pepe=123 | ||
+ | </ | ||
+ | |||
+ | De esa manera, los procesos hijos del proceso donde se creó la variable pepe, también podrán disponer de esa variable. Y ese, es el mecanismo más sencillo de comunicación entre procesos.\\ | ||
+ | Uno puede invocar un nuevo programa, pasándole argumentos, o simplemente creamos un conjunto de variables de entorno con los datos que el nuevo proceso requiere y el nuevo proceso los toma allí. | ||
+ | |||
== Órdenes == | == Órdenes == | ||
Línea 297: | Línea 382: | ||
$ ls -l | grep " | $ ls -l | grep " | ||
</ | </ | ||
+ | |||
+ | //**== Caso de estudio ==**// | ||
+ | |||
+ | Un ejemplo práctico del uso de las tuberías o pipes es el siguiente ((Idem)): | ||
+ | |||
+ | Se puede encadenar la salida de un comando a la entrada de otro (tal como lo vimos anteriormente), | ||
+ | |||
+ | < | ||
+ | comando1|comando2|comando3 | ||
+ | </ | ||
+ | |||
+ | De esta manera, la salida de comando 1, ingresa por el stdin de comando 2 y la salida de comando 2 ingresa por el stdin de comando 3.\\ | ||
+ | Esto permite, encadenar comandos que realizan diferentes tareas, para, de esa manera, ampliar la capacidad de procesamiento de la computadora. | ||
+ | |||
+ | En definitiva, estamos armando pequeños programas, que hacen cosas que no estaban previstas anteriormente. De ahi, surge la filosofía de UNIX de disponer de comandos sencillos, que hagan bien una cosa.\\ Al encadenar comandos con pipes, extendemos las posibilidades haciendo cosas que los comandos por separados no pueden hacer. | ||
+ | |||
+ | Vayamos pues al ejemplo: | ||
+ | |||
+ | Supongamos que tenemos un archivo de texto **palabras.txt** que contiene las siguientes palabras : | ||
+ | |||
+ | texto, anexo, pretexto, contexto, sujeto, predicado, texto, sujeto, sujeto, anexo, panfleto, anexo. | ||
+ | |||
+ | El comando **SORT** nos permite ordenarlo alfabéticamente : | ||
+ | |||
+ | < | ||
+ | SORT palabras.txt | ||
+ | </ | ||
+ | |||
+ | del cual se obtiene el siguiente resultado : | ||
+ | |||
+ | anexo\\ | ||
+ | anexo\\ | ||
+ | anexo\\ | ||
+ | contexto\\ | ||
+ | panfleto\\ | ||
+ | predicado\\ | ||
+ | pretexto\\ | ||
+ | sujeto\\ | ||
+ | sujeto\\ | ||
+ | sujeto\\ | ||
+ | texto\\ | ||
+ | texto\\ | ||
+ | |||
+ | para tener las cosas más claras podemos utilizar el comando **UNIQ**, que saca cada palabra una sola vez, porque en definitiva lo que hace **UNIQ**, es eliminar las líneas repetidas.\\ Haciendo una tubería obtenemos : | ||
+ | | | ||
+ | < | ||
+ | SORT palabras.txt |UNIQ | ||
+ | </ | ||
+ | |||
+ | anexo\\ | ||
+ | contexto\\ | ||
+ | panfleto\\ | ||
+ | predicado\\ | ||
+ | sujeto\\ | ||
+ | texto\\ | ||
+ | |||
+ | pero, si usamos **UNIQ** con la opción **-c**, coloca en la salida y junto a cada palabra, la cantidad de veces que esa palabra aparece en el texto : | ||
+ | |||
+ | < | ||
+ | SORT palabras.txt |UNIQ -c | ||
+ | </ | ||
+ | |||
+ | 3 anexo\\ | ||
+ | 1 contexto\\ | ||
+ | 1 panfleto\\ | ||
+ | 1 predicado\\ | ||
+ | 1 pretexto\\ | ||
+ | 3 sujeto\\ | ||
+ | 2 texto\\ | ||
+ | |||
+ | Pero ahora, podemos volver a ordenarlo, pero numéricamente (para eso usamos la opción **-n** del **SORT**), para poner al principio las palabras menos frecuentes y al final las más frecuentes. | ||
+ | |||
+ | < | ||
+ | SORT palabas.txt | UNIQ -c | SORT-n | ||
+ | </ | ||
+ | |||
+ | 1 contexto\\ | ||
+ | 1 panfleto\\ | ||
+ | 1 predicado\\ | ||
+ | 1 pretexto\\ | ||
+ | 2 texto\\ | ||
+ | 3 anexo\\ | ||
+ | 3 sujeto\\ | ||
+ | |||
+ | Esto, a su vez lo podemos unir con el comando **GREP**. que permite buscar expresiones regulares dentro de archivos de texto o desde **stdin**.\\ Lo podemos unir a la tubería que estuvimos viendo para extraer y numerar palabras que contengan un determinado patrón, por ejemplo, las palabras que contengan " | ||
+ | |||
+ | < | ||
+ | SORT palabras.txt | UNIQ -c | GREP texto | SORT -n | ||
+ | </ | ||
+ | |||
+ | 1 contexto\\ | ||
+ | 1 pretexto\\ | ||
+ | 2 texto\\ | ||
+ | |||
+ | Podemos unir, todo esto, al comando **SED** (Stream Editor) que permite cambiar o modificar el contenido del texto de un archivo. Por ejemplo, podemos cambiar " | ||
+ | | | ||
+ | < | ||
+ | SORT palabras.txt | UNIQ -C | GREP texto | SED ' | ||
+ | </ | ||
+ | |||
+ | 1 converso\\ | ||
+ | 1 preverso\\ | ||
+ | 2 verso\\ | ||
+ | |||
+ | Apasionante no, pues bien, vayamos a otro ejemplo : | ||
+ | |||
+ | El comando **DU** nos informa de la ocupación de un directorio determinado (disk usage). Si lo unimos con el comando **SORT**, podemos listar los directorios en orden ascendente de ocupación : | ||
+ | |||
+ | < | ||
+ | du -sk* | sort -n | ||
+ | </ | ||
+ | |||
+ | |||
+ | Estos, son apenas unos ejemplos mínimos que apenas arañan las posibilidades reales. Cada uno de estos comandos posee varias opciones, con lo que las posibilidades se multiplican, | ||
+ | |||
+ | Por esta razón es que los " | ||
+ | |||
+ | \\ | ||
+ | == Named Pipes - otro caso de Tuberías == | ||
+ | |||
+ | Las tuberías o pipes ((Idem))de las que hablamos, que permiten conectar **stdout** de un proceso, con el **stdin** de otro, se puede decir que son pipes anónimos, pues existen entre estos dos procesos y mientras estos procesos se están ejecutando.\\ Cuando termina la ejecución desaparecen, | ||
+ | |||
+ | Un nuevo ejemplo muy sencillo : | ||
+ | |||
+ | Primero abrimos 2 consolas (terminales), | ||
+ | |||
+ | < | ||
+ | mkfifo pepe | ||
+ | </ | ||
+ | |||
+ | el comando se llama **mkfifo**, pues los pipes son todos FIFO (first in, first out), o sea, que lo primero que entra a un pipe, es lo primero que sale por la otra punta. | ||
+ | |||
+ | Si hacemos un **ls -l** veremos que apareció un nuevo archivo **pepe**, y que tiene como tipo de archivo una p. | ||
+ | |||
+ | < | ||
+ | prw-r--r-- 1 ken ken 0 2012-01-08 21:43 pepe | ||
+ | </ | ||
+ | |||
+ | Vamos a poner a uno de los shells, a leer datos de ese archivo (**pepe**), para la cual escribimos en la otra consola : | ||
+ | |||
+ | < | ||
+ | while read linea | ||
+ | do | ||
+ | echo $linea | ||
+ | done <pepe | ||
+ | </ | ||
+ | |||
+ | Como veremos, el prompt no reaparece, pues estamos en un loop infinito, donde el shell simplemente está esperando que aparezcan líneas de texto en el archivo **pepe** y cada vez que aparece una línea de texto la lee y la imprime por pantalla. | ||
+ | |||
+ | Ahora cambiemos a la otra consola (o shell) y ejecutemos el comando siguiente : | ||
+ | |||
+ | < | ||
+ | cat palabras.txt> | ||
+ | </ | ||
+ | |||
+ | O sea, volcamos el contenido del archivo **palabras.txt** al archivo **pepe**.\\ | ||
+ | El prompt reaparece y no pasa nada... | ||
+ | |||
+ | Esta es una manera muy eficaz de comunicar datos entre procesos que no estén vinculados a través del mismo shell. Se puede tener un proceso que simplemente espera leer datos de un named pipe, y otro procesos que simplemente escriben datos allí y el proceso que lee el pipe procesa esos datos.\\ | ||
+ | |||
+ | ¡Simple y brillante! ¿No? | ||
\\ | \\ |
acemu/articulos/articulos_tecnicos/software/introduccion_a_gnu-linux/linux_inicio/terminal.1325973287.txt.gz · Última modificación: 2012/01/07 13:54 por luis