████████ ██ ██ ██████ ████████ ██░░░░░░ ░██ ░██ ░█░░░░██ ██░░░░░░██ ░██ ░██ ██████ █████ ░██ ██ ███ ██ ██████ ██████ █████ ░█ ░██ ██ ░░ ░█████████ ░██ ░░░░░░██ ██░░░██░██ ██ ░░██ █ ░██ ░░░░░░██ ░░██░░█ ██░░░██ ░██████ ░██ ░░░░░░░░██ ░██ ███████ ░██ ░░ ░████ ░██ ███░██ ███████ ░██ ░ ░███████ ░█░░░░ ██░██ █████ ░██ ░██ ██░░░░██ ░██ ██░██░██ ░████░████ ██░░░░██ ░██ ░██░░░░ ██░█ ░██░░██ ░░░░██ ████████ ███░░████████░░█████ ░██░░██ ███░ ░░░██░░████████░███ ░░██████░██░███████ ░░████████ ░░░░░░░░ ░░░ ░░░░░░░░ ░░░░░ ░░ ░░ ░░░ ░░░ ░░░░░░░░ ░░░ ░░░░░░ ░░ ░░░░░░░ ░░░░░░░░Mirrors for Slackware and some Slackware related projects.
Capítulo 6
Trabajando con Unix
A UNIX saleslady, Lenore,
Enjoys work, but she likes the beach more.
She found a good way
To combine work and play:
She sells C shells by the seashore.
Unix es un potente sistema para aquellos que saben cómo dominar su poder. En este capítulo, intentaré describir varias maneras de usar el shell de Unix, bash, más eficientemente.
6.1 Comodines
En el capítulo anterior, se enseñaron los comandos para mantener ficheros cp, mv, y rm. A veces, se querrá tratar con más de un fichero a la vez, en realidad, con muchos a la vez. Por ejemplo, se quiere copiar todos los ficheros que empiecen por data en un directorio llamado /backup. Se podría hacer esto ejecutando muchos comandos cp, o escribiendo cada fichero en una línea de comando. Estos dos métodos llevan mucho tiempo, incluso, se tienen muchas posibilidades de cometer errores.
Una buena manera de hacer este trabajo es teclear:
/home/larry/report$ ls -F
1993-1 1994-1 data1 data5
1993-2 data-new data2
/home/larry/report$ mkdir ~/backup
/home/larry/report$ cp data* ~/backup
/home/larry/report$ ls -F ~/backup
data-new data1 data2 data5
/home/larry/report$
Como se puede observar, el asterisco indica a cp que tome todos los ficheros que empiecen por data y los copie a /backup. ¿Qué cree que "cp d*w /backup" puede haber hecho?
6.1.1 ¿Qué ocurre realmente?
Buena pregunta. De hecho, hay un par de caracteres especiales interceptados por el shell, bash. El carácter "*" , un asterisco, dice "cambia esta palabra con todos los ficheros que se ajusten a esta especificación". Así, el comando "cp data* /backup" , como el de arriba, cambia a "cp data-new data1 data2 data5 /backup" antes de ejecutarse.
Para ilustrar esto, introduciré un comando nuevo, echo. echo es un comando extremadamente simple; repite, o muestra, cualquier parámetro. De este modo:
/home/larry$ echo Hola!
Hola!
/home/larry$ echo Como se encuentra?
Como se encuentra?
/home/larry$ cd report
/home/larry/report$ ls -F
1993-1 1994-1 data1 data5
1993-2 data-new data2
/home/larry/report$ echo 199*
1993-1 1993-2 1994-1
/home/larry/report$ echo *4*
1994-1
/home/larry/report$ echo *2*
1993-2 data2
/home/larry/report$
Como se puede ver, el shell expande el comodín y pasa todos los ficheros al programa que se va a ejecutar. Esto plantea una pregunta interesante: ¿qué ocurre si no hay ficheros que se ajusten a la especificación del comodín? Pruebe "echo /rc/fr*og" y bash pasará literalmente la especificación del comodín al programa.
Otros shells, como tcsh, en vez de pasar el comodín literalmente, contestarán No match. Aquí está el mismo comando ejecutado bajo tcsh:
mousehouse>echo /rc/fr*og
echo: No match.
mousehouse>
La última pregunta que podría hacerse es, ¿qué pasa si quisiera mostrar data*, en vez de la lista de nombres? Bien, tanto en bash como en tcsh, sólo se debe incluir la cadena entre comillas:
/home/larry/report$ echo "data*" mousehouse>echo "data*"
data* Ó bien data*
/home/larry/report$ mousehouse>
6.1.2 El signo de interrogación
Además del asterisco, el shell también interpreta un signo de interrogación como un carácter especial.
Un signo de interrogación coincidirá con un carácter, y sólo uno. Por ejemplo, "ls /etc/*
*??" mostrará todos los ficheros de dos letras en el directorio /etc.
6.2 Ganar tiempo con bash
6.2.1 Editando la línea de comandos
A veces, escribe un comando largo a bash y, antes de pulsar |_Intro_|, se da cuenta de que ha cometido un error al escribirlo. Se puede simplemente borrar todo y volver a teclear correctamente, pero ¡es demasiado esfuerzo! En cambio, se pueden usar las flechas para moverse, borrar el/los carácter/es incorrecto/s, y escribir la información correctamente.
Hay muchas teclas especiales que ayudan a editar la línea de comandos, muchas de ellas similares a los comandos usados en GNU Emacs. Por ejemplo, |_C-t_| intercambia dos carácteres adyacentes1.
Se pueden encontrar muchos de los comandos en el capítulo sobre Emacs, Capítulo 8.
6.2.2 Completamiento de comandos y nombres de fichero
Otra peculiaridad de bash es la ejecución automática de las líneas de comando. Por ejemplo, veamos el siguiente ejemplo de un comando cp típico:
/home/larry$ ls -F
esto-es-un-fichero-largo
/home/larry$ cp esto-es-un-fichero-largo corto
/home/larry$ ls -F
corto esto-es-un-fichero-largo
/home/larry$
Es una gran molestia tener que teclear cada letra de esto-es-un-fichero-largo cada vez que se quiere acceder a él, sucede lo mismo si queremos crear esto-es-un-fichero-largo copiando en él /etc/passwd2. Ahora, aprenderemos a escribir el anterior comando cp más rápidamente y con menos posibilidad de error.
En vez de teclear el nombre del fichero entero, se escribe "cp es" , se pulsa y suelta la tecla |_Tab_|. Por arte de magia, el resto del nombre del fichero aparece en la línea de comandos, y se puede escribir corto. Desgraciadamente, bash no pude leer los pensamientos, por lo que se debe teclear corto.
Cuando se pulsa |_Tab_|, bash mira lo que hay escrito y busca un fichero que empiece como eso. Por ejemplo, si tecleo /usr/bin/ema y luego pulso |_Tab_|, bash encontrará /usr/bin/emacs ya que es el único fichero que empieza por /usr/bin/ema en mi sistema. En cambio, si tecleo /usr/bin/ld y pulso |_Tab_|, bash me avisará. Eso es porque tres ficheros, /usr/bin/ld, /usr/bin/ldd, y /usr/bin/ld86 empiezan por /usr/bin/ld en mi sistema.
Si se intenta un completamiento y bash avisa, se puede pulsar inmediatamente |_Tab_| otra vez para conseguir una lista de todos los ficheros que coincidan con el patrón. De este modo, si no se está seguro del nombre exacto del fichero, podemos teclear los primeros caracteres del nombre y buscarlo en una lista más pequeña de ficheros.
______________________________________________
1 |_C-t_|significa mantener pulsada la tecla marcada como "Ctrl", y apretar la tecla "t". Luego soltar ambas.
2 "cp /etc/passwd esto-es-un-fichero-largo"
6.3 La entrada estándar y La salida estándar
Intentemos abordar un problema simple: conseguir un listado del directorio /usr/bin. Si hacemos "ls /usr/bin" , algunos de los nombres de los ficheros saldrán por arriba de la pantalla. ¿Como se pueden ver todos los ficheros?
6.3.1 Algunos conceptos de Unix
El sistema operativo Unix facilita mucho a los programas el uso del terminal. Cuando un programa escribe algo en la pantalla, está usando algo llamado salida estándar. Salida estándar, en inglés standard output o stdout, es la manera que tiene el programa de escribirle cosas al usuario. El nombre por el que se indica un programa es entrada estándar (stdin). Es posible que un programa se comunique con el usuario sin usar la entrada o salida estándar, pero la mayoría de los comandos que se tratan en este libro usan stdin y stdout.
Por ejemplo, el comando ls imprime una lista de los directorios en la salida estándar, que está normalmente "conectada" al terminal. Un comando interactivo, como el shell, bash, lee los comandos de la entrada estándar.
Un programa también puede escribir en el error estándar, ya que es muy fácil hacer que la salida estándar apunte a cualquier lugar aparte del terminal. El error estándar (stderr) está casi siempre conectado al terminal para que alguna persona pueda leer el mensaje.
En esta sección, examinaremos tres modos de enredarse con la entrada y salida estándar: redireccionar la salida, redireccionar la entrada, y las tuberías.
6.3.2 Redireccionar la salida
Un aspecto muy importante de Unix es la posibilidad de redireccionar la salida. Esto permite que, en vez de ver los resultados de un comando, los salvemos en un fichero o los enviemos directamente a una impresora. Por ejemplo, para redireccionar la salida del comando "ls /usr/bin", se coloca un signo ">" al final de la línea, y se indica el fichero donde dejar la salida:
/home/larry$ ls
/home/larry$ ls -F /usr/bin > listado
/home/larry$ ls
listado
/home/larry$
Como se puede ver, en vez de escribir los nombres de todos los ficheros, el comando crea un fichero totalmente nuevo en el directorio actual. Echemos un vistazo a este fichero usando el comando cat.
Si se recuerda, cat era un comando bastante inútil que copiaba lo que se escribía (entrada estándar) al terminal (salida estándar). cat también imprime un fichero en la salida estándar si se indica el fichero como parámetro:
/home/larry$ cat listado
..
/home/larry$
La salida exacta del comando "ls /usr/bin" aparece en el contenido de listado. Por ahora todo bien, sin embargo no resuelve el problema original.3
A pesar de todo, cat hace algunas cosas interesantes cuando se redirecciona su salida. ¿Qué hace el comando "cat listado > fichero"? Normalmente, el "> fichero" dice "coge toda la salida del comando y ponla en fichero". La salida del comando "cat listado" es el fichero listado. Así hemos inventado un nuevo (y no tan eficiente) método de copiar ficheros.
¿Qué ocurre con el comando "cat > zorro" ? cat lee cada línea escrita en el terminal (entrada estándar) y la imprime de vuelta (salida estándar) hasta que lee |_Ctrl-d_|. En este caso, la salida estándar se ha redireccionado al fichero zorro. Ahora cat sirve como un editor rudimentario:
/home/larry$ cat > zorro
El rapido zorro marron salta sobre el descuidado perro.
pulsa Ctrl-d
Ahora se ha creado el fichero zorro que contiene la frase "El rapido zorro marron salta sobre el descuidado perro". Un último uso del versátil comando cat es concatenar ficheros. cat imprimirá cada fichero dado como parámetro, uno despues de otro. El comando "cat listado zorro" imprimirá el listado del directorio /usr/bin, y luego la tonta frase. Así, el comando "cat listado zorro > listyzorro" creará un nuevo fichero conteniendo los contenidos de listado y zorro.
6.3.3 Redireccionar la entrada
Así como cuando se redirecciona la salida estándar, es posible redireccionar la entrada. En lugar de que un programa lea su entrada desde el teclado, la leerá desde un fichero. Como redireccionar la entrada está relacionado con redireccionar la salida, parece natural que "<" sea el carácter para redireccionar la entrada. Éste también se usa después del comando que se desee ejecutar.
Esto es generalmente útil si se tiene un fichero de datos y un comando que espera sus datos desde la entrada estándar. Muchos comandos permiten especificar un fichero sobre el cual operar, así que en las actividades diarias el "<" no se usa tanto como otras técnicas.
6.3.4 Las tuberías
Muchos comandos Unix producen gran cantidad de información. Por ejemplo, es normal que un comando como "ls /usr/bin" produzca más salida que la que se puede ver en pantalla. Para que se pueda ver toda la información de un comando como "ls /usr/bin" , es necesario usar otro comando Unix llamado more4. more parará cada vez que la pantalla se llene de información. Por ejemplo, "more < /etc/rc" mostrará el fichero /etc/rc como lo haría "cat /etc/rc" , excepto que more permite leerlo. more también admite el comando "more /etc/rc" , y esa es la forma normal de invocarlo.
_____________________________________________
3 Para lectores impacientes, el comando que se debe usar es more. Sin embargo, hay que hablar un poco sobre algo más antes de llegar ahí.
4 Se llama more porque ese es el indicador que originalmente mostraba: "--more--". En varias versiones de Linux el comando more es identico a un comando más avanzado que hace todo lo que more puede hacer y más aún. Como demostración de que los programadores de ordenadores son malos cómicos, llamaron a este nuevo programa "less".
Sin embargo, eso no ayuda al problema de que "ls /usr/bin" muestre más información de la que se pueda ver. "more < ls /usr/bin" no funciona, ¡la redirección de entrada sólo funciona con ficheros, no comandos! Se podría hacer esto:
/home/larry$ ls /usr/bin > temp-ls
/home/larry$ more temp-ls
..
/home/larry$ rm temp-ls
Pero, Unix propone una forma más limpia de hacerlo. Se puede usar el comando "ls /usr/bin _ more". El carácter "_" es una tubería. Como una tubería de agua, una tubería Unix controla el flujo. En vez de agua, se controla el flujo de información.
Los filtros son programas muy útiles para usarse en conjunción con las tuberías. Un filtro es un programa que lee la entrada estándar, la cambia de alguna manera, y la saca por la salida estándar.
more es un filtro, lee los datos que coge de la entrada estándar y los muestra por la salida estándar pantalla a pantalla, permitiendo leer el fichero. more no es un gran filtro porque su salida no se puede enviar a otro programa.
Otros filtros incluyen los programas cat, sort, head, y tail. Por ejemplo, si se quiere leer sólo las primeras diez líneas de la salida de ls, se puede usar "ls /usr/bin _ head" .
6.4 Multitarea
6.4.1 Usando el control de trabajos
Control de trabajos se refiere a la habilidad de poner procesos (esencialmente, otra palabra para programas) en background (segundo plano) y ponerlos de vuelta en foreground (primer plano).
Esto es como decir, que se quiere ser capaz de ejecutar algo mientras se hacen otras cosas, pero que estén ahí otra vez cuando se les quiera decir algo o pararlos. En Unix, la principal herramienta para el control de procesos es el shell, seguirá la pista de los procesos por usted, si se aprende como hablar su lenguaje.
Las dos palabras más importantes en ese lenguaje son fg, para primer plano, y bg, para segundo plano. Para entender como funcionan, use el comando yes en el indicador del sistema.
/home/larry$ yes
Esto produce el maravilloso efecto de desplazar una larga columna de yes por la parte izquierda de la pantalla, tan rápido que no se pueden seguir5. Para pararlo, se podría pulsar |_Ctrl-c_| y matarlo, pero esta vez Ud. oprimirá |_Ctrl-z_|. Parece haberse detenido, pero habrá un mensaje antes del indicador de sistema, más o menos parecido a este:
[1]+ Stopped yes
_____________________________________________
5 Hay buenas razones para que este extraño comando exista. Ciertos comandos esperan una confirmación, un "si" ([y]es en inglés) a una pregunta. El comando yes permite al programador automatizar la respuesta a esas preguntas.
Significa que el trabajo yes se ha suspendido en el segundo plano. Se puede hacer que siga ejecutándose tecleando fg en el indicador de sistema, que lo pondrá en primer plano otra vez. Si se desea, se pueden hacer otras cosas antes, mientras está suspendido. Pruebe unos cuantos ls o algo antes de ponerlo en primer plano nuevamente.
Una vez que ha vuelto al primer plano, las yes empezarán a salir otra vez, tan rápido como antes.
No hay que preocuparse de que si mientras ha estado suspendido ha "almacenado" más yes para enviarlas a la pantalla: cuando un trabajo se suspende, el programa entero no se ejecuta hasta que se lo vuelva de vuelta a la vida. (Ahora pulse |_Ctrl-c_| para matarlo de veras).
Pongamos aparte el mensaje que obtuvimos del shell:
[1]+ Stopped yes
El número entre corchetes es el número de trabajo de este proceso, y se usará cuando se necesite referenciarlo específicamente. (Naturalmente, desde el momento que tengamos en ejecución múltiples trabajos, se necesita un modo de acceder a cada uno). El "+" siguiente indica que ése es el "trabajo actual", esto es, el proceso más reciente que se ha movido del primer plano al segundo.
Si se tecleara "fg" , se pondría el trabajo con el "+" en primer plano otra vez. (Más sobre esto después, cuando se discuta la ejecución de múltiples trabajos a la vez). La palabra Stopped significa que el trabajo está "parado". El trabajo no está muerto, pero actualmente no se ejecuta. Linux lo ha guardado en un estado especial de suspendido, listo para saltar a la acción cuando alguien lo solicite. Finalmente, el yes es el nombre del trabajo que se ha detenido.
Antes de seguir adelante, matemos este trabajo y lo arrancamos otra vez de forma diferente. El comando se llama kill y se usa del siguiente modo:
/home/larry$ kill %1
[1]+ Stopped yes
/home/larry$
Ese mensaje sobre el proceso que indica "parado" otra vez induce a error. Para saber si aún está vivo (eso es, tanto en ejecución como congelado en un estado suspendido), teclee "jobs":
/home/larry$ jobs
[1]+ Terminated yes
/home/larry$
Ahora ya lo sabe: ¡el trabajo ha terminado! (Es posible que el comando jobs no muestre nada, lo que simplemente significa que no hay trabajos ejecutándose en segundo plano. Si se acaba de matar un trabajo, y al teclear jobs no muestra nada, se tiene la seguridad de que el comando kill se ha ejecutado correctamente. Normalmente indicará que el trabajo ha "terminado").
Ahora, ejecute yes de nuevo, de esta forma:
/home/larry$ yes > /dev/null
Si lee la sección sobre la redirección de entrada y salida, sabrá que se está enviando la salida de yes a un fichero especial llamado /dev/null. /dev/null es un agujero negro que come cualquier salida que se le envíe (se puede imaginar ese torrente de yes saliendo por detrás del ordenador y perforando un agujero en la pared, si eso le hace feliz).
Después de teclear esto, no se recuperará el indicador de sistema, pero tampoco saldrá esa columna de yes. Sin embargo la salida se está enviando a /dev/null, el trabajo aún se ejecuta en primer plano. Como siempre, se puede suspender pulsando |_Ctrl-z_|. Hágalo ahora para volver al indicador del sistema.
/home/larry$ yes > /dev/null
["yes" se ejecuta, y solamente se ha pulsado Ctrl-z]
[1]+ Stopped yes >/dev/null
/home/larry$
Hmm. . . ¿hay alguna forma de ponerlo en ejecución en segundo plano, mientras deja el indicador del sistema para trabajar de forma interactiva? El comando para hacer eso es bg:
/home/larry$ bg
[1]+ yes >/dev/null &
/home/larry$
Ahora, deberá tener confianza en mí sobre esto: después de teclear bg, el trabajo "yes > /dev/null" habrá continuado con su ejecución otra vez, pero esta vez en segundo plano. De hecho, si hace alguna cosa en el prompt, como ls u otros, se dará cuenta que su máquina se ha ralentizado un poco (¡generar y descargar continuamente una cadena preparada de "yes" lleva algo de tiempo, al fin y al cabo!) Aparte de esto, no hay ningún otro efecto. Se puede hacer lo que se desee en el indicador del sistema, y yes continuará felizmente enviando su salida al agujero negro.
Ahora hay dos formas diferentes de matarlo: con el comando kill que ya se explicó, o poniendo el trabajo en primer plano de nuevo e interrumpirlo con una interrupción, |_Ctrl-c_|. Probemos la segunda forma, sólo para entender la relación entre fg y bg un poco mejor;
/home/larry$ fg
yes >/dev/null
[ahora esta en primer plano. Imagine que pulso Ctrl-c para terminarlo]
/home/larry$
Bueno, se acabó. Ahora, ejecute unos cuantos trabajos simultáneamente, como estos:
/home/larry$ yes > /dev/null &
[1] 1024
/home/larry$ yes _ sort > /dev/null &
[2] 1026
/home/larry$ yes _ uniq > /dev/null
[y aqui, pulse Ctrl-z para suspenderlo, por favor]
[3]+ Stopped yes _ uniq >/dev/null
/home/larry$
La primera cosa que le debe llamar la atención de estos comandos es la terminación "&" al final de los dos primeros. Poner un "&" después del comando indica al shell que los ejecute en segundo plano desde el principio. (Es una forma de evitarse tener que ejecutar el programa, pulsar |_Ctrl-z_|, y luego teclear "bg" .) Así, estos dos comandos han empezado a ejecutarse en segundo plano. El tercero está suspendido e inactivo en este momento. Se puede dar cuenta de que la máquina se ha vuelto más lenta, ya que los que se están ejecutando requieren un poco de tiempo de CPU.
Cada uno indica su número de trabajo. Los dos primeros también muestran sus números de identificación de proceso, o PID, después del número de trabajo. Los PIDs normalmente no son algo que se necesite conocer, pero a veces viene bien.
Matemos el segundo, ya que creo que está ralentizando su máquina. Se puede teclear "kill %2", pero eso sería demasiado fácil. Por el contrario, haga esto:
/home/larry$ fg %2
yes _ sort >/dev/null
[pulse Ctrl-c para matarlo]
/home/larry$
Como esto demuestra, fg toma parámetros empezando con "%" . De hecho, se podría teclear sólo esto:
/home/larry$ %2
yes _ sort >/dev/null
[pulse Ctrl-c para matarlo]
/home/larry$
Esto funciona por que el shell automáticamente interpreta un número de trabajo como una petición para poner ese trabajo en primer plano. Se puede indicar los números de trabajo con otros números precedidos por un "%". Ahora teclee "jobs" para ver cuáles trabajos quedan en ejecución:
/home/larry$ jobs
[1]- Running yes >/dev/null &
[3]+ Stopped yes _ uniq >/dev/null
/home/larry$
El "-" indica que ese trabajo número 1 es segundo en la lista para ser puesto en el primer plano, si sólo se teclea "fg" sin dar parámetros. El "+" indica que el trabajo especificado es el primero en la lista un "fg" sin parámetros pondrá al trabajo número 3 en el primer plano. Sin embargo, se puede acceder a él llamándolo, si se desea, mediante:
/home/larry$ fg %1
yes >/dev/null
[ahora pulse Ctrl-z para suspenderlo]
[1]+ Stopped yes >/dev/null
/home/larry$
Al cambiar al trabajo número 1 y luego suspenderlo han cambiado las prioridades de todos los trabajos de usuario. Esto se puede ver con el comando jobs:
/home/larry$ jobs
[1]+ Stopped yes >/dev/null
[3]- Stopped yes _ uniq >/dev/null
/home/larry$
Ahora los dos están parados (porque los dos se han suspendido con |_Ctrl-z_|), y el número 1 es el siguiente en la lista a entrar en el primer plano por defecto. Esto es así porque se le puso en el primer plano manualmente, y luego fue suspendido. El "+" siempre se refiere al trabajo más reciente que ha sido suspendido del primer plano. Se puede continuar con su ejecución otra vez:
/home/larry$ bg
[1]+ yes >/dev/null &
/home/larry$ jobs
[1]- Running yes >/dev/null
[3]+ Stopped yes _ uniq >/dev/null
/home/larry$
Fíjese que ahora está en ejecución, y el otro trabajo se ha movido en la lista y tiene el "+". Ahora matémoslos para que el sistema no esté permanentemente ralentizado por procesos que no hacen nada.
/home/larry$ kill %1 %3
[3] Terminated yes _ uniq >/dev/null
/home/larry$ jobs
[1]+ Terminated yes >/dev/null
/home/larry$
Aparecerán varios mensajes sobre la terminación de los trabajos, nada muere tranquilamente, al parecer. La figura 6.1 de la página 59 muestra un breve resumen de lo que se debe saber acerca del control de trabajos.
6.4.2 Teoría del control de trabajos
Es importante entender que el control de procesos lo hace el shell. No hay ningún programa en el sistema llamado fg; por eso, fg, bg, &, jobs, y kill son internos al shell6. (A veces kill es un programa independiente; en el shell bash usado por Linux pertenece al shell). Esto es una forma lógica de hacerlo: ya que cada usuario quiere su propio espacio de control de trabajos, y cada usuario ya tiene su propio shell, es más fácil que el shell siga la pista de los trabajos usuario. Por otro lado, cada número de trabajo de usuario sólo tiene significado para ese usuario: mi trabajo número [1] y su trabajo número [1] son probablemente dos procesos totalmente diferentes. De hecho, si se está conectado más de una vez, cada uno de los shells tendrá datos únicos sobre el control de trabajos, así como también un usuario puede tener dos trabajos diferentes con el mismo número ejecutándose en dos shells diferentes.
_____________________________________________
6 N. del T.: En el original pone "shell-builtins", eso es que se compilan dentro del shell.
La manera segura de referenciarlos es usar el número IDentificador de Proceso (PID). Estos números abarcan todo el sistema, cada proceso tiene su propio (y único) número. Dos usuarios diferentes pueden referenciar un proceso por su PID y saber que están hablando sobre el mismo proceso (¡asumiendo que están conectados en la misma máquina!).
Echémosle un vistazo a un comando más para entender que son los PIDs. El comando ps lista todos los procesos en ejecución, incluyendo el shell. Pruébelo. Tiene también unas cuantas opciones, de las cuales las más importantes (para mucha gente) son "a" , "u" , y "x" . La opción "a" lista los procesos pertenecientes a algún usuario, no sólo los suyos propios. La "x" lista los procesos que no tienen un terminal asociado a ellos7. Finalmente, la "u" da información adicional sobre los procesos que es frecuentemente útil.
Para hacerse una idea de lo que realmente está haciendo el sistema, se ponen todos juntos: "ps -aux" . Se pueden ver los procesos que usan más memoria mirando la columna %MEM, y más CPU mirando a la columna %CPU. (La columna TIME lista la cantidad total de tiempo de CPU usado).
Otra nota rápida sobre los PIDs. kill, aparte de tomar opciones de la forma %no_trabajo, toma opciones de los PIDs en crudo. Esto es, si pone un "yes > /dev/null" en segundo plano, se ejecuta "ps" , y se busca el yes. Luego se teclea "kill PID" 8 .
Si empieza a programar en C con su sistema Linux, pronto aprenderá que el control de trabajos del shell es sólo una versión interactiva de las llamadas a las funciones fork y execl. Esto es demasiado complejo para explicarlo aquí, pero sería útil recordarlo después cuando se esté programando y se quieran ejecutar múltiples procesos desde un simple programa.
6.5 Consolas virtuales: como estar en varios lugares a la vez
Linux soporta consolas virtuales. Son una manera de hacer que su simple máquina aparezca como múltiples terminales, todos conectados al mismo núcleo Linux. Por fortuna, usar las consolas virtuales es una de las cosas más simples en Linux: hay "hot keys"9 para cambiar entre las consolas rápidamente. Para probarlo, hay que conectarse al sistema, pulsar la tecla |_Alt_| izquierda, y pulsar |_F2_| (esto es, la tecla de función número 2)10 11.
_____________________________________________
7 Esto sólo tiene sentido para ciertos programas que no tienen que hablar con el usuario a través del teclado.
8 En general, es más fácil matar el número del trabajo en vez de usar PIDs.
9 N.T.: No he creido apropiado traducir este término, ya que muchos usuarios saben a lo que se refiere. De todas formas para el que no lo sepa, esto es, una simple combinación de teclas que hace un cierto trabajo.
Se encontrará con otro indicador para conectarse. No se alarme: ahora está en la consola virtual (VC) número 2. Conéctese y haga algunas cosas, unos cuantos ls o lo que sea, para confirmar que es un shell real. Ahora puede volver a la VC número 1, pulsando el |_Alt_| izquierdo y |_F1_|. O se puede mover a una tercera VC, de la forma obvia (|_Alt-F3_|).
Generalmente los sistemas Linux vienen con cuatro VC activadas por defecto. Esto se puede incrementar a ocho; estos temas se cubrirán en The Linux System Administrator's Guide. Ello implica editar uno o dos ficheros en el directorio /etc. Sin embargo, cuatro deben ser suficientes para la mayoría de las personas.
Una vez las haya usado, las VC probablemente se convertirán en una herramienta indispensable para tener varias cosas ejecutándose a la vez. Por ejemplo, yo normalmente ejecuto Emacs en la VC 1 (y hago la mayor parte de mi trabajo ahí), mientras tengo un programa de comunicaciones en la VC 3 (así puede coger o dejar ficheros via modem mientras trabajo, o ejecutar programas en máquinas remotas), y mantengo un shell en la VC 2 sólo en caso de que tenga que ejecutar algo sin involucrar a la VC 1.
_____________________________________________
10 Hay que asegurarse de que esto se hace desde consolas en modo texto: si se está ejecutando X Window u otra aplicación gráfica, probablemente no funcionará, sin embargo corre el rumor de que pronto se podrá cambiar entre las consolas virtuales en X Window de Linux.
11 N. del T.: De hecho al momento de la traducción, la combinación es |_Ctrl-Alt-tecla-de-función_|.
Figura 6.1 Resumen de comandos y teclas usados para el control de trabajos.
Comando |
Explicación |
fg %nº_trabajo |
Este es un comando del shell que devuelve un trabajo al primer plano. Para saber cuál es éste por defecto, se teclea "jobs" y se busca el que tiene el +. Parámetros: número de trabajo opcional. El trabajo por defecto se identifica con el +. |
& |
Cuando se añade un & al final de la línea de comandos, indica al comando que se ejecute en segundo plano automáticamente. Este trabajo está entonces sujeto a todos los métodos usuales para el control de trabajos aquí detallados. |
bg %nº_trabajo |
Este es un comando del shell que manda a un trabajo suspendido ejecutarse en segundo plano. Para saber cual es éste por defecto, se teclea "jobs" y se busca el que tiene el +. Parámetros: número de trabajo opcional. El trabajo por defecto se identifica con el +. |
kill %nº_trabajo PID |
Este es un comando del shell que obliga a un trabajo en segundo plano, ya sea suspendido o en ejecución, a terminar. Se debe siempre especificar el número de trabajo o PID, y si se están usando números de trabajo, no hay que olvidar poner el %. Parámetros: El número de trabajo (a continuación del %) o el PID (no es necesario el %). Se puede especificar más de un proceso o trabajo en una línea. |
jobs |
Este comando del shell lista información sobre los trabajos que están en ese momento en ejecución o suspendidos. A veces también dice cuáles son los que acaban de salir o han terminado. |
|_Ctrl-c_| |
Este es el carácter genérico de interrupción. Normalmente, si se pulsa mientras un programa se está ejecutando en primer plano, matará al programa (puede que haya que hacerlo varias veces). Sin embargo, no todos los programas responderán a este método de terminación. |
|_Ctrl-z_| |
Esta combinación de teclas normalmente suspende un programa, puede que algunos programas lo ignoren. Una vez suspendido, el trabajo se puede reiniciar en el segundo plano o se puede matar. |