Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| tutorial_de_shell_de_bourne [2024/07/24 19:25] – [Tutorial de Shell (sh)] peron | tutorial_de_shell_de_bourne [2026/04/21 16:09] (actual) – editor externo 127.0.0.1 | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| - | =======Tutorial de Shell de Bourne | + | =======Tutorial de Shell de Bourne======== |
| - | Este tutorial histórico presenta algunos métodos y comandos que lo ayudarán a hacer expeditas las tareas diarias que se realizan con la shell sh de Bourne | + | |
| + | Este tutorial histórico presenta algunos métodos y comandos que lo ayudarán a hacer expeditas las tareas diarias que se realizan con el [[intérpretes | ||
| + | |||
| + | La primer sección de este tutorial " | ||
| - | La primer parte del tutorial " | ||
| ===== Lenguaje de Comandos de la Shell ====== | ===== Lenguaje de Comandos de la Shell ====== | ||
| El lenguaje de la shell tiene caracteres especiales que le ofrecen algunos atajos para realizar tareas en la shell. Estos caracteres especiales se listan abajo y se discuten en esta sección del tutorial. | El lenguaje de la shell tiene caracteres especiales que le ofrecen algunos atajos para realizar tareas en la shell. Estos caracteres especiales se listan abajo y se discuten en esta sección del tutorial. | ||
| - | + | Estos son //metacaracteres//. Un metacaracter es un caracter que tiene un significado especial en el lenguaje de comandos | |
| - | Estos son metacaracteres. Un metacaracter es un caracter que tiene un significado especial en el lenguaje de ocmandos | + | |
| ^ Metacaracter ^ Significado ^ | ^ Metacaracter ^ Significado ^ | ||
| Línea 15: | Línea 16: | ||
| | '';'' | | '';'' | ||
| | '' | | '' | ||
| - | | ''< | + | | ''< |
| ====Metacaracteres==== | ====Metacaracteres==== | ||
| - | El significado de los metacaracteres es similar a decir "etc, etc, etc", "todo lo anterior", | + | El significado de los metacaracteres es similar a decir "etc, etc, etc", "todo lo anterior", |
| ===*=== | ===*=== | ||
| - | '' | + | '' |
| El '' | El '' | ||
| Línea 82: | Línea 83: | ||
| El '' | El '' | ||
| - | </code> | + | < |
| $ ls F*E | $ ls F*E | ||
| - | </ | + | </ |
| Este comando hubiese listado los siguientes ficheros en orden | Este comando hubiese listado los siguientes ficheros en orden | ||
| Línea 92: | Línea 93: | ||
| FATE | FATE | ||
| FE | FE | ||
| - | </ | ||
| - | |||
| Fig3.4E | Fig3.4E | ||
| + | </ | ||
| ===?=== | ===?=== | ||
| Línea 119: | Línea 119: | ||
| Por supuesto, si desea listar todos los capítulos en el directorio actual, usaría '' | Por supuesto, si desea listar todos los capítulos en el directorio actual, usaría '' | ||
| - | > En ocasiones usa //mv// o //cp// con un fichero, | + | > En ocasiones usa //mv// o //cp// con un fichero, |
| Intente el siguiente ejemplo | Intente el siguiente ejemplo | ||
| - | -Haga un fichero corto llamado '' | + | - Escriba |
| - ingresa mv prueba prueba**^g**1 (recuerda que **^g** se hace con **Ctrl+g**) | - ingresa mv prueba prueba**^g**1 (recuerda que **^g** se hace con **Ctrl+g**) | ||
| - ls prueba1 | - ls prueba1 | ||
| - | te dara | + | le dara |
| < | < | ||
| Línea 133: | Línea 133: | ||
| </ | </ | ||
| - | ingresa | + | ingrese |
| <code bash>ls prueba? | <code bash>ls prueba? | ||
| - | te indicará | + | le indicará |
| - | <codeprueba1</ | + | <code> |
| === [...] === | === [...] === | ||
| Línea 155: | Línea 155: | ||
| </ | </ | ||
| - | La shell también buscará un rango de caracterers | + | La shell también buscará un rango de caracteres |
| <code bash> | <code bash> | ||
| Línea 171: | Línea 171: | ||
| El caracter ''&'' | El caracter ''&'' | ||
| - | Algunos comandos de shell requieren tiempo considerable para su cumplimiento. Es conveniente dejar que dichos comandos corran en //segundo plano// | + | Algunos comandos de shell requieren tiempo considerable para su cumplimiento. Es conveniente dejar que dichos comandos corran en //segundo plano// |
| <code bash> | <code bash> | ||
| Línea 177: | Línea 177: | ||
| </ | </ | ||
| - | El comando [[grep]] puede desarrollar búsquedas | + | El comando [[grep]] puede desarrollar búsquedas |
| <code bash> | <code bash> | ||
| $ grep palabra * & | $ grep palabra * & | ||
| - | 2190 | + | 21940 |
| $ | $ | ||
| </ | </ | ||
| Línea 191: | Línea 191: | ||
| ===;=== | ===;=== | ||
| - | El metacaracter '';'' | + | El metacaracter '';'' |
| - | Si desea tipear | + | Si desea introducir |
| <code bash> | <code bash> | ||
| Línea 199: | Línea 199: | ||
| </ | </ | ||
| - | La ejecución secuencial es muy útil cuando necesita ejecutar varios comandos de shell mientras se encuentra en el editor de líneas [[ed]]. Intente ingresar varios comandos separados por una '';'' | + | La ejecución secuencial es muy útil cuando necesita ejecutar varios comandos de shell mientras se encuentra en el editor de líneas [[ed]]. Intente ingresar varios comandos separados por una '';'' |
| <code bash> | <code bash> | ||
| Línea 205: | Línea 205: | ||
| </ | </ | ||
| - | La shell ejecutará los comandos | + | La shell ejecutará los comandos |
| - | -cd cambia al directorio de usuario | + | ^ Orden ^ Comando ^ Acción ^ |
| - | -pwd imprime el directorio actual | + | |1 |'' |
| - | -ls lista los ficheros en el directorio actual | + | |2 |'' |
| - | -ed prueba | + | |3 |'' |
| + | |4 |'' | ||
| - | Notó la rápida ráfaga de comandos. Podría no querer que estas veloces respuestas se presenten en su temrinal. La sección de [[# | + | ¿Notó |
| === \ === | === \ === | ||
| Línea 218: | Línea 219: | ||
| La barra invertida '' | La barra invertida '' | ||
| - | ¿Cómo busca uno de los caracteres especiales en un fichero? Ingrese una barra invertida justo antes de ingresar el metacaracter. La barra invertida desactiva el significado especial del siguiente metacaracter que ingrese. Cree un fichero llamado | + | ¿Cómo busca uno de los caracteres especiales en un fichero? Ingrese una barra invertida justo antes de ingresar el metacaracter. La barra invertida desactiva el significado especial del siguiente metacaracter que ingrese. Cree un fichero llamado |
| <code bash> | <code bash> | ||
| Línea 228: | Línea 229: | ||
| ===Desactivar caracteres especiales por Citado=== | ===Desactivar caracteres especiales por Citado=== | ||
| - | Todos los caracters | + | Todos los caracteres |
| Todos los caracteres entrecomillados ''< | Todos los caracteres entrecomillados ''< | ||
| - | Los metacaracteres en la shell pierden | + | Los metacaracteres en la shell pierden |
| - | Un delimitador separa argumentos, | + | Un //delimitador// separa argumentos, |
| - | El comando //banner// usa espacios | + | El comando //banner// usa los caracteres de espacio |
| <code bash> | <code bash> | ||
| Línea 308: | Línea 309: | ||
| - | Si usa apóstrofes en el argumento del comando grep, el espacio en blanco pierde su significado de delimitador. Puede buscar dos palabras. La linea '' | + | Si usa apóstrofes en el argumento del comando |
| <code bash> | <code bash> | ||
| $ grep 'de las' prueba | $ grep 'de las' prueba | ||
| Línea 316: | Línea 318: | ||
| Intenta desactivar el significado especial de caracter '' | Intenta desactivar el significado especial de caracter '' | ||
| + | |||
| <code bash> | <code bash> | ||
| grep ' | grep ' | ||
| Línea 322: | Línea 325: | ||
| </ | </ | ||
| - | ====Redirigid | + | ====Redirigir |
| - | La redirección de entrada y salida son herramientras importanets | + | La redirección de entrada y salida son herramientas importantes |
| ===Redirigir entrada=== | ===Redirigir entrada=== | ||
| Puede redirigir el texto de un fichero para que sea la entrada de un comando. | Puede redirigir el texto de un fichero para que sea la entrada de un comando. | ||
| - | El caracter ''<'' | + | El caracter ''<'' |
| - | El formato | + | La sintaxis |
| <code bash> | <code bash> | ||
| Línea 354: | Línea 357: | ||
| El caracter ''>'' | El caracter ''>'' | ||
| - | Un símbolo único de redirección creará un nuevo fichero, o borrará un fichero viejo y reemplazará sus contenidos con la nueva salida. | + | Un símbolo único de redirección creará un nuevo fichero, o borrará un fichero viejo y reemplazará sus contenidos con la nueva salida. |
| <code bash> | <code bash> | ||
| Línea 380: | Línea 383: | ||
| </ | </ | ||
| - | la shell borrará '' | + | la shell borrará '' |
| > Si redirige un comando en un fichero que ya existe, la shell __borrará__ el fichero existente y pondrá la salida del comando en dicho fichero. No se le dará advertencia alguna de que está borrando un nuevo fichero. Si desea asegurarse usted mismo que no es un fichero existente, recurra al comando //ls// con dicho nombre de fichero como argumento. | > Si redirige un comando en un fichero que ya existe, la shell __borrará__ el fichero existente y pondrá la salida del comando en dicho fichero. No se le dará advertencia alguna de que está borrando un nuevo fichero. Si desea asegurarse usted mismo que no es un fichero existente, recurra al comando //ls// con dicho nombre de fichero como argumento. | ||
| Línea 434: | Línea 437: | ||
| Si dos comandos o mas están interconectados por medio de un caracter caño '' | Si dos comandos o mas están interconectados por medio de un caracter caño '' | ||
| - | El formato | + | La sintaxis |
| <code bash> | <code bash> | ||
| Línea 450: | Línea 453: | ||
| </ | </ | ||
| - | El usuario '' | + | El usuario '' |
| El comando //date// le da la fecha y la hora. Compruébelo en su terminal | El comando //date// le da la fecha y la hora. Compruébelo en su terminal | ||
| Línea 509: | Línea 512: | ||
| El comando //batch// es útil si está ejecutando un proceso o programa de shell que requiere una cantidad mayor a la normal de tiempo de cómputo. El comando //batch// produce un trabajo "en lote", que consiste en comandos a ser ejecutados por la computadora. El trabajo forma una cola, y se ejecutará no bien la carga del procesador del sistema descienda hasta un nivel aceptable. Esto libera a la computadora para poder responder rápidamente a otras entradas que le pudiesen efectuar otros o usted mismo. | El comando //batch// es útil si está ejecutando un proceso o programa de shell que requiere una cantidad mayor a la normal de tiempo de cómputo. El comando //batch// produce un trabajo "en lote", que consiste en comandos a ser ejecutados por la computadora. El trabajo forma una cola, y se ejecutará no bien la carga del procesador del sistema descienda hasta un nivel aceptable. Esto libera a la computadora para poder responder rápidamente a otras entradas que le pudiesen efectuar otros o usted mismo. | ||
| - | El formato | + | La sintaxis |
| <code bash> | <code bash> | ||
| $ batch | $ batch | ||
| primer comando | primer comando | ||
| - | " | + | . |
| - | " | + | . |
| - | " | + | . |
| último comando | último comando | ||
| ^d | ^d | ||
| Línea 528: | Línea 531: | ||
| </ | </ | ||
| - | El siguiente ejemplo usa el comando batch para ejecutar el comando grep en un momento conveniente. Cuando el sistema puede ejecutar el comando y responder aún rápidamente a otros usuarios, ejecutará grep para buscar todos los ficheros con la palabra dólar, y redirigirá la salida en el fichero '' | + | El siguiente ejemplo usa el comando batch para ejecutar el comando |
| <code bash> | <code bash> | ||
| Línea 537: | Línea 540: | ||
| </ | </ | ||
| - | El comando //at// indica a la computadora un momento específico para ejecutar dicho comando. | + | El comando //at// indica a la computadora un momento específico para ejecutar dicho comando. |
| <code bash> | <code bash> | ||
| $ at hora | $ at hora | ||
| primer comando | primer comando | ||
| - | | + | |
| - | | + | |
| - | | + | |
| último comando | último comando | ||
| ^d | ^d | ||
| Línea 551: | Línea 554: | ||
| La '' | La '' | ||
| - | Si temes olvidar el cumpleaños de '' | + | Si teme olvidar el cumpleaños de '' |
| <code bash> | <code bash> | ||
| $ at 8:15 am feb 27 | $ at 8:15 am feb 27 | ||
| - | banner | + | banner |
| ^d | ^d | ||
| job 1282923.a at Mon Feb 27 8:15, 1986 | job 1282923.a at Mon Feb 27 8:15, 1986 | ||
| </ | </ | ||
| - | Tanto el comando //batch// y el comando //at// le proporcionarán un número de trabajo. Si decide que no desea ejecutar los comandos //batch// o //at// que ya estan a la espera en una cola de procesos por lote, puede borrarlos con la opción **-r** del comando // | + | Tanto el comando //batch// y el comando //at// le proporcionarán un número de trabajo. Si decide que no desea ejecutar los comandos //batch// o //at// que ya están |
| <code bash> | <code bash> | ||
| Línea 566: | Línea 569: | ||
| </ | </ | ||
| - | Intenta borrar el trabajo por lotes previo de //at//. El comando //at -l// proporcionará | + | Como '' |
| <code bash> | <code bash> | ||
| Línea 593: | Línea 596: | ||
| El comando //ps// le dará el status de los proceso que usted está ejecutando. | El comando //ps// le dará el status de los proceso que usted está ejecutando. | ||
| - | El comando //ps// le dirá el status de los comandos en segundo plano discutidos en la [[# | + | El comando //ps// le dirá el status de los comandos en segundo plano discutidos en la [[# |
| <code bash> | <code bash> | ||
| Línea 612: | Línea 615: | ||
| === Terminar Procesos Activos === | === Terminar Procesos Activos === | ||
| - | El comando //kill// se utiliza para detener procesos activos de la shell. | + | El comando //kill// se utiliza para detener procesos activos de la shell. |
| <code bash> | <code bash> | ||
| Línea 618: | Línea 621: | ||
| </ | </ | ||
| - | ¿Que hace si decide que no necesita ejecutar el comando que está ejecutándose en segundo plano? Si presiona la tecla BREAK o la tecla DEL, decubrirá | + | ¿Que hace si decide que no necesita ejecutar el comando que está ejecutándose en segundo plano? Si presiona la **tecla BREAK** o la **tecla DEL**, decubrirá |
| <code bash> | <code bash> | ||
| Línea 628: | Línea 631: | ||
| ===Usar el comando nohangup === | ===Usar el comando nohangup === | ||
| - | Otra forma de exterminar todos los procesos es colgar la conexión | + | Otra forma de exterminar todos los procesos es colgar |
| <code bash> | <code bash> | ||
| Línea 642: | Línea 645: | ||
| El comando //nohup// puede exterminarse con el comando //kill//. | El comando //nohup// puede exterminarse con el comando //kill//. | ||
| + | |||
| + | |||
| + | ===== Programación de la shell ===== | ||
| + | |||
| + | ====Comenzando ==== | ||
| + | |||
| + | Deje que un [[script|guion de shell]] realice sus tareas por usted. Un guion de shell es un fichero de sistema UNIX que contiene los comandos que usted usaría para desarrollar una tarea programada. | ||
| + | |||
| + | === Crear un programa simple de shell === | ||
| + | |||
| + | Para crear un guion de shell, usa tu [[editores de texto|editor de texto favorito]] e ingresa los siguientes comandos: | ||
| + | |||
| + | <code bash> | ||
| + | pwd | ||
| + | ls | ||
| + | echo Este es el final del guion de shell | ||
| + | </ | ||
| + | |||
| + | Guarda los contenidos escritos en el editor en un fichero llamado dl (por " | ||
| + | |||
| + | <code bash> | ||
| + | $ cat dl | ||
| + | pwd | ||
| + | ls | ||
| + | echo Este es el final del guion de shell | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | ===Ejecutar un guion de shell=== | ||
| + | |||
| + | La manera mas simple de decirle a la shell que queremos ejecutar un programa, es usar el comando //sh//. | ||
| + | |||
| + | <code bash> | ||
| + | sh dl | ||
| + | </ | ||
| + | |||
| + | Notará que se imprime primero la ruta de directorio del directorio actual, y luego se listará elc contenido del mismo, y finalmente el comentario "Este es el final del guion de shell" | ||
| + | |||
| + | El comando //sh// resulta una buena maneta para evaluar su guion de shell y asegurarse que funciona. | ||
| + | |||
| + | Si //dl// le resulta conveniente, | ||
| + | |||
| + | <code bash> | ||
| + | $ chmod u+x dl | ||
| + | $ ls -l dl | ||
| + | -rwx------ 1 usuario usuario | ||
| + | </ | ||
| + | |||
| + | Ahora tiene un programa ejecutable llamado '' | ||
| + | |||
| + | Ejecute el comando ingresando | ||
| + | |||
| + | <code bash> | ||
| + | $ dl | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===Crear un directorio bin para los ficheros ejecutables === | ||
| + | |||
| + | Si su guion de shell le resultó útil, querrá guardarlo en un directorio especial llamado bin, dentro de su direcotrio ''/ | ||
| + | |||
| + | Si desea que su comando dl sea accesible desde todos sus directorios, | ||
| + | |||
| + | <code bash> | ||
| + | mkdir ~/bin/ | ||
| + | mv dl ~/bin/dl | ||
| + | </ | ||
| + | |||
| + | Cambie al directorio bin e ingrese el comando '' | ||
| + | |||
| + | Ahora muévase a otro directorio distinto a su directorio ''/ | ||
| + | ¿Que sucedió? | ||
| + | |||
| + | El directorio bin/ es el mejor lugar para mantener sus programas de shell ejecutables. Es posible darle al directorio bin otro nombre, pero necesitará cambiar la variable de '' | ||
| + | |||
| + | >Puede darle a su guion de shell cualquier nombre de fichero apropiado. Sin embargo, no debería nombrar su programa con el mismo nombre de un comando de sistema. El sistema ejecutaría su comando y no el comando de sistema. | ||
| + | |||
| + | Si hubiese nombrado a su programa //dl// como //mv//, cada vez que hubiese intentado mover un fichero o renombrarlo, | ||
| + | |||
| + | >Otro problema hubiese ocurrido si usted hubiese llamado a su programa //dl// como //ls//, y luego intentado ejecutar el fichero //ls//. Esto hubiese creado un bucle infinito. Luego de un tiempo, el sistema le hubiese dado un mensaje de error: | ||
| + | |||
| + | < | ||
| + | too many processes, cannot fork. | ||
| + | </ | ||
| + | |||
| + | ¿Qué ha sucedido? Tipeó su nuevo comando //ls//. La shell leyó el comando //pwd// y ejecutó dicho comando. Luego la shell leyó el comando ls en su fichero e intentó ejecutar su comando ls. Esto formó el bucle infinito. | ||
| + | |||
| + | Los programadores del sistema UNIX sabiamente establecieron un límite de cantidad a las ejecuciones en bucle, para impedir que sean infinitas. Una manera de evitar que esto suceda es darle un nombre de ruta al comando ls del sistema: /bin/ls | ||
| + | |||
| + | El siguiente programa //ls// debería funcionar: | ||
| + | |||
| + | <code bash> | ||
| + | $ cat ls | ||
| + | pwd | ||
| + | /bin/ls | ||
| + | echo Este es el final del guion de shell | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Si usted hubiese nombrado su comanbdo //ls//, entonces, entonces sólo podría ejecutar el comando de sistema con /bin/ls. | ||
| + | |||
| + | |||
| + | ====Variables==== | ||
| + | |||
| + | Si le gustó enviar el cartelón de cumpleaños con el comando //banner//, podría hacer un guion de shell que entube el resultado de //banner// a un correo electrónico de //mail//. Un buen prograam de shell le permitirá enviar a un usuario distinto cada vez que se ejecute. El usuario debería ser entonces una __variable__. Existen dos maneras de especificar una variable en un guion de shell. | ||
| + | |||
| + | * parámetros posicionales | ||
| + | * variables que define usted mismo | ||
| + | |||
| + | === Parámetros posicionales=== | ||
| + | |||
| + | Un parámetro posicional es una varibale que se encuentra en una posición especificada en la línea de comandos de su guion de shell. Los parámetros posicional se ingresan después del comando. Son cadenas de caracteres delimitadas por espaciones en blanco, excepto para el último parámetro. Si el primer parámetro posicional es //pp1//, //pp2// es el segundo parámetro posicional, y ... //pp9// es el noveno parámetro posicional, entonces la línea de comando de su guion de shell '' | ||
| + | |||
| + | <code bash> | ||
| + | $ shell.prog pp1 pp2 pp3 pp4 pp5 pp6 pp7 pp8 pp9 | ||
| + | </ | ||
| + | |||
| + | El guion de shell tomará el primer parámetro posicional ('' | ||
| + | |||
| + | Si desea ver como se sustituyen los parámetros posicionales en un programa, intente ingresar las siguientes líneas en un fichero llamado '' | ||
| + | |||
| + | < | ||
| + | echo El primer parámetro posicional es: $1 | ||
| + | echo El segundo parámetro posicional es: $2 | ||
| + | echo El tercer parámetro posicional es: $3 | ||
| + | echo El cuarto parámetro posicional es: $4 | ||
| + | </ | ||
| + | |||
| + | El primer comando //echo// le dice cuál parámetro aparecerá en pantalla y luego mostrará el parámetro. | ||
| + | |||
| + | Ahora le damos permisos de ejecución al guion de shell '' | ||
| + | |||
| + | <code bash> | ||
| + | $ chmod u+x pp | ||
| + | $ | ||
| + | $ pp uno dos tres cuatro | ||
| + | El primer parámetro posicional es: uno | ||
| + | El segundo parámetro posicional es: dos | ||
| + | El tercer parámetro posicional es: tres | ||
| + | El cuarto parámetro posicional es: cuatro | ||
| + | </ | ||
| + | |||
| + | Si cambiamos los parámetros posicionales previstos, estos cambiarán en el resultado: | ||
| + | |||
| + | <code bash> | ||
| + | $ pp River Boca cancha pelota | ||
| + | El primer parámetro posicional es: River | ||
| + | El segundo parámetro posicional es: Boca | ||
| + | El tercer parámetro posicional es: cancha | ||
| + | El cuarto parámetro posicional es: pelota | ||
| + | </ | ||
| + | |||
| + | Sabiendo esto, ahora volvemos a vrear un guion de shell para el cartelón cumpleañero. Lo llamamos '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat cumple | ||
| + | banner Feliz cumple! | mail $1 | ||
| + | </ | ||
| + | |||
| + | Intente mandarse un saludo de cumpleaños a usted mismo. Podría usar | ||
| + | |||
| + | <code bash> | ||
| + | $ cumple $USER | ||
| + | You have mail | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | El comando //who// le dice qué usuarios están usando actualmente la computadora. ¿Cómo haría un guion de shell simple llamado '' | ||
| + | |||
| + | Intente lo siguiente: | ||
| + | |||
| + | <code bash> | ||
| + | $ who | grep jefe | ||
| + | jefe tty51 Nov 29 17:01 | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Este comando entuba la salida del comando //who// al comando //grep//. El comando grep busca los caracteres " | ||
| + | |||
| + | < | ||
| + | jefe tty51 Nov 29 17:01 | ||
| + | </ | ||
| + | |||
| + | Si la única respuesta es un signo '' | ||
| + | |||
| + | Debajo tiene los ingredientes para su guion de shell '' | ||
| + | |||
| + | |'' | ||
| + | |'' | ||
| + | |'' | ||
| + | |||
| + | El comando //grep// busca en la salida del comando who el parámetro designado en el programa como '' | ||
| + | |||
| + | Edite un fichero llamado '' | ||
| + | |||
| + | <code bash> | ||
| + | who | grep $1 | ||
| + | </ | ||
| + | |||
| + | Guarde el fichero '' | ||
| + | |||
| + | Ahora intente proporcionale a '' | ||
| + | |||
| + | Si su nombre de usuario es '' | ||
| + | |||
| + | <code bash> | ||
| + | $ esta mengano | ||
| + | mengano | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | El primer parámetro posicional es el nombre de usuario '' | ||
| + | |||
| + | <code bash> | ||
| + | who | grep mengano | ||
| + | </ | ||
| + | |||
| + | La línea de comandos de la shell permite hasta 128 parámetros posicionales. Sin embargo, su guion de shell está restringido desde $1 a $9, a no ser que use el '' | ||
| + | |||
| + | ===Parámetros con Significado Especial=== | ||
| + | |||
| + | '' | ||
| + | |||
| + | Veamos un ejemplo que demuestre qué sucede cuando usamos '' | ||
| + | |||
| + | <code bash> | ||
| + | echo El número de parámetros es: $# | ||
| + | </ | ||
| + | |||
| + | Este programa contará todos los parámetros posicionales habido y mostrará la cifra numérica. Puede ser cualquier cadena de caracteres. | ||
| + | |||
| + | <code bash> | ||
| + | $ obt.num La vuelta vamos a dar | ||
| + | En número de parámetros es: 5 | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Como vemos, obt.num cuenta y muestra la cantidad de argumentos. | ||
| + | |||
| + | |||
| + | '' | ||
| + | |||
| + | Puede hacer un guion de shell simple para demostrar la variable '' | ||
| + | |||
| + | echo Los parámetros para este comando son: $* | ||
| + | |||
| + | Al ejeceutarlo podría indicar: | ||
| + | |||
| + | <code bash> | ||
| + | $ mostrar.param Hola como estás | ||
| + | Los parámetros para este comando son: Hola como estás | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Ahora intente usar mostrar.param con más de nueve parámetros posicionales: | ||
| + | |||
| + | <code bash> | ||
| + | $ mostrar.param uno dos 3 4 5 seis 7 8 9 10 once | ||
| + | Los parámetros para este comando son: uno dos 3 4 5 seis 7 8 9 10 once | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | La variable '' | ||
| + | |||
| + | Intente un parámetro de generación de nombre para su comando '' | ||
| + | |||
| + | <code bash> | ||
| + | $ mostrar.param cap? | ||
| + | Los parámetros para este comando son: cap1 cap2 cap3 cap4 cap5 cap6 cap7 | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Podría querer practicarr con parámetros posicionales de manera que le resulten familiares antes de continuar con la siguiente sección en la cual nombrará las variables dentro de uin programa en lugar de usarlas como argumentos desde la línea de comandos. | ||
| + | |||
| + | ==== Nombres de Variables==== | ||
| + | |||
| + | La shell le permite nombrar las variables dentro de un guion de shell. Al nombrar las variables en un guion de shell, esto hace más simple que otra persona pueda usarlo. En lugar de usar parámetros posicionales, | ||
| + | |||
| + | ¿Qué apariencia tiene una variable designada? En el ejemplo siguiente, '' | ||
| + | |||
| + | <code bash> | ||
| + | var1=minombre | ||
| + | </ | ||
| + | |||
| + | Dentro de la shell, un '' | ||
| + | |||
| + | El primer caracter de un nombre de variable deve ser una letra o un guión bajo '' | ||
| + | |||
| + | |'' | ||
| + | |'' | ||
| + | |'' | ||
| + | |'' | ||
| + | |'' | ||
| + | |'' | ||
| + | |'' | ||
| + | |'' | ||
| + | |||
| + | Muchas de estas variables nombradas se explican en la última sección de este capítulo en su ambiente de usuario. | ||
| + | |||
| + | ===Asignar Valores a Variables === | ||
| + | |||
| + | Si has editado con //vi//, sabe que debe establecer la variable '' | ||
| + | |||
| + | <code bash> | ||
| + | TERM=VT100 | ||
| + | </ | ||
| + | |||
| + | Esta es la manera más simple de asignar un valor a una variable. | ||
| + | |||
| + | Existen otras formas de hacerla. Una es usar el comando //read// y asignar entrada a la variable. Otra forma es asignar la variable desde la salida de un comando, usando apóstrofos agudos ''< | ||
| + | |||
| + | ===Asignar Valores con el comando read === | ||
| + | |||
| + | Puede establecer su programa de forma que ingrese el comando, y luego que le solicite ingresar el valor para la variable. El comando //read// asigna la entrada a la variable espeficiada. La sintaxis general del comando //read// es: | ||
| + | |||
| + | <code bash> | ||
| + | read var | ||
| + | </ | ||
| + | |||
| + | Los valores asignados por //read// a '' | ||
| + | |||
| + | Si tenía una lista que contenía los nombres y números telefónicos de la gente que llama a menudo, podría hacer un programa simple que automáticamente le de el nombre de alguien. ¡Un momento! ¿Cómo haría tal guion de shell con los siguientes ingredientes? | ||
| + | |||
| + | |'' | ||
| + | |'' | ||
| + | |'' | ||
| + | |||
| + | Primero, usaría el comando //echo// para informar al usuario que mecanografía el nombre a llamar | ||
| + | |||
| + | <code bash> | ||
| + | echo Ingrese el apellido | ||
| + | </ | ||
| + | |||
| + | El comando //read// entonces asignaría el nombre de la persona a la variable '' | ||
| + | |||
| + | <code bash> | ||
| + | read name | ||
| + | </ | ||
| + | |||
| + | note que no usa el '' | ||
| + | |||
| + | El comando //grep// buscará entonces su lista telefónica en busca del nombre. Si la lista telefónica se llamara agenda, la línea de comandos sería | ||
| + | |||
| + | <code bash> | ||
| + | grep $nombre agenda | ||
| + | </ | ||
| + | |||
| + | En el siguiente ejemplo, el guion de shell se llama '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat tel | ||
| + | echo Ingrese el apellido | ||
| + | read nombre | ||
| + | grep $nombre agenda | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Haga un listado de apellidos y números telefonicos llamado '' | ||
| + | |||
| + | * Asignaría el nombre de la persona, | ||
| + | * Asignaría el nombre a la variable '' | ||
| + | * Pide el número de teléfono de la persona, | ||
| + | * Solicita el número a la variable '' | ||
| + | * da eco del '' | ||
| + | |||
| + | El programa se llamará '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat agendar | ||
| + | echo Ingrese el nombre | ||
| + | read nombre | ||
| + | echo Ingrese el número telefónico | ||
| + | read num | ||
| + | echo $nombre $num >> agenda | ||
| + | $ | ||
| + | $ chmod u+x agendar | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Ahora pruebe los nuevos programas para su agenda telefónica. En el siguiente ejemplo, usamos '' | ||
| + | |||
| + | <code bash> | ||
| + | $ agendar | ||
| + | Ingrese el nombre | ||
| + | Sr. Fulano Sultano | ||
| + | Ingrese el número | ||
| + | 5555-1234 | ||
| + | $ | ||
| + | $ tel | ||
| + | Ingrese el apellido | ||
| + | Sultano | ||
| + | Sr. Fulano Sultano 5555-1234 | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Vea que que la variable '' | ||
| + | |||
| + | ===Sustituir salida de comando por el Valor de una Variable=== | ||
| + | |||
| + | Otra forma de asignar un valor a una variable es sustituir la salida de un comando por el valor. Esto será muy útil en la siguiente sección, donde intentaremos bucles y construcciones condicionales. | ||
| + | |||
| + | La sintaxis general para asignar una salida como valor de variable es recurrir al apostrofe agudo '' | ||
| + | |||
| + | <code bash> | ||
| + | var=`comando` | ||
| + | </ | ||
| + | |||
| + | La variable '' | ||
| + | |||
| + | En uno de los ejemplos anteriores de entubado, redirigimos el comando //date// al comando //cut// para obtener la hora correcta. Dicha línea había sido | ||
| + | |||
| + | <code bash> | ||
| + | date | cut -c12-19 | ||
| + | </ | ||
| + | |||
| + | Puede colocar dicho comando en un programa de shell llamado '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat hora | ||
| + | hora=`date | cut -c12-19` | ||
| + | echo Son las $hora | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Recuerda que aqu{i no hay espacioes en blanco a los costados del signo '' | ||
| + | |||
| + | Cambia el modo del fichero y ahora tendrás un microprograma que te da la hora. | ||
| + | |||
| + | <code bash> | ||
| + | $ chmod u+x hora | ||
| + | $ hora | ||
| + | Son las 10:36 | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | === Asignar Valores con Parámetros Posicionales === | ||
| + | |||
| + | Puede asignar un parámetro posicional como parámetro designado. Por ejemplo: | ||
| + | |||
| + | <code bash> | ||
| + | var1=$1 | ||
| + | </ | ||
| + | |||
| + | El ejemplo siguiente es un guion de shell simple '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat simp.p | ||
| + | var1=$1 | ||
| + | echo $var1 | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | O, puede asignar la salida de un comando que usa un parámetro posicional: | ||
| + | |||
| + | <code bash> | ||
| + | persona=`who | grep $1` | ||
| + | </ | ||
| + | |||
| + | Si quiere mantener registro de su programa '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat picaentrada | ||
| + | persona=`who | grep $1` | ||
| + | echo $persona >> lista.ingreso | ||
| + | echo $persona | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | La respuesta de la computadora a '' | ||
| + | |||
| + | <code bash> | ||
| + | $ picanetrada fulana | ||
| + | fulana | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | En la medida que programe más cosas, descubrirá otras maneras de asignar variables que le ayudarán a hacer mejores microprogramas por medio de los guiones de shell. | ||
| + | |||
| + | ==== Construcciones de Programación de Guiones ==== | ||
| + | |||
| + | El lenguaje de programación de la shell cuenta con varias // | ||
| + | |||
| + | * El "aqui documento" | ||
| + | | ||
| + | * La construcción de bucle **for** y **while** hacen que un programa reitere comandos en bucle. | ||
| + | | ||
| + | * Los comandos de control condicional **if** y **case** ejecutan un grupo de comandos sólo si un conjunto de condiciones particulares se cumplen. | ||
| + | | ||
| + | * El comando **break** le ofrece una finalización incondicional al bucle. | ||
| + | | ||
| + | === Comentarios=== | ||
| + | | ||
| + | Antes de comenzar a escribir programas de la shell con bucles, querrá sabner cómo poner comentarios sobre su programa en el mismo fichero, los cuales son ignorados por el sistema. Para poner comandos en un programa, comience el comentario con ''#'' | ||
| + | | ||
| + | < | ||
| + | # | ||
| + | </ | ||
| + | |||
| + | La shell ignorará todos los caracteres que sigan al ''#'' | ||
| + | |||
| + | <code bash> | ||
| + | #Este programa envia un saludo de cumpleaños genérico | ||
| + | #Este programa necesita un usuario como parámetro posicional. | ||
| + | </ | ||
| + | |||
| + | será ignorado por el sistema cuando su programa se ejecuta. Simplemente sirve como un recordatorio para tí, el programador. | ||
| + | |||
| + | ===El Documento Aquí=== | ||
| + | |||
| + | El Documento '' | ||
| + | |||
| + | <code bash> | ||
| + | comando <<! | ||
| + | ...lineas de entrada... | ||
| + | ! | ||
| + | </ | ||
| + | |||
| + | El documento '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat fcumple | ||
| + | mail $1 <<! | ||
| + | Que los cumplas muy feliz! | ||
| + | ! | ||
| + | </ | ||
| + | |||
| + | El parámetro posicional '' | ||
| + | |||
| + | La entrada redirigida a mail será | ||
| + | |||
| + | < | ||
| + | Que los cumplas muy feliz! | ||
| + | </ | ||
| + | |||
| + | Para enviar el saludo: | ||
| + | |||
| + | <code bash> | ||
| + | $ fcumple maria | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Para recibir esta salutación, | ||
| + | |||
| + | <code bash> | ||
| + | |||
| + | De fulana | ||
| + | Que los cumplas muy feliz! | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | ===Usar ed en un programa de shell=== | ||
| + | |||
| + | El editor de líneas [[ed]] puede usarse dentro de un programa de shell, si se combina con los comandos del documento Aquí. | ||
| + | |||
| + | Suponga que desea hacer un programa de shell que ingrese al editor **ed**, realice una sustitución global a un fichero, escriba el fichero, y luego salga del editor. El comando de **ed** que realiza una sustitución global es: | ||
| + | |||
| + | <code bash> | ||
| + | g/texto a cambiar/ | ||
| + | </ | ||
| + | |||
| + | Antes de continuar leyendo, piense bien cuál cree que será la secuencia del comando. Ponga su secuencia de comandos en un fichero llamado '' | ||
| + | |||
| + | <code bash> | ||
| + | ed - fichero | ||
| + | </ | ||
| + | |||
| + | Intente ejecutar el fichero. ¿Funciona? | ||
| + | |||
| + | Si usó el comando **read** para ingresar las variables, su programa '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat cambio.text | ||
| + | echo Ingrese un nombre de fichero | ||
| + | read fichero1 | ||
| + | echo Ingrese el texto exacto a cambiar. | ||
| + | read busqueda | ||
| + | echo Ingrese exactamente el nuevo texto con el cual reemplazar al anterior. | ||
| + | read reemplazo | ||
| + | ed - $fichero1 <<! | ||
| + | g/ | ||
| + | w | ||
| + | q | ||
| + | ! | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Este programa usa tres variables. Cada una de ellas se ingresa al programa con el comando **read**. | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | | ||
| + | Una vez que las variables son introducidas al programa, el documento aquí redirige los comandos //búsqueda global//, //grabar//, y //salir// al editor **ed**. | ||
| + | |||
| + | Pruebemos el nuevo comando '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cambio.text | ||
| + | Ingrese un nombre de fichero | ||
| + | carta.txt | ||
| + | Ingrese el texto exacto a cambiar. | ||
| + | Estimado Juan | ||
| + | Ingrese exactamente el nuevo texto con el cual reemplazar al anterior. | ||
| + | A quien pueda concernir | ||
| + | cat carta.txt | ||
| + | Calle de los Pinos 1234 | ||
| + | Santa Eduviges, Molinos | ||
| + | |||
| + | A quien pueda concernir: | ||
| + | |||
| + | Hemos notado que en la publicación del día 23 de mayo, se refirió a... | ||
| + | (...) | ||
| + | </ | ||
| + | |||
| + | ¿Intentó utilizar parámetros posicionales? | ||
| + | |||
| + | > También puede usarse el editor de flujos [[sed]] en la programación de shell. | ||
| + | |||
| + | ===Bucles=== | ||
| + | |||
| + | Hasta ahora, los comandos en su programa de la shell han sido ejecutados una vez, y sólo una vez, y secuencialmente. La construcción bucle le ofrece la ejecución repetitiva (iterada) de un comando o grupo de comandos. Los comandos **for** y **while** harán que el programa haga bucles y ejecute una secuencia de comandos __en varias ocasiones__. | ||
| + | |||
| + | ==El bucle for== | ||
| + | |||
| + | El bucle '' | ||
| + | |||
| + | <code bash> | ||
| + | for variable | ||
| + | in esta lista de valores | ||
| + | do los siguientes comandos | ||
| + | comando1 | ||
| + | comando2 | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | último comando | ||
| + | done | ||
| + | </ | ||
| + | |||
| + | La variable puede ser cualquier nombre que elijamos. Si es '' | ||
| + | |||
| + | Cuando los comandos se ejecutaron hasta el último valor, el programa ejecutará la siguiente línea que siga a '' | ||
| + | |||
| + | Es más sencillo leer un programa de shell si la construcción de bucle se resalta. Ya que la shell ignora los espacios al comienzo de la línea, se usa indentar cada sección de comandos como aparece en la sintaxis anterior. También, si indenta cada sección de comandos, podrá observar rápidaemten para asegurarse que cada '' | ||
| + | |||
| + | La manera más fácil de entender una // | ||
| + | |||
| + | Los ingredientes para este programa serán: | ||
| + | |||
| + | * **echo**: quiere que de eco de instrucciones para que usted ingrese una ruta de cada directorio nuevo. | ||
| + | * **read**: quiere ingresar el nombre de ruta, y asignarlo a la variable '' | ||
| + | * **for** '' | ||
| + | * **in** '' | ||
| + | * **done** | ||
| + | | ||
| + | El contenido de programación de su programa de shell mv.fichero podría ser: | ||
| + | |||
| + | <code bash> | ||
| + | $ cat mv.fichero | ||
| + | echo Por favor indique la ruta de directorio | ||
| + | read ruta | ||
| + | for fichero | ||
| + | in carta1 carta2 carta3 | ||
| + | do | ||
| + | mv $fichero $ruta/ | ||
| + | done | ||
| + | </ | ||
| + | |||
| + | Tenga presente que no ingresó ningunos valores para la variable '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat mv.fichero | ||
| + | echo Por favor indique la ruta de directorio | ||
| + | read ruta | ||
| + | for fichero | ||
| + | do | ||
| + | mv $fichero $ruta/ | ||
| + | done | ||
| + | </ | ||
| + | |||
| + | Es probable que quiera mover varios fichero usando los varios metacaracteres de generación de nombre de fichero, que hemos visto. | ||
| + | |||
| + | |||
| + | ==El bucle While == | ||
| + | |||
| + | |||
| + | El bucle **while** continuará ejecutando la secuencia de comandos en la lista '' | ||
| + | |||
| + | <code bash> | ||
| + | while | ||
| + | | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | | ||
| + | do | ||
| + | | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | | ||
| + | done | ||
| + | </ | ||
| + | |||
| + | Estas son las líneas de un programa simple llamado '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat ingresa.nombre | ||
| + | while | ||
| + | read x | ||
| + | do | ||
| + | echo $x >> ficherox | ||
| + | done | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Este programa de shell necesita algunas instrucciones. Debe saber que para delimitar o separar los nombres tiene que usarse la **tecla Intro**, y que tiene que usar **Ctrl+d** para finalizar el programa. También sería amable si su programa mostrara la lista de nombres de '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat ingresa.nombre | ||
| + | echo 'Por favor ingrese cada nombre personal, y luego presione la tecla Intro.' | ||
| + | echo 'Por favor, finalice el ingreso de nombres con Ctrl+d.' | ||
| + | while read x | ||
| + | do | ||
| + | echo $x >> ficherox | ||
| + | done | ||
| + | echo ficherox contiene los siguientes nombres: | ||
| + | cat ficherox | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Note que una vez que se complete el bucle, el programa ejecutará el comando que viene después de '' | ||
| + | |||
| + | En la línea del comando '' | ||
| + | |||
| + | <code bash> | ||
| + | Por favor ingrese cada nombre personal, y luego presione la tecla Intro. | ||
| + | María Luisa | ||
| + | Jana | ||
| + | ^d | ||
| + | ficherox contiene los siguientes nombres: | ||
| + | María Luisa | ||
| + | Jana | ||
| + | </ | ||
| + | |||
| + | ====Construcciones condicionales if...then==== | ||
| + | |||
| + | El comando **if** le dice al programa de shell que ejecute la secuencia **then** de comandos __solo si__ el comando final de la lista de comandos **if** ha sido exitoso. La construcción **if** finaliza con la palabra clave '' | ||
| + | |||
| + | <code bash> | ||
| + | if | ||
| + | comando1 | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | último comando | ||
| + | then | ||
| + | comando1 | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | último comando | ||
| + | fi | ||
| + | </ | ||
| + | |||
| + | El siguiente programa de shell demuestra la construcción **if...then**. El programa buscará una palabra en un fichero. Si el comando **grep** tiene éxito, entonces el programa usará **echo** para mostrar dicha palabra encontrada en el fichero. En este ejemplo, las variables se leen en el programa de shell. Ingrese el programa a continuación y pruébelo. Llame al programa '' | ||
| + | |||
| + | |||
| + | <code bash> | ||
| + | $ cat buscar | ||
| + | echo Ingrese la palabra y el nombre de fichero | ||
| + | read palabra fichero | ||
| + | if grep $palabra $fichero | ||
| + | then echo $palabra está en $fichero | ||
| + | fi | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Note que el comando **read** está asignando valores a dos variables. Los primeros caracteres que usted ingrese, hasta el espacio en blanco, son asignados a la variable '' | ||
| + | |||
| + | Escoja una palabra que sabe que existe en un fichero, y evalúe este programa de shell. ¿Se da cuenta que a pesar de que el programa funciona, existe un problema irritante? Su programa muestra más de la línes de texto descubiertas. Las líneas de texto extra mostradas en su terminal son la salida del comando **[[grep]]**. | ||
| + | |||
| + | === El cesto de la shell /dev/null === | ||
| + | |||
| + | La shell cuenta con un fichero que actúa de cesto de basura. Puede depositar cualquier salida no deseada en el fichero ''/ | ||
| + | |||
| + | Probemos el "cesto de basura" | ||
| + | |||
| + | <code bash>who > / | ||
| + | |||
| + | La respuesta que aparecerá en su terminal será el prompt. La respuesta del comando **who** será descartada a ''/ | ||
| + | |||
| + | <code bash> | ||
| + | if grep $palabra $fichero > /dev/null | ||
| + | </ | ||
| + | |||
| + | Ahora ejecute el programa '' | ||
| + | |||
| + | La construcción **if...then** también puede ofrecer un conjunto de comandos alternativo con '' | ||
| + | |||
| + | |||
| + | <code bash> | ||
| + | if | ||
| + | comando1 | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | último comando | ||
| + | then | ||
| + | comando1 | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | último comando | ||
| + | else | ||
| + | comando1 | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | último comando | ||
| + | fi | ||
| + | </ | ||
| + | |||
| + | Ahora podremos mejorar el comando '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat buscar | ||
| + | echo Ingrese una palbra y el nombre de fichero | ||
| + | read palabra fichero | ||
| + | if | ||
| + | grep $palabra $fichero > /dev/null | ||
| + | then | ||
| + | echo $palabra está en $fichero | ||
| + | else | ||
| + | echo $palabra NO ESTÁ en $fichero | ||
| + | fi | ||
| + | </ | ||
| + | |||
| + | == Comando test para bucles== | ||
| + | |||
| + | **test** es un comando muy útil en las // | ||
| + | |||
| + | |test -r fichero |Verdadero si existe y es legible | | ||
| + | |test -w fichero |Verdadero si el fichero existe y tiene permisos de escritura | | ||
| + | |test -x fichero |Verdadero si el fichero existe y es ejecutable | | ||
| + | |test -s fichero |Verdadero si el fichero existe y tiene al menos un caracter | | ||
| + | |||
| + | Si no ha cambiado los valores de su varaible '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat mv.fichero | ||
| + | echo Por favor indique la ruta de directorio | ||
| + | read ruta | ||
| + | for fichero | ||
| + | do | ||
| + | mv $fichero $ruta/ | ||
| + | done | ||
| + | </ | ||
| + | |||
| + | Incluya una declaración '' | ||
| + | |||
| + | Si nombra al programa '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat mv.exe | ||
| + | echo Por favor indique la ruta de directorio | ||
| + | read ruta | ||
| + | for fichero | ||
| + | do | ||
| + | if test -x $fichero | ||
| + | then | ||
| + | mv $fichero $ruta/ | ||
| + | fi | ||
| + | done | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | La ruta de directorio será la ruta desde su directorio actual al directorio ''/ | ||
| + | |||
| + | <code bash> | ||
| + | $ cat mv.exe | ||
| + | for fichero | ||
| + | do | ||
| + | if test -x $fichero | ||
| + | then | ||
| + | mv $fichero $HOME/ | ||
| + | fi | ||
| + | done | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Para ejecutar el comando, use como parámetro posicional a todos los ficheros del directorio actual, con '' | ||
| + | |||
| + | <code bash> | ||
| + | $ mv.exe | ||
| + | $ cd; cd bin; ls | ||
| + | </ | ||
| + | |||
| + | |||
| + | === La construcción condicional case...esac=== | ||
| + | |||
| + | La **case..esac** es una construcción múltiple choice, que permite elegir una de varios patrones, y luego ejecutar una lista de comandos para dicho patrón. La palabra clave '' | ||
| + | |||
| + | |||
| + | <code bash> | ||
| + | case caracteres | ||
| + | in | ||
| + | patrón1 | ||
| + | linea de comando1 | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | última linea de comando | ||
| + | ;; | ||
| + | patron2) | ||
| + | línea de comando1 | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | última línea de comando | ||
| + | ;; | ||
| + | esac | ||
| + | </ | ||
| + | |||
| + | La construcción **case** intentará coincidir caracteres con el primer patrón. Si hay coincidencia, | ||
| + | |||
| + | Si el primer patrón no coincide, entonces el programa procederá al segundo patrón. Luego de alcanzar una coincidencia de patrón, el prorgrama no intentará coincidir ningún otro patrón más, pero irá al comando que sigue a '' | ||
| + | |||
| + | Si usted ha usado el editor [[vi]], ya sabe que debe asignar un valor a la variable '' | ||
| + | |||
| + | '' | ||
| + | |||
| + | <code bash> | ||
| + | TERM=codigo de terminal | ||
| + | export TERM | ||
| + | </ | ||
| + | |||
| + | En este ejemplo de '' | ||
| + | |||
| + | El programa '' | ||
| + | |||
| + | Al final de los patrones para las terminales de la [[serie VT]] aparece el patrón '' | ||
| + | |||
| + | <code bash> | ||
| + | echo Si tiene una terminal DEC VT52, ingrese vt52 | ||
| + | echo Si tiene un terminal DEC VT100, ingrese vt100 | ||
| + | echo Si tiene un terminal DEC VT320, ingrese vt320 | ||
| + | read term | ||
| + | case $term | ||
| + | in | ||
| + | vt52) | ||
| + | TERM=VT32 | ||
| + | ;; | ||
| + | vt100) | ||
| + | TERM=VT100 | ||
| + | ;; | ||
| + | vt320) | ||
| + | TERM=VT320 | ||
| + | ;; | ||
| + | *) | ||
| + | echo No es un tipo de terminal correcto. | ||
| + | ;; | ||
| + | esac | ||
| + | export TERM | ||
| + | echo Fin del programa | ||
| + | </ | ||
| + | |||
| + | ¿Qué hubiese sucedido de haber puesto el patrón '' | ||
| + | |||
| + | Cuando lee la sección de modificar su ambiente de inicio de sesión, podría querer aprovechar el programa '' | ||
| + | |||
| + | <code bash> | ||
| + | set.term | ||
| + | </ | ||
| + | |||
| + | a su fichero '' | ||
| + | |||
| + | ===Declaración de control incondicional break=== | ||
| + | |||
| + | El comando **break** detiene incondicionalmente la ejecución de cualquier bucle en el cual se encuentra, y va al siguiente comando que sigue a las declaraciones '' | ||
| + | |||
| + | En el ejemplo del programa '' | ||
| + | |||
| + | <code bash> | ||
| + | echo Si tiene una terminal DEC VT52, ingrese vt52 | ||
| + | echo Si tiene un terminal DEC VT100, ingrese vt100 | ||
| + | echo Si tiene un terminal DEC VT320, ingrese vt320 | ||
| + | read term | ||
| + | case $term | ||
| + | in | ||
| + | vt52) | ||
| + | TERM=VT32 | ||
| + | ;; | ||
| + | vt100) | ||
| + | TERM=VT100 | ||
| + | ;; | ||
| + | vt320) | ||
| + | TERM=VT320 | ||
| + | ;; | ||
| + | *) | ||
| + | break | ||
| + | ;; | ||
| + | esac | ||
| + | export TERM | ||
| + | echo Fin del programa | ||
| + | </ | ||
| + | |||
| + | En la medida que escriba mas programas de shell, podría querer usar dos otros comandos incondicionales, | ||
| + | |||
| + | Normalmente, | ||
| + | |||
| + | |||
| + | ====Depurando programas==== | ||
| + | |||
| + | Depurar es un término informático que significa buscar y encontrar errores en un programa. Existirán veces en las cuales ejecute un programa de shell y no pasará nada. Hay un " | ||
| + | |||
| + | Su programa puede consistir en varios pasos, o varios gurpos de comandos. ¿Cómo descubriría cuál paso es el culpable? Existen dos opciones en el intérprete **sh** que lo ayudarán a depurar un programa. | ||
| + | |||
| + | |'' | ||
| + | |'' | ||
| + | |||
| + | Para intentar estas dos opciones, cree un programa de shell que contenga un error en él. Por ejemplo, ingrese la siguiente lista de comandos en un fichero llamado '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat bug | ||
| + | hoy=' | ||
| + | persona=$1 | ||
| + | mail $2 | ||
| + | $persona | ||
| + | Cuando se desconecte, venga a mi oficina, por favor. | ||
| + | $hoy | ||
| + | MLH | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | El mensaje de correo enviado a Tomás ('' | ||
| + | |||
| + | <code bash> | ||
| + | De mlh Mie Abr 10 11:36 CST 1984 | ||
| + | Tom | ||
| + | Cuando se desconecte, venta a mi oficina por favor. | ||
| + | Mie Abr 10 11: | ||
| + | MLH | ||
| + | $ | ||
| + | ? | ||
| + | . | ||
| + | </ | ||
| + | |||
| + | Si intenta ejecutar '' | ||
| + | |||
| + | Para depurar este programa, intente '' | ||
| + | |||
| + | <code bash> | ||
| + | $ sh -v bug tomas tomi | ||
| + | hoy=' | ||
| + | persona=$1 | ||
| + | mail $2 | ||
| + | </ | ||
| + | |||
| + | Note que la salida se detiene en el comando **mail**. Hay problemas con **mail**. El documento aquí debe usarse para redirigir la entrada a **mail**. | ||
| + | |||
| + | Antes de corregir el programa '' | ||
| + | |||
| + | <code bash> | ||
| + | sh -x bug tomas tomi | ||
| + | +date | ||
| + | hoy=Mie | ||
| + | persona=tomas | ||
| + | +mail tomi | ||
| + | </ | ||
| + | |||
| + | Una vez mas, el programa se detiene en el comando **mail**. Note que las sustituciones para las variables han sido establecidas, | ||
| + | |||
| + | El programa '' | ||
| + | |||
| + | <code bash> | ||
| + | $ cat bug | ||
| + | hoy=' | ||
| + | persona=$1 | ||
| + | mail $2 <<! | ||
| + | $persona | ||
| + | Cuando se desconecte, venga a mi oficina por favor. | ||
| + | $hoy | ||
| + | MLH | ||
| + | ! | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | El comando **tee** es un comando útil para depurar cañerías. Coloca una copia de la salida de un comando en un fichero que usted nombre, así como lo entuba a otro comando. La sintaxis general del comando **tee** es: | ||
| + | |||
| + | <code bash> | ||
| + | comando1 | tee fichero.guardado | comando2 | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | Si queire revisar la salida del comando grep en la siguiente línea de comandos: | ||
| + | |||
| + | <code bash> | ||
| + | who | grep $1 | cut -c1-9 | ||
| + | </ | ||
| + | |||
| + | Puede usar tee para copiar la salida de **grep** en un fichero para revisarlo una vez que el programa haya terminado con su ejecución. | ||
| + | |||
| + | <code bash> | ||
| + | who | grep $1 | tee revisar | cut -c1-9 | ||
| + | </ | ||
| + | |||
| + | el fichero '' | ||
| + | |||
| + | <code bash> | ||
| + | $ who | grep mlhmo | tee revisar | cut -c1-9 | ||
| + | $ mlhmo | ||
| + | $ cat revisar | ||
| + | mlhmo | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | >Si escribe muchos programas de shell, querrás referirte a UNIX System Shell Commands and Programming, | ||
| + | |||
| + | ==== Modificando su Ambiente de Logueo ==== | ||
| + | |||
| + | === ¿Qué es un .profile? === | ||
| + | ===Agregar comandos a .profile=== | ||
| + | ===Configurar las opciones de TErminal=== | ||
| + | |||
| + | ===Usar variables de shell=== | ||
| + | ==HOME== | ||
| + | ==PATH== | ||
| + | == TERM== | ||
| + | ==PS1== | ||
| + | Una de las cosas interesantes de su '' | ||
| + | |||
| + | Ingresa: | ||
| + | |||
| + | <code bash> | ||
| + | |||
| + | Y su prompt tendrá el siguiente aspecto: | ||
| + | |||
| + | <code bash> | ||
| + | $ . .profile | ||
| + | Sus deseos son órdenes | ||
| + | </ | ||
| + | |||
| + | El mundano '' | ||
| + | |||
| + | |||
| + | ====Conclusión==== | ||
| + | |||
| + | Este tutorial le ha otorgado lo básico para crear algunos guiones de programación de shell. Si ha iniciado sesión y ha intentado los ejemplos y ejercicios de este tutorial, proablemente podrás realizar muchas de tus tares diarias recurriendo a programas de shell. La programación de shell puede ser mucho más compleja y desarrollar tareas más complicadas que las que se muestran aquí. Si quieres leer más de los comandos de la shell y la programación, | ||
