jueves, 21 de septiembre de 2017

Trabajando con Comandos

Llegados a este punto, hemos visto una serie de misteriosos comandos, cada uno con sus misteriosas opciones y argumentos. En este capítulo, intentaremos resolver algunos de estos misterios e incluso crear algunos comandos propios. Los comandos presentados en este capítulo son:
  • type – Indica como se interpreta el nombre de un comando 
  • which – Muestra que programa ejecutable será ejecutado 
  • help – Ofrece ayuda para funciones del shell 
  • man – Muestra el manual de un comando 
  • apropos – Muestra una lista de comandos apropiados 
  • info – Muestra información sobre un comando 
  • whatis – Muestra una descripción muy breve de un comando 
  • alias – Crea un alias para un comando 
¿Qué son exactamente los comandos?

Un comando puede ser una de estas cuatro cosas: 

  • Un programa ejecutable como todos esos archivos que vimos en /usr/bin. Dentro de esta categoría, los programas pueden ser binarios compilados como programas escritos en C y C++, o programas escritos en lenguajes de script como el shell, perl, python, ruby, etc. 
  • Un comando contenido en el propio shell. bash soporta gran número de comandos internos llamados shell builtins. El comando cd, por ejemplo, es un shell builtin. 
  • Una función del shell. Éstos son pequeños scripts de shell incorporados en el entorno. Veremos cómo configurar el entorno y cómo escribir funciones del shell en próximos capítulos, pero por ahora, sólo ten en cuenta que existen. 
  • Un alias. Comando que podemos definir nosotros mismos, construidos a partir de otros comandos. 
Identificando comandos

A menudo es útil saber exactamente cual de los cuatro tipos de comandos estamos usando y Linux proporciona un par de formas de averiguarlo.

type – Muestra de que tipo es un comando

El comando type es una función del shell que muestra el tipo de comando que el shell ejecutará, indicándole el nombre de un comando en particular. Funciona así:

 type comando

donde comando es el nombre del comando que quieres examinar. Aquí tienes algunos ejemplos:

 [me@linuxbox ~]$ type type
 type is a shell builtin
 [me@linuxbox ~]$ type ls
 ls is aliased to `ls --color=tty'
 [me@linuxbox ~]$ type cp
 cp is /bin/cp


Aquí vemos los resultados para tres comandos diferentes. Fíjate en el de ls (realizado sobre un sistema Fedora) y en cómo el comando ls es realmente un alias del comando ls con la opción “--color=tty” añadida. ¡Ahora sabemos porqué la salida de ls se muestra en color!


which – Muestra la localización de un ejecutable


A veces hay más de una versión de un programa ejecutable instalada en un sistema. Aunque no es muy usual en los sistemas de escritorio, sí es más frecuente en grandes servidores. Para determinar la localización exacta de un ejecutable dado tenemos el comando which:

 [me@linuxbox ~]$ which ls
 /bin/ls


which sólo funciona con programas ejecutables, no con builtins ni con alias que son sustitutos de los verdaderos programas ejecutables. Cuando intentamos usar which en un shell builtin, por ejemplo, cd, no tendremos respuesta o nos dará un mensaje de error:

[me@linuxbox ~]$ which cd
/usr/bin/which: no cd in /opt/jre1.6.0_03/bin:/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/opt/jre1.6.0_03/bin:/usr/lib/ccache:/usr/local/bin:/usr/bin:/bin:/home/me/bin)


que es una forma algo complicada de decir “comando no encontrado”.


Obteniendo la documentación de un comando


Ahora que sabemos qué es un comando, podemos buscar la documentación disponible para cada tipo de comando.

help – Ofrece ayuda sobre los shell builtins

bash tiene una ayuda integrada disponible para cada shell builtin. Para usarla, escribimos “help” seguido del nombre del shell builtin. Por ejemplo:

[me@linuxbox ~]$ help cd
cd: cd [-L|[-P [-e]]] [dir]
Change the shell working directory.

Change the current directory to DIR. The default DIR is the value of the HOME shell variable.

The variable CDPATH defines the search path for the directory containing DIR. Alternative directory names in CDPATH are separated by a colon (:). A null directory name is the same as the current directory. If DIR begins with a slash (/), then CDPATH is not used.

If the directory is not found, and the shell option `cdable_vars' is set, the word is assumed to be a variable name. If that variable has a value, its value is used for DIR.

Options:
-L force symbolic links to be followed
-P use the physical directory structure without following symbolic links
-e if the -P option is supplied, and the current working directory cannot be determined successfully, exit with a non-zero status

The default is to follow symbolic links, as if `-L' were specified.

Exit Status:
Returns 0 if the directory is changed, and if $PWD is set successfully when -P is used; non-zero otherwise.

Una nota sobre la notación: Cuando aparecen corchetes en la descripción de la sintaxis de un comando, indican opciones adicionales. Una barra vertical indica que son elementos excluyentes entre ellos. En el caso del comando cd que vimos antes:

 cd [-L|[-P[-e]]] [dir]

Esta notación dice que el comando cd podría ir seguido opcionalmente por una “-L” o una “-P” y después, si la opción “-P” está especificada la opción “-e” podría también ser incluida seguida por el argumento opcional “dir”.

Mientras que la salida de help para el comando cd es concisa y precisa, esto no significa que sea un tutorial como podemos ver, también parece mencionar muchas cosas de las que aún no hemos hablado. No te preocupes. Llegaremos a ello.


--help – Muestra información de uso

Muchos programas ejecutables soportan una opción “--help” que muestra una descripción de la sintaxis y las opciones soportadas por el comando. Por ejemplo:

[me@linuxbox ~]$ mkdir --help
Usage: mkdir [OPTION] DIRECTORY...
Create the DIRECTORY(ies), if they do not already exist.


  -Z, --context=CONTEXT (SELinux) set security context to CONTEXT Mandatory arguments to long options are mandatory for short options too.
  -m, --mode=MODE set file mode (as in chmod), not a=rwx – umask
  -p, --parents no error if existing, make parent directories as needed
  -v, --verbose print a message for each created directory
      --help display this help and exit
      --version output version information and exit



Report bugs to <bug-coreutils@gnu.org>.

Algunos programas no soportan la opción “--help”, pero pruébalo de todas formas. A menudo el resultado es un error que revelará la misma información de uso.

man – Muestra el manual de un programa

La mayoría de los programas ejecutables pensados para usarse en la linea de comandos proveen un documento llamado manual page o man page. Un programa de paginación especial llamado man se usa para verlos. Se usa así:

 man programa

donde “programa” es el nombre del comando que queremos ver.

Las man pages varían algo en formato pero generalmente contienen un título, una sinopsis de la sintaxis del comando, una descripción del propósito del comando, y una lista y descripción de cada opción del comando. Las man pages, de todas formas, no suelen incluir ejemplos, y están pensadas como una referencia, no como un tutorial. Como ejemplo, probaremos a ver la man page para el comando ls:

 [me@linuxbox ~]$ man ls

En la mayoría de los sistemas Linux, man usa less para mostrar la man page, así que todos los comandos de less que nos son familiares funcionan cuando está mostrado la página.

El “manual” que man muestra está dividido en secciones y no sólo cubre los comandos de usuario sino también los comandos del administrador de sistema, interfaces de programación, formatos de archivo y más. A continuación se describe la estructura del manual:


Organización de la man page

1  Comandos de usuario
2  Interfaces de programación para
 llamadas del kernel del sistema
3  Interfaces de programación para la librería C
4  Archivos especiales como nodos de dispositivos y controladores
5  Formatos de archivo
Juegos y pasatiempos como protectores 
de pantalla
7  Miscelánea
Comandos de administración del sistema

A veces necesitamos buscar en una sección específica del manual para encontrar lo que estamos buscando. Esto es particularmente cierto si estamos buscando un formato de archivo que también es el nombre de un comando. Sin especificar un número de sección, siempre obtendremos el primer resultado, probablemente en la sección 1. Para especificar un número de sección, usamos man así:

 man sección término_buscado

Por ejemplo:

 [me@linuxbox ~]$ man 5 passwd

Ésto mostrará la man page describiendo el formato de archivo del archivo /etc/passwd.

apropos – Muestra comandos apropiados

También es posible buscar una lista de man pages para posibles resultados basados en un término de búsqueda. Es muy tosco pero a veces ayuda. Aquí tienes un ejemplo de una búsqueda de man pages utilizando el término de búsqueda “floppy”:

[me@linuxbox ~]$ apropos floppy
create_floppy_devices (8) - udev callout to create all 
possible floppy device based on the CMOS type 
fdformat (8) - Low-level formats a floppy disk 
floppy (8) - format floppy disks 
gfloppy (1) - a simple floppy formatter for the GNOME 
mbadblocks (1) - tests a floppy disk, and marks the bad blocks in the FAT 
mformat (1) - add an MSDOS filesystem to a low-level formatted floppy disk

El primer campo de cada línea es el nombre de la man page, el segundo campo muestra la sección. Fíjate que el comando man con la opción “-k” ofrece exactamente la misma función que apropos.


whatis – Muestra una descripción muy breve de un comando

El programa whatis muestra el nombre y una descripción de una línea de una man page coincidente con una palabra especificada:

 [me@linuxbox ~]$ whatis ls

 ls                   (1) - list directory contents


La man page más brutal de todas

Como hemos visto, las man pages proporcionadas por Linux y otros sistemas como-Unix están pensadas como una documentación de referencia y no como tutoriales. Muchas man pages son duras de leer, pero pienso que el gran premio a la dificultad tiene que ir a la man page de bash. Cuando estaba haciendo mi investigación para este libro, revisé muy cuidadosamente que estaba cubriendo la mayoría de los temas. Cuando la imprimí, eran alrededor de 80 páginas extremadamente densas, y su estructura no tenían absolutamente ningún sentido para un usuario nuevo.


Por otra parte, es muy precisa y concisa, además de ser extremadamente completa. Así que échale un vistazo si te atreves y imagínate el día en que puedas leerla y tenga sentido.

info – Muestra un archivo de información de un programa

El Proyecto GNU proporciona una alternativa a las man pages para sus programas, llamada “info.” Las páginas info se muestran con un programa lector llamado, muy apropiadamente, info. Las páginas info están hyperenlazadas como las páginas web. Aquí tenemos un ejemplo:

File: coreutils.info, Node: ls invocation, Next: dir invocation,
Up: Directory listing


10.1 `ls': List directory contents
==================================


The `ls' program lists information about files (of any type, including directories). Options and file arguments can be intermixed arbitrarily, as usual.


For non-option command-line arguments that are directories, by default `ls' lists the contents of directories, not recursively, and omitting files with names beginning with `.'. For other non-option arguments, by default `ls' lists just the filename. If no non-option argument is specified, `ls' operates on the current directory, acting as if it had been invoked with a single argument of `.'.


By default, the output is sorted alphabetically, according to the --zz-Info: (coreutils.info.gz)ls invocation, 63 lines –Top----------

El programa info lee archivos info, que tienen una estructura de árbol con nodos individuales, cada uno de los cuales contiene un asunto concreto. Los archivos info contienen hipervínculos que permiten movernos de un nodo a otro. Un hipervínculo puede identificarse por su asterisco delante, y se activa colocando el cursor encima y presionando la tecla enter.

Para invocar a info, escribe “info” seguido opcionalmente del nombre de un programa. A continuación tienes una lista de comandos usados para controlar el lector mientras muestra una página info:



?               
Muestra la ayuda de un comando 

PgUp o Borrar   
Muestra la página previa 

PgDn o Espacio  

Muestra la siguiente página 

n Siguiente –   

Muestra el siguiente nodo

p Previo –      


Muestra el nodo anterior
u Up –          


Muestra el nodo padre del nodo mostrado actualmente, normalmente un menú
Enter           
Sigue el hipervínculo que está bajo el cursor 

q               
Salir
La mayoría de los programas de la línea de comandos que hemos visto hasta ahora son parte del paquete “coreutils” del Proyecto GNU, así que escribiendo:

 [me@linuxbox ~]$ info coreutils

mostrará una página con un menú con hipervínculos a cada programa contenido en el paquete coreutils.

Creando tus propios comandos con alias

Ahora ¡para nuestra primera experiencia con la programación! crearemos un comando propio usando el comando alias. Pero antes de empezar, necesitamos desvelar un pequeño truco de la línea de comandos. Es posible poner más de un comando en una línea separando cada comando con un punto y coma. Funciona así:

 comando1; comando2; comando3...

Aquí tenemos el ejemplo que usaremos:

 [me@linuxbox ~]$ cd /usr; ls; cd -
 bin games kerberos lib64 local share tmp
 etc include lib libexec sbin src
 /home/me
 [me@linuxbox ~]$

Como podemos ver, hemos combinado tres comandos en una línea. Primero hemos cambiado el directorio a /usr luego hemos listado el directorio y finalmente hemos vuelto al directorio original (usando 'cd -') con lo que hemos terminado donde empezamos. Ahora convirtamos esta secuencia en un nuevo comando usando alias. La primera cosa que tenemos que hacer es inventarnos un nombre para nuestro nuevo comando. Probemos “test”. Antes de hacerlo, sería una buena idea averiguar si el nombre “test” ya está siendo usado. Para averiguarlo, podemos usar el comando type de nuevo:

 [me@linuxbox ~]$ type test
 test is a shell builtin

Ups! El nombre “test” ya existe. Probemos “foo”:

 [me@linuxbox ~]$ type foo
 bash: type: foo: not found

¡Genial! “foo” no está. Así que creemos nuestro alias:

 [me@linuxbox ~]$ alias foo='cd /usr; ls; cd -'

Fíjate en la estructura de este comando:

 alias name='string'

Tras el comando “alias” le damos a alias un nombre seguido inmediatamente (si espacio en blanco) por un signo igual, seguido inmediatamente por una cadena entre comillas simples conteniendo los comandos que se asignarán al nombre. Después de definir nuestro alias, puede ser usado donde quiera que el shell acepte comandos. Probemos:

 [me@linuxbox ~]$ foo
 bin games kerberos lib64 local share tmp
 etc include lib libexec sbin src
 /home/me
 [me@linuxbox ~]$

También podemos usar el comando type de nuevo para ver nuestro alias:

 [me@linuxbox ~]$ type foo
 foo is aliased to `cd /usr; ls ; cd -'

Para eliminar un alias, se usa el comando unalias, así:


 [me@linuxbox ~]$ unalias foo
 [me@linuxbox ~]$ type foo
 bash: type: foo: not found

Aunque evitamos a propósito nombrar nuestro alias con un nombre de comando existente, no es raro que se haga. A menudo se hace para aplicar una opción que se utilice a menudo en cada invocación de un comando común. Por ejemplo, vimos antes que el comando ls a menudo es un alias con soporte para colores:

 [me@linuxbox ~]$ type ls
 ls is aliased to `ls –color=tty'

Para ver todos los alias definidos en nuestro entorno, utiliza el comando alias sin argumentos. Aquí tienes algunos de los alias definidos por defecto en un sistema Fedora. Pruébalo e imagina para que sirve cada uno:

 [me@linuxbox ~]$ alias
 alias l.='ls -d .* --color=tty'
 alias ll='ls -l --color=tty
 alias ls='ls –color=tty'

Hay un pequeño problema con la definición de alias en la linea de comandos. Se esfuman cuando la sesión de shell se cierra. En próximos capítulos, veremos como añadir nuestros alias a archivos que establecen el entorno cada vez que nos logueamos, pero por ahora, disfruta del hecho de que hemos dado nuestro primer paso, aunque sea pequeño, ¡en el mundo de la programación en shell!


Resumiendo

Ahora que hemos aprendido como encontrar documentación sobre los comandos, échale un vistazo a la documentación de todos los comandos que hemos visto hasta ahora. Estudia que opciones adicionales están disponibles y ¡prúebalas!

Para saber más


Hay muchas fuentes de documentación online para Linux y la línea de comandos. Aquí tienes algunas de las mejores:

  • El Bash FAQ contiene respuestas a preguntas frecuentes sobre bash. Esta lista está dirigida usuarios de intermedios a avanzados, pero contiene un montón de buena información.
    http://mywiki.wooledge.org/BashFAQ
  • El Proyecto GNU provee una extensa documentación para sus programas, los cuales forman el corazón de la experiencia con la linea de comandos de Linux. Puedes ver una lista completa aquí:
    http://www.gnu.org/manual/manual.html

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.