Qué es la terminal
La terminal, también llamada consola, shell, modo texto, intérprete de comandos, línea de comandos o CLI (Command Line Interface), es una de las dos interfaces posibles en Linux, junto con el entorno gráfico, también llamado modo gráfico, X Window o las X.
Resumiendo y para hacernos una idea, es un entorno de trabajo similar a MS-DOS en Windows, donde se introducen los comandos de forma manual.
Vamos a ver un pequeño manual con lo más básico en la terminal de Linux.
Cómo le damos órdenes a la máquina en modo texto?
Usando comandos. La sintaxis de un comando es:
$ orden <opciones> <argumentos> |
- orden: comando a ejecutar (por ejemplo ls).
- <opciones>: suelen ir precedidas por un guión (por ejemplo -l) y pueden ser más de una, en cuyo caso se pueden escribir separadas (por ejemplo -l -r) o juntas (-lr). Algunas opciones tienen formato corto (-f) y formato largo (–fix-broken), que suele llevar dos guiones.
- <argumentos>: pueden ser varios separados por espacios.
Normalmente, los comandos que admiten opciones suelen tener una opción por defecto que corresponde a su forma de uso habitual y facilita su empleo.
Algunos comandos, una vez ejecutados, quedan en modo interactivo esperando entradas por el teclado. En este caso, con <Ctrl+D> (fin de entrada de datos, carácter EOT, End Of Text, fin de texto) le diremos al sistema que deje de leer la entrada y continue procesándo el comando.
Con el carácter "" indicamos que el comando continúa en la línea siguiente, en la que aparece el prompt secundario (>) para que sigamos tecleando el comando.
$ cat > file1 aceitunas berenjenas castañas |
Qué ocurre cuando tecleamos un comando?
Cuando se teclea una orden, el intérprete de comandos hace varias cosas:
- primero comprueba si es una orden interna, es decir, una orden que el propio intérprete de comandos
sabe ejecutar por sí mismo (como alias, job, cd, etc). Veremos un listado
con los comandos internos de bash con help:
$ help
- si no es una orden interna, comprueba si la orden es un alias de otro comando. Para ver el listado de
alias haremos:
$ alias
- si no es una orden interna ni un alias, busca el programa en los directorios indicados en
el PATH, en orden. Para ver el valor de la variable PATH haremos:
$ echo $PATH
y obtendremos algo similar a:
/bin:/usr/bin:/usr/local/bin:/usr/bin/X11
El PATH de root es distinto al de un usuario normal. Además de los directorios anteriores incluye los directorios sbin:
/sbin:/usr/sbin:/usr/local/sbin
Esto explica que si un usuario normal intenta ejecutar el comando:
$ ifup
el sistema no lo encuentra, ya que está en /sbin/ifup y esa ruta no figura en su PATH. Debe ejecutar:
$ /sbin/ifup
Para ejecutar programa, que está en el directorio actual, suponiendo que su ruta no figura en el PATH, haremos:
$ ./programa
Directorio actual y directorio padre
En Linux "." representa el directorio actual y ".." el directorio padre.
- si ha encontrado el comando lo ejecuta pasándole las opciones y argumentos especificados. El shell genera un sub-shell para cada orden que ejecuta que muere al finalizar la ejecución de la orden.
- si no encuentra un programa con ese nombre, muestra un mensaje de error:
command not found
Veremos a menudo este mensaje de error si el directorio donde está el programa a ejecutar no figura en el PATHsi nos equivocamos al teclear una orden o . Debemos tener en cuenta que los nombres de comandos (igual que ocurre con los archivos y directorios) son case-sensitive y distinguen entre mayúsculas y minúsculas). Por ejemplo, el comando make es diferente a Make o MAKE.
Entrada y Salida estándar
En Linux cada proceso abre tres canales de comunicación:
- la entrada estándar (stdin): entrada de datos, el teclado.
- la salida estándar 1 (stdout): respuesta del comando, el monitor.
- la salida estándar 2 (stderr): mensajes de error, el monitor.
Por ejemplo, el comando cat tiene como entrada estándar el teclado y como salida estándar 1 el monitor. Si lo ejecutamos sin argumentos leerá datos del teclado y los enviará al monitor, de manera que cada línea que el usuario teclea es inmediatamente enviada al monitor, hasta la señal de fin de entrada de datos (<Ctrl+D>).
$ cat Hola caracol Hola caracol Adios Adios <Ctrl+D> |
En cambio, el comando para copiar archivos cp tiene como entrada estándar un archivo (file1) y como salida estándar 1 otro archivo (file2):
$ cp file1 file2 |
Veamos los operadores que nos permiten redireccionar la entrada y salida estándar:
- redirección destructiva de la salida (>)
- Podemos redireccionar la salida estándar 1 a un archivo usando el símbolo
">". Este tipo de redirección es destructiva: si el archivo no existe lo crea,
y si existe lo sobrescribe. En el siguiente ejemplo vemos que el resultado de cat no se muestra por
pantalla, sino que es enviado al archivo lista.
$ cat > lista Hola caracol Adios <Ctrl+D>
Para almacenar el contenido del archivo file1 en file2 haremos:
$ cat file1 > file2
- Este tipo de redirección también se puede aplicar a la salida estándar 2, la
salida de errores, que normalmente es también el monitor. Por ejemplo, cuando se ejecuta un
comando en segundo plano, interesa evitar que los mensajes de error aparezcan en la pantalla, pues
en ella habremos empezado a hacer otra cosa: en ese caso, lo que haremos será redirigir la
salida de errores hacia un archivo. En el siguiente ejemplo, compilamos en segundo plano un archivo
dirigiendo los mensajes de error al archivo errores:
$ gcc prueba.c 2> errores &
- Podemos redireccionar ambas salidas, la salida estándar 1 y la 2. Por ejemplo, si ejecutamos
el siguiente comando redireccionando la salida estándar 1, el sistema listará el
directorio actual y enviará la salida al archivo dummy:
$ ls > dummy
Pero si hacemos eso con un directorio inexistente, el sistema no enviará nada a dummy, pero mandará el mensaje de error a la pantalla, ya que hemos redireccionado la salida estándar 1 pero no la salida estándar 2, la salida estándar para errores:
$ ls directorio_inexistente > dummy ls: directorio_inexistente: No existe el archivo o el directorio.
Para que el error tampoco aparezca por pantalla redireccionaremos ambas salidas:
$ ls directorio_inexistente > dummy 2> dummy
- Podemos redireccionar la salida estándar 1 a un archivo usando el símbolo
">". Este tipo de redirección es destructiva: si el archivo no existe lo crea,
y si existe lo sobrescribe. En el siguiente ejemplo vemos que el resultado de cat no se muestra por
pantalla, sino que es enviado al archivo lista.
- redirección no destructiva de la salida (>>)
- Podemos hacer una redirección no destructiva
de la salida estándar 1 utilizando el operador ">>". Este tipo
de redirección es no destructiva: si el archivo no existe lo crea, y si existe
añadirá la salida al final del archivo, en lugar de sobrescribirlo. Por ejemplo,
para añadir el archivo file2 al final de file1 haremos:
$ cat file2 >> file1
- También se puede aplicar la redirección
no destructiva a la salida estándar 2, la salida de errores. Por ejemplo, para
añadir los mensajes de error producidos al compilar prueba.c en segundo plano
al archivo errores haremos:
$ gcc prueba.c 2>> errores &
- Podemos hacer una redirección no destructiva
de la salida estándar 1 utilizando el operador ">>". Este tipo
de redirección es no destructiva: si el archivo no existe lo crea, y si existe
añadirá la salida al final del archivo, en lugar de sobrescribirlo. Por ejemplo,
para añadir el archivo file2 al final de file1 haremos:
- redirección de la entrada (<)
Podemos redireccionar la entrada estándar usando el operador "<":
$ sort < cosas.txt aceitunas berenjenas castañas
- tuberías (|) las tuberías o pipes nos permiten conectar
(entubar) una cadena de comandos: la salida del primero es la entrada del
segundo, y así sucesivamente. Por ejemplo, vamos a enviar a sort la salida
de ls, para que la ordene en orden inverso:
$ ls | sort -r tesis notas historia
Podemos conectar tantos comandos como queramos:
$ ls /usr | sort -r | more
- bifurcaciones (| tee) una bifurcación o T permite que la salida de un comando, además de
redirigirse a un determinado archivo, se bifurque también hacia la terminal, con objeto de observar
inmediatamente el resultado. Para que la salida de ls se bifurque hacia la terminal y hacia
file haremos:
$ ls | tee file
Para que la salida de ls se añada al final de file usaremos la opción -a:
$ ls | tee -a file
- tuberías con nombre (FIFOs): una tubería con nombre es un archivo que actúa
como una tubería. Uno añade algo al archivo y sale por el otro extremo. Es por eso que se denomina
FIFO o First-In-First-Out: lo primero que entra a la tubería es lo primero que sale por el otro extremo.
Si se escribe en una tubería con nombre, el proceso que escribe en la tubería no finaliza hasta que la información escrita es leída de la tubería.
Si se lee de una tubería con nombre, el proceso de lectura espera hasta que exista algo para leer antes de finalizar.
El tamaño de la tubería es siempre cero: no almacena datos, sólo vincula dos procesos. No obstante, puesto que la tubería tiene nombre, los dos procesos no tienen que estar en la misma línea de comandos ni tampoco ser ejecutados por el mismo usuario.
Veamos un ejemplo. Creamos una tubería con nombre:
$ mkfifo mi_tuberia
Escribimos en la tubería con nombre en segundo plano:
$ echo "hola" > mi_tuberia & [1] 5952
Listamos la tubería con nombre para comprobar que su tamaño es cero:
$ ls -l mi_tuberia prw-r--r-- 1 francis francis 0 2003-11-06 23:18 mi_tuberia
Leemos la tubería con nombre:
$ cat mi_tuberia hola [1]+ Done echo "hola" > mi_tuberia
Historial de comandos ejecutados
El shell de Linux guarda en la memoria el historial de comandos ejecutados y podemos acceder a ellos
simplemente pulsando las flechas del cursor. Si cerramos la sesión adecuadamente el historial de
comandos ejecutados quedará guardado en el archivo:
~/.bash_history
cuyo contenido se puede controlar desde ~/.bashrc, por ejemplo:
# no guardar duplicados export HISTCONTROL=ignoreboth # numero de comandos a guardar export HISTSIZE=1000 # guardar los comandos al ejecutarlos PROMPT_COMMAND='history -a' |
Autocompletar
Linux tiene implementada una función de autocompletar que funciona en dos casos:
- si escribimos los primeros caracteres de un comando y pulsamos dos veces TAB, nos presentará la lista de comandos que comienzan por esos caracteres.
- si escribimos las primeras letras del nombre de un archivo o directorio como argumento de un comando, al pulsar TAB efectuará un autorrellenado hasta el punto en el que se diferencien las opciones.
Caracteres comodín
Los llamados comodines nos permiten referirnos a, por ejemplo, grupos de archivos que tienen algún tipo de coincidencia.
- El comodín "*" hace referencia cualquier carácter
o cadena de caracteres.
$ ls precios presupuestos notas $ ls *r* precios presupuestos
Utilizando este comodín no obtendremos los archivos que comiencen con un punto ("."). A estos archivos, llamados "ocultos" (porque no son mostrados en un listado normal de ls) o "dot files" (por comenzar por un punto), no les afecta el uso del comodín "*". Para verlos debe usarse la opción -a:
$ ls -a .config .gnome2 precios presupuestos notas
- El comodín "?" sólo expande un único carácter.
$ ls ?resupuestos presupuestos
- El comodín [...] sustituye cualquier valor incluido entre los corchetes:
$ ls nota1 nota2 nota3 note3 $ ls nota[13] nota1 nota3 $ ls not[ae]3 nota3 note3 $ ls nota[1-3] nota1 nota2 nota3 $ ls nota[!12] nota3
Escapar caracteres especiales
Cuando escribimos caracteres especiales (wildcards) el sistema los interpreta como tales. Por ejemplo, si ejecutamos el comando:
$ echo * precios presupuestos notas |
Si queremos utilizar caracteres especiales ("*" asterisco, ">" mayor que, "&" ampersand…) y que el sistema los interprete como caracteres normales tenemos que usar una "secuencia de escape", y diremos que los hemos "escapado". Lo que haremos será preceder dicho carácter con la barra invertida (), que impide la interpretación del carácter siguiente (sólo uno). Por ejemplo, para escribir un asterisco haremos:
$ echo * * |
Si queremos escribir tres asteriscos haremos:
$ echo *** *** |
Comillas
- Las comillas simples (‘) anulan el significado de todos los caracteres comprendidos entre ellas. Por ejemplo,
podríamos escribir un triple asterisco con el comando:
$ echo '***'
- Las comillas dobles (") son menos restrictivas y anulan el significado de todos los caracteres especiales
excepto dólar ($), comilla simple (‘), comilla simple invertida (`) y barra invertida (). Por ejemplo, si
VAR es una variable:
$ VAR=hola
y queremos sacar por pantalla el valor de VAR haremos:
$ echo $VAR hola
o bien:
$ echo "$VAR" hola
mientras que para sacar por pantalla la cadena "$VAR" haremos:
$ echo '$VAR' $VAR
- Las comillas simples invertidas o acento grave (`) provocan la ejecución de los comandos comprendidos entre
ellas, sustituyéndose el comando por el resultado que genera al ejecutarse. Por ejemplo, si hacemos:
$ echo "Soy el usuario `whoami`" Soy el usuario francis
Agrupar comandos
Linux permite agrupar comandos por medio de operadores:
- operador ";": ejecutar sucesiva e independientemente varios comandos:
$ orden1 ; orden2 ; orden3
- operador "&&": ejecutar orden2 sólo si la
ejecución de orden1 ha tenido éxito.
$ orden1 && orden2
- operador "||": ejecutar orden2 sólo si la ejecución
de orden1 no ha tenido éxito.
$ orden1 || orden2
Limpiar la pantalla
- El comando clear limpia la pantalla:
$ clear
- El comando reset devuelve la consola a su estado normal. Si la pantalla ha enloquecido por
haber volcado en pantalla algún archivo binario, por ejemplo por haber hecho:
$ cat <archivo_binario>
debemos ejecutar (aunque probablemente no podamos ver lo que escribimos):
$ reset
Visualizar el contenido de un archivo de texto
Para visualizar el contenido de un archivo de texto usaremos:
- para ver todo el contenido, el comando cat (concatenate):
$ cat file
- para ver el contenido pantalla a pantalla usaremos el paginador less. Podemos movernos con
<AvPág>, <RePág>, flechas y <Espacio> (equivale a
<AvPág>) y volver al prompt pulsando <q> (quit):
$ less file
Capturar una sesión de terminal
El comando script permite guardar una transcripción de una sesión de terminal en un archivo de texto. Se suele utilizar para capturar la actividad de la terminal durante la ejecución de comandos como dpkg o apt-get. La sintaxis es:
$ script <archivo> |
Para iniciar la transcripción y guardarla en el archivo /home/francis/type.txt haremos:
$ script /home/francis/type.txt Script iniciado: el fichero es /home/francis/type.txt |
El comando script genera un sub-shell, de manera que a partir de ese momento, todas las órdenes ejecutadas y sus salidas por pantalla se guardarán en el archivo /home/francis/type.txt. Para terminar la ejecución de script haremos:
$ exit Script terminado: el fichero es /home/francis/type.txt |
Si no especificamos <archivo>, la captura de la sesión se guardará en el archivo /<directorio_actual>/typescript (si el archivo existe lo sobreescribirá).
Variables
- Una variable puede tener ámbito global (visible en todos los shell) o ámbito local (visible
sólo en el shell en que fue definida). Para ver la lista de variables globales haremos:
$ env
Para ver la lista de variables locales haremos:
$ set
- Podemos definir variables desde el shell o desde scripts. Para definir la variable llamada A (es
habitual utilizar letras mayúsculas) y valor "playa", haremos lo siguiente:
$ A=playa
Nota
No debemos dejar espacios entre el nombre, el igual (=) y el valor.
Si una variable contiene espacios debe llevar comillas simples (‘) o dobles ("):$ FECHA="31 de diciembre de 1986"
Para ver el contenido de una variable hay que precederla con el carácter "$".
Ahora podemos usar esta variable desde el prompt o en scripts, pero sólo podremos acceder a su valor en el shell en que se han definido, ya que es una variable local:
$ echo $A playa $ bash $ echo $A
Primero comprobamos su valor y está correcto, pero después hemos lanzado un nuevo sub-shell con el comando bash y aquí la variable A no aparece: sólo es "visible" en el shell donde fue definida.
- Para convertir variables locales en globales (para que sean accesibles desde todos los shell), usaremos el
comando export:
$ export A $ bash $ echo $A playa
Ahora el valor de la variable A puede ser leído desde cualquier shell o script.
- El comando export sin argumentos nos mostrará el listado de variables exportadas:
$ export
Directorio actual y directorio padre
Cuando listemos el contenido de un directorio veremos dos archivos un poco raros:
$ ls -a . .. imagen1.jpg imagen2.jpg |
El símbolo "." representa el directorio actual y ".." el directorio padre.
Atajo para el directorio personal
El carácter "~" (<AltGr+4>) es un atajo para referirnos al directorio personal de un usuario.
- para un usuario normal "~" equivale a /home/<usuario>, y el comando:
$ cd ~
es equivalente a:
$ cd /home/francis
- para el usuario root "~" equivale a /root.
Scripts de inicio del shell Bash en Linux
Cuando el shell Bash arranca ejecuta varios scripts de inicio que permiten personalizar el entorno de trabajo de cada usuario, definiendo variables (como PATH) o ejecutando comandos (como alias), de manera que se activen cada vez que iniciamos sesión. Usaremos dos archivos, según el tipo de terminal:
- /etc/profile: se ejecuta sólo al entrar en un shell de login y afecta a todos los usuarios. Por
ejemplo, para activar <NumLock> en las consolas de login incluiremos la línea:
# activar NumLock setleds +num
- ~/.bashrc (uno para cada usuario): se ejecuta al entrar tanto en los shell de login como en los Xterm,
y sólo afecta a cada usuario. Por ejemplo, podemos incluir algunos alias:
# alias alias ls="ls -l" alias "cd.."="cd .."
Este archivo se genera cuando se crea un usuario: se copia /etc/skel/.bashrc en su directorio personal.
Si hemos modificado algún script de inicio de Bash y queremos volverlo a cargar, lo haremos con el comando source:
$ source ~/.bashrc |
Excelente, gracias por el aporte.
Muchisimas gracias por este mini manual. Llevaba buscando algo así bastante tiempo.
Buen mini-manual.
Hey MUCHAS GRACIAS!!! Soy nueva en este mundo y me han puesto a programar en Anjuta, aún sin siquiera poder manejar bien la terminal XD… Está excelente el mini-manual, cuesta encontrar cosas tan claras entre los foros…
Clarito como el agua,muy bien explicado de principio a fin.muchas gracias,sigan asi.
Me encanta, he salido de un apuro con esta información. ¡Mil gracias! ¡No lo quites!