Está en la página 1de 10

SHELL

Antes de los escritorios gráficos, la única vía para interactuar con un sistema Unix era a través
de un interfaz de línea de comandos de texto (CLI) proporcionado por el shell. Hoy en día es
diferente, pero aún se hace a veces necesario introducir comandos del shell en un sistema (por
ejemplo un servidor) que no esté corriendo un entorno gráfico).

Este modo se conoce como consola Linux. Cuando Linux se inicia, automáticamente crea varias
consolas virtuales. Una consola es una sesión de terminal que corre en la memoria del sistema
Linux. En lugar de tener varias terminales físicas conectadas al sistema, la mayoría de
distribuciones inician cinco, seis o más consolas virtuales que pueden ser accedidas a través de
un único teclado y pantalla.

Las consolas virtuales de texto usan la pantalla entera y comienzan con la pantalla de texto de
login. Introduciremos el nombre de usuario y la contraseña.

ACCEDIENDO A UNA CONSOLA VIRTUAL

En la mayoría de servidores Linux, si no somos llevados automáticamente a una sesión de login


en una terminal virtual, podemos acceder a una usando una combinación de teclas.
Normalmente pulsaremos Ctrl + Alt y una tecla de función (desde F1 hasta F7) para elegir la
consola virtual deseada. Cada tecla de función producirá una consola virtual. Qué teclas de
función serán apropiadas, depende de la configuración del sistema Linux.

CAMBIANDO DE CONSOLA

Por ejemplo, si estamos en la consola 2, podemos cambiar a la consola 3 pulsando Ctrl + Alt +
F3, y para volver a la consola 2 bastaría con pulsar Ctrl + Alt + F2.

PROMPT DEL SHELL

Una vez estamos conectados a una consola, tendremos acceso al prompt del CLI del shell. El
prompt es nuestra pasarela al shell, el lugar donde introducimos los comandos shell. El
símbolo por defecto del prompt para el Bash shell es el signo dólar ($). Indica que el shell está
esperando que introduzcamos texto. Diferentes distribuciones usan diferentes formatos para
el prompt. En Ubuntu probablemente podría ser algo similar a:

sysadmin@ubuntu-server:~$

Mientra que en CentOS podría ser:

[sysadmin@localhost ~]$

Además de actuar como punto de acceso al shell, el prompt puede proporcionar información
de ayuda. En ambos casos anteriores, el prompt muestra el nombre del usuario actual
(sysadmin), y el nombre de sistema (ubuntu-server en Ubuntu y localhost en CentOS). El
símbolo ~ representa nuestro directorio home.

Otra ayuda que nos proporciona el shell, es el manual.


MANUAL DEL SHELL

La mayoría de distribuciones incluyen un manual online para buscar información sobre


comandos shell y de otras utilidades GNU incluidas en la distribución. El comando man
proporciona acceso a las páginas del manual almacenadas en el sistema:

$ man apt

Cuando usamos el comando man, la información se muestra con algo llamado paginador
(pager). Un paginador es una utilidad que nos permite ver texto a una página o una línea por
vez. Por lo tanto, podemos navegar por las páginas pulsando la barra espaciadora, o ir línea
por línea usando Enter. Adicionalmente, podemos usar los cursores para hacer scroll. Las
páginas man usan el comando less en concreto. Para más información, usar el comando man
less. Si hemos terminado con las páginas man, pulsamos Q para terminar, y volveremos al
prompt.

El manual divide la información sobre un comando en secciones separadas. Cada sección es


nombrada de forma estandarizada según una convención:

Section Description

Name Displays the command name and a short description


Synopsis Shows command syntax
Configuration Provides configuration information
Description Describes the command generally
Options Describes the command option(s)
Exit Status Defines the command exit status indicator(s)
Return Value Describes the command return value(s)
Errors Provides command error messages
Environment Describes environment variable(s) used
Files Defines files used by the command
Versions Describes command version information
Conforming To Provides the standards that are followed
Notes Describes additional helpful command material
Bugs Provides the location to report found bugs
Example Shows command use examples
Authors Provides information on command developers
Copyright Defines command code copyright status
See Also Refers to similar available commands

No cada página de un comando tiene todas las secciones. Además, algunos comandos tienen
nombres de sección que no están en el estándar convencional. Junto a las secciones
convencionales, existen áreas de sección. Cada área de sección tiene un número asignado,
desde el 1 hasta el 9:

Section Contents

1 Executable programs or shell commands


2 System calls
3 Library calls
4 Special files
5 File formats and conventions
6 Games
7 Overviews, conventions, and miscellaneous
8 Super user and system administration commands
9 Kernel routines

Habitualmente, la utilidad man proporciona el área de contenido más bajo para el comando.
Por ejemplo, al introducir el comando man apt, el las esquinas superiores la palabra APT va
seguida de un número entre paréntesis (8). Esto indica que las páginas que estamos
visualizando provienen del área de contenido 8 (comandos de superusuario y administración
de sistema).

El sistema puede incluir algunos números de sección no estándar en sus páginas man. Por
ejemplo, 1p es la sección que cubre comandos de Portable Operating System Interface (POSIX),
3n es para funciones de red, etc.

AYUDA ADICIONAL

Las páginas man no son la única referencia, hay también páginas de información llamadas info
pages. Para más información sobre las info pages, escribiremos info info.

Los comandos internos (built-in), que son los comandos que están construidos dentro del Bash
shell, tienen su propio recurso especial llamado help pages. Para más información,
escribiremos help help.

Adicionalmente, muchos de los comandos aceptan la opción -h o --help.

En ocasiones, un comando tiene el mismo nombre que un archivo especial o una sección en las
páginas man, y por consiguiente el nombre aparece listado en múltiples áreas de contenido de
sección. Por defecto, la información man que se muestra es la del número de sección más
bajo, por lo que man passwd mostrará la información del comando passwd de la sección 1.
Para omitir el orden de sección por defecto, usaremos man 5 passwd si queremos ver las
páginas man del archivo passwd (sección 5).

También podemos navegar por una introducción a las diferentes áreas de sección con man 1,
man 2, etc.

COMANDOS

Existen algunos trucos para ayudar a trabajar con el shell más rápidamente.

INTRODUCIENDO COMANDOS

Los comandos introducidos en el prompt de línea de comando son de hecho programas. Al


introducir un nombre de programa en el prompt del shell, se ordena al Bash shell que ejecute
ese programa. Esos programas pueden estar construidos dentro del propio shell o ser externos
y residir en la estructura virtual de directorios de Linux.

DETERMINANDO SI UN COMANDO ESTÁ DENTRO DEL SHELL


La forma más rápida es usando el comando type. Por ejemplo, si usamos type type,
recibiremos un mensaje de que help está dentro del shell. Otro ejemplo sería usar el comando
type con la utilidad man, escribiendo type man. Recibiremos un mensaje similar a
/usr/bin/man, lo que indica que éste programa es externo a Bash shell.

Estos programas tienen una sintáxis básica para su uso:

Nombre_de_comando Opción(es) Argumento(s)

Por ejemplo, el comando:

$ man –k cp

El nombre de comando es man. La opción es -k, y el argumento es cp. Las opciones y


argumentos no son requeridos, pero si se usan, son para modificar el comportamiento del
comando.

USANDO COMPLECCIÓN DE COMANDOS

Bash shell proporciona una característica llamada complección de comandos. Nos permite
escribir parte de un comando o nombre de archivo y pulsar la tecla Tab. Si hay solo un caso,
Bash completa por nosotros.

OBTENIENDO COMANDOS ANTERIORES

Un método para que las cosas vayan más rápidas es usar la historia de línea de comandos.
Todos los comandos son almacenados en una lista histórica (los últimos 1000 comandos).
Podemos recuperar comandos de esta lista y reutilizarlos con un tecleo mínimo. Además,
posemos modificar los comandos. Para ver la historia, escribimos el comando history sin
opciones:

$ history


11 exit
12 man -k copy
13 apropos copy

Para llamar al último comando y reutilizarlo, escribimos !! y pulsamos Enter:

$ type man
man is /usr/bin/man

$ !!
type man
man is /usr/bin/man

Al pulsar !!, Bash shello primero muestra el comando y después lo ejecuta. También podemos
usar el cursor arriba y pulsar Enter para llamar y reusar el último comando.
Para llama a un comando que está más arriba en la lista, escribimos !5 (o el número adecuado)
y pulsamos Enter.

$ !16
whatis cp
cp (1) - copy files and directories

También podemos editar comandos antes de ejecutarlos. Sin embargo, es necesario usar el
cursor arriba antes de modificarlo.

La historia es guardada en memoria, pero cuando hacemos logout, la lista es guardada en un


archivo especial, el .bash_history, situado en el directorio home de cada usuario. Al hacer login
nuevamente, el contenido del archivo es cargado en la historia en memoria.

Algunas opciones del comando history:

Option Description

-a Appends the current history list to the history file


-c Clears the history list of contents
-n Appends history file commands to the current history list, but only if they have not
already been put into the list
-w Writes the current history list to the history file

Si tenemos múltiples sesiones de terminal abiertas, actualizamos automáticamente las listas


de historia en nuestras otras sesiones de terminal abiertas mediante el comando history –a en
la sesión de terminal cuya historia queremos guardar. Entonces en las otras sesiones de
terminal, usaremos el comando history –n para actualizar sus listas de historia.

REDIRECCIÓN DE COMANDOS

Una de las cosas que podemos hacer con el Linux CLI es redirigir comandos. Por defecto, la
salida de un comando va a la pantalla de la terminal, y la entrada viene del teclado o del ratón.
Pero podemos modificar este comportamiento.

Linux maneja cada objeto como un archivo, incluyendo el proceso de entrada y salida. Linux
identifica cada objeto de archivo usando un descriptor de archivo, que es un entero que
identifica de manera única archivos abiertos en una sesión. Bash shell reserva los primeros tres
descriptores de archivo (0, 1 y 2) para las entradas y salidas estándar del CLI:

File Descriptor Abbreviation Description

0 STDIN Standard input


1 STDOUT Standard output
2 STDERR

REDIRECCIONANDO STDOUT

La mayoría de comandos Bash dirigen su salida al descriptor de archivo STDOUT por defecto,
pero podemos redireccionar esa salida.
$ history > keepHistory.txt

Usando el símbolo mayor (>), STDOUT es redirigido al fichero keepHistory.txt en lugar de salir
por pantalla.

Si usamos la redirección hacia un fichero preexistente, borrará todo el contenido previo. Por lo
tanto, para anexar el contenido al fichero usaremos:

$ history >> keepHistory.txt

REDIRECCIONANDO STDERR

El shell maneja los mensajes de error usando el descriptor de archivo STDERR. Por defecto,
este descriptor apunta al mismo sitio que STDOUT. Para redireccionar:

$ hist
-bash: hist: command not found

$ hist 2 > myerr.txt

$ cat myerr.txt
-bash: hist: command not found

El anexado funcionará de forma similar a la de STDOUT:

$ hist 2 >> myerr.txt

Si no queremos guardar mensajes de error y no queremos verlos, podemos ponerlos dentro de


un agujero negro, que es el archivo /dev/null:

$ hist 2 >> /dev/null

Si es necesario, podemos redirigir tanto STDERR como STDOUT al mismo archivo. Bash shell
proporciona un símbolo para este propósito, el ampersand (&). Veamos mostrando un archivo
que sí existe (/proc/version), y otro que no existe (NSF.txt):

$ cat /proc/version NSF.txt &> newerr.txt

$ cat newerr.txt
Linux version 4.18.0-193.28.1.el8_2.x86_64 (mockbuild@kbuilder.bsys
.centos.org) (gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC))
#1 SMP Thu Oct 22 00:20:22 UTC 2020
cat: NSF.txt: No such file or directory

REDIRECCIÓN A TRAVÉS DE PIPES

Las pipes encadenan el STDOUT de un comando al STDIN de otro comando. Esto crea una línea
de tuberías (pipeline) de comandos.

El símbolo para redirigir STDIN para un comando es el símbolo menor (<). Sin embargo, para
encadenar STDOUT y STDIN, Bash shell proporciona el símbolo pipe (|).
Redirigiremos el STDOUT del comando history como STDIN para el comando less, usando un
pipe:

$ history | less

Por supuesto, no estamos limitados a encadenar solo dos comandos en una pipeline.

DIVIDIENDO LA REDIRECCIÓN

Si queremos no solo ver la información producida en un pipeline sino también mantener una
copia, esto requerirá el uso de un comando especial llamado tee. El comando tee guardará
STDOUT en un archivo y lo hará fluir como STDIN para el siguiente comando del pipeline:

Vamos a guardar una copia de la lista de historia en keepHistory.txt y verla en el paginador


less:

$ history | tee keepHistory.txt | less

VARIABLES DE ENTORNO

Bash shell usar una característica llamada variables de entorno para almacenar información
acerca de la sessión shell y el entorno de trabajo. Esta característica también nos permite
almacenar datos en memoria que puedan ser fácilmente accedidos por cualquier programa.

Hay dos tipos de variables de entorno en Bash shell: globales y locales.

VARIABLES DE ENTORNO GLOBALES

La sesión de shell que se inicia cuando un usuario loguea en una terminal es un shell padre.
Cuando se introduce el comando bash en el CLI prompt, por ejemplo cuando corremos un shell
script, se crea un nuevo proceso shell. Este es un shell hijo. Las variables globales de entorno
son visibles no solo en el shell donde son definidas sino también en sus subshells hijos.

Las variables locales son diferentes en que están disponibles solo en el shell que las crea. Esto
hace que las variables de entorno globales sean útiles en aplicaciones que crean subshells hijos
que requieren información del shell padre.

El sistema Linux establece varias variables globales de entorno cuando iniciamos nuestra
sesión Bash. Estas variables de entorno siempre usan letras mayúsculas para diferenciarse de
las variables definidas por el usuario.

Para ver todas las variables de entorno globales actualmente establecidas usaremos el
comando printenv o el comando env:

$ env


HOSTNAME=localhost.localdomain
USER=sysadmin
PWD=/home/sysadmin
HOME=/home/sysadmin
SHELL=/bin/bash
HISTSIZE=1000

Podemos usar el comando printenv o el comando echo para mostrar un contenido individual
del entorno global:

$ printenv USER

sysadmin

$ echo $HOME

/home/sysadmin

Si usamos el comando echo, tenemos que agregar el signo dólar ($) delante del nombre de la
variable de entorno global, lo que no es requerido con el comando printenv.

Algunas variables de entorno globales comunes por defecto:

Name Description

BASH The full pathname to execute the current instance of the Bash shell
BASH_VERSION The version number of the current instance of the Bash shell
GROUPS A variable array containing the list of groups of which the current user
is a member
HISTFILE The name of the file in which to save the shell history list
(.bash_history by default)
HISTSIZE The maximum number of commands stored in the history list
HOME The current user’s home directory
HOSTNAME The name of the current host
PATH A colon-separated list of directories where the shell looks for
commands
PS1 The primary shell command-line interface’s prompt string
PS2 The secondary shell command-line interface’s prompt string
PWD The current working directory
SHELL The full pathname to the Bash shell
USER Username of current login session

Un par de variables interesantes implican al comando history anteriormente comentado. Sus


ajustes en CentOS son:

$ echo $HISTFILE

/home/sysadmin/.bash_history

$ echo $HISTSIZE

1000
VARIABLES DE ENTORNO DEFINIDAS POR EL USUARIO

Las variables de entorno locales solo son vistas en el proceso local donde son definidas y no
están disponibles en subshells hijos. Linux define unas cuantas variables de entorno locales por
nosotros, pero cuando definimos las nuestras, estas se llaman variables de entorno locales
definidas por el usuario.

Tras loguearse en el sistema Linux o lanzar un shell hijo, ya podemos crear variables locales
definidas por el usuario que son visibles dentro de nuestro proceso shell. Podemos asignar un
valor numérico o un valor de cadena a una variable usando el signo igual (=). Para no liarse con
las variables globales, lo mejor es utilizar solo letras minúsculas:

$ myvar="Hello World"
$ echo $myvar

Hello World

Tras definir una variable de usuario, en cualquier momento que necesitemos referenciarla,
bastará con usar su nombre precedido del signo dólar ($). Si deseamos eliminar el valor de la
variable, usaremos el comando unset:

$ echo $myvar

Hello World

$ unset myvar

$ echo $myvar

GLOBALIZACIÓN DE VARIABLES

En ocasiones queremos variables locales definidas por usuario disponibles para los subshells. Si
queremos hacer global una variable ya definida, usaremos el comando export. Para hacerla
global cuando la definimos, tenemos dos opciones. Podemos poner los dos comandos en la
misma línea separando por punto y coma (;):

$ newvar="42"; export newvar

La segunda opción es usar el comando export al principio:

$ export newvar="42"

El comando set muestra variables de entorno globales, variables de entorno locales, variables
definidas por el usuario y funciones locales, y las muestra alfabéticamente (printenv y env no
ordenan y no incluyen ni las locales, ni las definidas por el usuario, ni las funciones shell
locales).

REDEFINICIÓN DE LAS VARIABLES DE ENTORNO POR DEFECTO

A veces necesitamos modificar una variable de entorno por defecto. Podemos querer dicha
modificación local o global. Sin embargo, ya que modificar el valor por defecto de una variable
de entorno global puede repercutir de forma importante en el sistema, es bueno practicar
primero con variables globales menos importantes:

1. Cambiar la apariencia del prompt de Bash shell con PS1=”$ “.


2. Ver si el cambio sobrevive en un subshell usando el comando bash. Veremos que no,
pues no hemos globalizado la variable local.
3. Usaremos exit para abandonar el subshell.
4. Ahora usaremos export PS1=”$ “.
5. Si creamos un subshell, vemos que el cambio sobrevive.
6. Abandonamos nuevamente el subshell.
7. Eliminamos nuestro prompt con unset PS1. Ahora no tenemos prompt.
8. Abandonemos el shell con exit. Cuando volvamos a iniciarlo, todo estará como antes.

También podría gustarte