Programación del Shell LinuxAquí tenemos un libro libre y completo sobre ShellLa sed del "conocimiento libre" es muy bienvenida. |
Comandos Shell Script |
![]() |
|
Home |
Artículos ![]() ![]() |
Comprar el libroChangelogs |
|
Conversación de Bar - Parte V
- Que hay amigo! Ordenaste ya tus ideas?, Se fundió ya tu cabeza, o todavía aguanta más Shell?
- Aguanto, claro! Me esta gustando mucho! Me gustó tanto que hasta me esmeré en el ejercicio que me dejaste. Te acuerdas que me pediste que hiciera un programa que recibiría como parámetro el nombre de un archivo y que cuando se ejecutara salvara este archivo con el nombre original seguido de una tilde (
- Claro que me acuerdo, muéstramelo y explica como lo hiciste. $ cat vira
#!/bin/bash
#
# vira - vi grabando el archivo anterior
# == = =
# Verificando si fue pasado 1 parámetro
if [ "$#" -ne 1 ]
then
echo "Erro -> Uso: $0 Arq=$1 # En caso de que el archivo no exista, no hay copia para grabar if [ ! -f "$Arq" ] then vi $Arq exit 0 fi # Si no puedo alterar el archivo, para que voy a usar el vi? if [ ! -w "$Arq" ] then echo "Usted no tiene privilegios de grabación en $Arq" exit 2 fi # Ya que está todo OK, voy a salvar la copia y llamar el vi cp -f $Arq $Arq~ vi $Arq exit 0
- Bárbaro, muy bien! Pero dime una cosa: porque terminaste el programa con un
- Ahhh! Descubri que el número después del
- Grande!, aprendiste bien, pero es bueno dejar claro que el
Hasta ahora ya vimos algunos bloques de programa, como cuando te mostré un ejemplo para hacer un cd lmb 2> /dev/null || { mkdir lmb cd lmb }
El fragmento contenido entre las dos llaves (
Un bloque de comandos también puede estar dentro de un
- Espera ahí Julio, que
- Claro, todavía no había hablado de ellos porque no había llegado el momento adecuado. Todas las instrucciones de loop o lazo, ejecutan los comandos del bloque comprendido entre el Comandos de Loop (o lazo)
Las instrucciones de loop o lazo son el El comando for
Si ya estás habituado a programar, con seguridad conoces el comando Vamos a entender su sintaxis, primero en español y después como funciona realmente. para var en val1 val2 ... valn haga cmd1 cmd2 cmdn hecho
Donde la variable Ahora que ya vimos el significado de la instrucción en español, veamos la sintaxis correcta: Primera sintaxis del comando for:for var in val1 val2 ... valn do cmd1 cmd2 cmdn done Vamos directo a los ejemplos, a fin de entender el funcionamiento de este comando. Vamos a escribir un script para listar todos los archivos de nuestro directorio separados por dos puntos, pero mira primero: $ echo *
ArchDoDOS.txt1 confuso incusu logado musexc musicas musinc muslist
O sea, el Shell vio el asterisco ( $ cat testefor1
#!/bin/bash
# 1o. Prog didáctico para entender el for
for Arch in * do echo -n $Arq: # La opción -n es para no saltar la línea done Ahora vamos a ejecutarlo: $ testefor1
ArchDoDOS.txt1:confuso:incusu:logado:musexc:musicas:musinc:muslist:$
Como viste, el Shell transformó el asterisco (es odioso ser llamado por un asterisco) en una lista de archivos separados por espacios en blanco. cuando el
El bloque de comandos para ejecutar era solamente el $ cat testefor2
#!/bin/bash
# 2o. Prog didáctico para entender el for
for Palabra in Conversa de Bar do echo $Palabra done Y ejecutando resulta: $ testefor2
Conversa
de
Bar
Como viste, este ejemplo es tan bobo y simple como el anterior, pero sirve para mostrar el comportamiento básico del
Fíjate en la fuerza del
En realidad, las listas no son obligatoriamente separadas por espacios, pero antes de seguir, déjame mostrarte como se comporta una variable del sistema llamada $ echo "$IFS" | od -h
0000000 0920 0a0a
0000004
O sea, mandé la variable (protegida de la interpretación del Shell por las comillas) para un dump hexadecimal (
Donde el último $ echo ":$IFS:" | cat -vet
: ^I$
:$
Presta atención a lo siguiente para entender la construcción del comando cat: ![]() cat , la opción -e representa el <ENTER> como un signo de pesos ($ ) y la opción -t representa el <TAB> como un ^I . Usé los dos puntos (: ) para mostrar el inicio y el fin del echo . y de esta forma, otra vez podemos notar que los tres caracteres están presentes en aquella variable.
Ahora, $ cat musicas
album 1^Artista1~Musica1:Artista2~Musica2
album 2^Artista3~Musica3:Artista4~Musica4
album 3^Artista5~Musica5:Artista6~Musica6
album 4^Artista7~Musica7:Artista1~Musica3
album 5^Artista9~Musica9:Artista10~Musica10
En base a este esquema mostrado arriba fue desarrollado el script que sigue: $ cat listartista
#!/bin/bash
# Dado un artista, muestra sus músicas
if [ $# -ne 1 ] then echo Usted debería haber pasado un parámetro exit 1 fi IFS=" :" for ArtMus in $(cut -f2 -d^ musicas) do echo "$ArtMus" | grep $1 && echo $ArtMus | cut -f2 -d~ done
El script, como siempre, comienza testando si los parámetros fueron pasados correctamente, en seguida el $ listartista Artista1
Artista1~Musica1
Musica1
Artista1~Musica3
Musica3
Artista10~Musica10
Musica10
Epa! Pasaron dos cosas no deseadas: los bloques también fueron listados y la
Para que eso no ocurriese, debería pasar el nombre del artista entre comillas ( echo "$ArtMus" | grep clitandro & eduviges Lo que resultaría en un error. Lo corretco sería: echo "$ArtMus" | grep -i "clitandro & eduviges"
Donde fue colocada la opción
Todavia falta arreglar el error de haber listado al $ cat listartista
#!/bin/bash
# Dado un artista, muestra sus músicas
# versao 2
if [ $# -eq 0 ] then echo Usted debería haber pasado un parámetro exit 1 fi IFS=" :" for ArtMus in $(cut -f2 -d^ musicas) do echo "$ArtMus" | grep -i "^$@~" > /dev/null && echo $ArtMus | cut -f2 -d~ done Que ejecutado da: $ listartista Artista1
Musica1
Musica3
Segunda sintáxis del comando for:for var do cmd1 cmd2 cmdn done
- Espera ahí!, sin el
- Eso mismo, no? Esta construcción a primera vista parece extraña pero es bastante simple. En este caso, Vamos rapidito a los ejemplos para entenderlo mejor. Vamos a hacer un script que reciba como parámetro una cantidad de músicas y liste sus autores: $ cat listamusica
#!/bin/bash
# Recibe parte de los nombres de músicas como parámetro y
# lista los intérpretes. Si el nombre es compuesto, debe
# ser pasado entre comillas.
# ex. "No soy tu perrito, no!" "Asadito de Madre"
#
if [ $# -eq 0 ]
then
echo Uso: $0 musica1 [musica2] ... [musican]
exit 1
fi
IFS="
:"
for Musica
do
echo $Musica
Str=$(grep -i "$Musica" musicas) ||
{
echo " No encontrada"
continue
}
for ArtMus in $(echo "$Str" | cut -f2 -d^)
do
echo " $ArtMus" | grep -i "$Musica" | cut -f1 -d~
done
done
De la misma forma que los otros, comenzamos el ejercício con una crítica sobre los parámetros recibidos, en seguida hicimos un Como siempre vamos a ejecutarlo para ver si realmente funciona: $ listamusica musica3 Musica4 "Yegüita Pocotó"
musica3
Artista3
Artista1
Musica4
Artista4
Yegüita Pocotó
No encontrada
La lista quedó fea porque todavia no sabemos dar formato a la salida, pero cualquier día de estos, cuando sepas posicionar el cursor, hacer negritas, trabajar con colores, etc, haremos esta lista nuevamente usando todas estas perfumerías y entoces quedará bien coqueto.
A esta altura de los acontecimientos debes estar preguntandote: "Y aquél
Y es ahí donde te respondo: "Yo no te dije que nuestro 1 - con la primera sintáxis que vimos, como en los siguientes ejemplos directamente en el prompt: $ for i in $(seq 9)
> do
> echo -n "$i "
> done
1 2 3 4 5 6 7 8 9
Aquí, la variable $ for i in $(seq 3 9)
> do
> echo -n "$i "
> done
4 5 6 7 8 9
O todavia en la forma más completa del
$ for i in $(seq 0 3 9)
> do
> echo -n "$i "
> done
0 3 6 9
2 – La otra forma de hacer lo deseado es con una sintáxis muy parecida al
Tercera sintáxis del comando for:for ((var=ini; cond; incr)) do cmd1 cmd2 cmdn done Donde:
Como siempre vamos a los ejemplos y la cosa quedara más fácil: $ for ((i=1; i<=9; i++))
> do
> echo -n "$i "
> done
1 2 3 4 5 6 7 8 9
En este caso la variable
Fíjate que en el
Como me referí al comando $ for ((; i<=9;))
> do
> let i++
> echo -n "$i "
> done
1 2 3 4 5 6 7 8 9
Observa que el incremento desapareció del cuerpo del for y pasó dentro del bloque de comandos, fíjate también que cuando usé el $ echo $j
$ let j++ $ echo $j 1
O sea, la variable Fíjate en lo simples que son las cosas: $ for arq in *
> do
> let i++
> echo "$i -> $Arq"
> done
1 -> ArqDoDOS.txt1
2 -> confuso
3 -> incusu
4 -> listamusica
5 -> listartista
6 -> logado
7 -> musexc
8 -> musicas
9 -> musinc
10 -> muslist
11 -> testefor1
12 -> testefor2
- Y hasta aqui amigo!, tengo la seguridad que hoy tomaste una buena dosis de jarabe del comando
OBS: Esa cuenta tiene que ser hecha usando el comando for para que te habitues a su uso. No vale usar o
- Chico! Tráeme, por favor la del estribo! Y no te olvides, cualquer duda o falta de compañia para tomar una cerveza o hasta para hablar mal de los políticos lo único que tienes que hacer es mandarme un e-mail para julio.neves@gmail.com. Voy aprovechar también para mandar mi aviso publicitario: puedes decirle a los amigos que quien quiera hacer un curso nota diez de programación en Shell que mande un e-mail para julio.neves@uniriotec.br para informarse. Gracias y hasta la próxima -- HumbertoPina - 20 Oct 2006 |
||||||||||
Licencia Creative Commons - Reconocimiento y no comercial (CC) 2009 Por Visitantes del Bar de Júlio Neves. Todo el contenido de esta página puede ser usada de acuerdo a la Creative Commons License: Atribuição-UsoNãoComercial-PermanênciaDaLicença. |