[COMO] Usos del shell

Imagen de Gabriel_M
11,573 puntos

Además de usar el shell para ejecutar comandos, puedes usar su lenguaje de programación para escribir tus propios comandos o programas. Puedes poner comandos en el archivo (conocido como shell script) y después ejecutar el archivo como un comando o programa.

 

EL Bourne shell (sh) está disponible en todos los sistemas UNIX. Los scripts del Bourne shell también pueden trabajar bajo el Bourne Again Shell (bash). Los shells C y TC usan un lenguaje de programación similar al lenguaje C.

 

Creación y ejecución de shell scripts simples

 

Para crear un shell script simple, debes poner líneas de comando en un archivo, darle los permisos de acceso apropiados y después ejecutar el archivo.

 

Este es el contenido de un shell script llamado display :

 

cat display

# Este script displaya la fecha, hora, nombre de

# usuario y directorio actual

echo "Fecha y hora:"

date

echo

echo "Tu usuario es: `whoami` \\n"

echo "Tu directorio actual es: \\c"

pwd

 

Las primeras dos líneas que comienzan con una almohadilla (#) son comentarios y no son interpretadas por el shell.

 

Las backquotes (`) entre el comando whoami ilustran el uso de la sustitución de comandos.

 

- sustitución de comandos : para incluir la salida de un comando dentro de una línea de comandos de otro comando, encierra el comando cuya salida quieres incluir, entre backquotes (`)

 

- whoami : muestra el usuario actual

 

\\n es una opción del comando echo que dice al shell que añada un retorno de carro al final de la línea. \\c dice al shell que permanezca en la misma línea.

 

(si utilizas el shell bash, para que funcionen estas opciones tienes que poner echo -e )

 

Antes de usar el archivo como shell script debemos cambiar los permisos de acceso. Para dar permiso de ejecución al archivo deberemos usar el comando :

 

chmod u+rwx display

 

El +rwx después de la u te permiten leer, escribir y ejecutar el script, nadie mas tendrá permiso para hacerlo.

 

Para dar permiso a otros usuarios para leer y ejecutar el shell script usa :

 

chmod go+rx display

 

Programación con Bourne Shell

 

El shell también te ofrece un entorno de programación con características similares a las de los lenguajes de programación de alto nivel.

 

Pasando argumentos al shell

 

Los shell scripts pueden actuar igual que los comandos standard de Unix y tomar argumentos desde la línea de comandos.

 

La forma de pasar estos comandos es con los parámetros posicionales $1 hasta $9. Cada parámetro corresponde a la posición del argumento en la línea de comandos.

 

El parámetro posicional $0 hace referencia al nombre del comando o nombre del archivo ejecutable que contiene el shell script.

 

Solo se pueden pasar nueve argumentos, pero se puede acceder a mas de nueve usando el comando shift. Cada vez que se ejecuta el comando shift el argumento 1 desaparece, el 2 se convierte en el uno, y así sucesivamente hasta el 9 que se convierte en el 8 quedando aquel libre.

 

Se puede hacer referencia a todos los parámetros que se están pasando usando el parámetro especial $*. Esto es especialmente útil cuando se pasan nombres de archivos como argumentos, por ejemplo :

 

cat printps

# Este script convierte archivos ASCII a PostScript

# y los envía a la impresora PostScript ps1

# Usa la utilidad local "a2ps"

a2ps $* | lpr -Pps1

 

printps elm.txt vi.ref msg

 

Ejemplo de paso de argumentos :

 

cat first_5args

# Este script lista los cinco primeros argumentos

echo Los cinco primeros argumentos de la línea

echo de comandos son $1 $2 $3 $4 $5

 

first_5args mines a pint john o.k.

 

Manejo de variables

 

Existen algunas variables que se establecen automáticamente con tu login.

 

Los valores de algunas de estas variables esta guardados en nombres que colectivamente son llamados 'tu entorno de usuario'.

 

Cualquier nombre definido en tu entorno de usuario, puede se accedido por un shell script. Para incluir el valor de una variable shell en tu entorno debes exportarla.

 

(Si se modifica el valor de una variable, este permanece hasta que efectúas el logout del sistema o sales del shell en el cual estas trabajando. Para hacer que otros programas que usan la variable tengan consciencia del cambio debes teclear el comando export variable).

 

Algunas variables establecidas internamente por el shell y que están disponibles para el usuario:

 

$1 - $9 parámetros posicionales

$0 nombre del comando actual

$# número de parámetros posicionales

$? exit status del último comando ejecutado

dado como un string decimal. Si todo ha

ido bien se retorna cero.

$$ el numero de proceso de este shell, útil

para incluirlo en nombres de archivos

para hacerlos únicos.

$! la pid del último comando ejecutado en

background.

$- las opciones actuales suministradas para

esta invocación del shell.

$* un string que contiene todos los

argumentos del shell comenzando por el $1.

$@@ igual que el anterior, excepto cuando va

entrecomillado.

 

Reglas que gobiernan la evaluación de variables shell :

 

$var significa el valor de la variable

o nada si la variable no está

definida.

 

${var} igual que el anterior excepto que

las llaves contienen el nombre de

la variable a ser sustituida.

 

${var-thing} valor de var si var está

definida, si no thing.

 

${var=thing} valor de var si var está

definida, si no thing y

el valor de var pasa a ser thing

 

${var?message} Si definida, $var; si no, imprime

el mensaje y terminal el shell.

Si el mensaje esta vacío imprime

un mensaje standard.

 

${var+thing} thing si $var esta definida, si

no nada.

 

Entrecomillados y caracteres especiales

 

Caracteres especiales para terminar palabras :

 

; & ( ) | ^ < > nueva-linea espacio tab

 

Para entrecomillar estos usa el backslsh (\) o llaves con comillas.

 

Comillas simples :

 

Entre comillas simples todos los caracteres son entrecomillados incluido el backslash.

 

grep : ${gid}: /etc/group | awk -F: '{print $1}'

 

Dobles comillas :

 

Entre dobles comillas se produce sustitución de variable (el signo del dolar se interpreta) pero no generación de archivo ( * y ? son entrecomillados)

 

Comillas contrarias :

 

Las comillas contrarias significan ejecutar el comando y sustituir por la salida.

 

TODAY=`(set \`date\`; echo $1)`

 

Leer de la entrada standard.

 

Para leer de la entrada standard se utiliza el comando read, por ejemplo :

 

echo "Por favor introduzca su nombre:"

read nombre

echo "Bienvenido $nombre"

 

echo "Introduce tu apellido\n"

echo "seguido de tu nombre: \c"

read apellido nombre

echo "Bienvenido a Madrid $nombre $apellido"

 

Entrada standard : la fuente de información para un comando. Por defecto es el teclado a menos que se redireccione a un archivo o a otro comando.

 

Para redireccionar la entrada o salida standard se usa :

 

cambiar la entrada = < mail gerardo < documento

cambiar la salida = > grep gerardo /etc/passwd > mi_passw

añadir a la salida = >> cat parte2 >> mi_libro

 

También se pueden utilizar pipes. Unix permite enlazar dos o mas comandos usando un pipe. El pipe toma la entrada standard de la salida estandard de otro comando. La | (barra vertical) se usa para representar la conexión de los comandos.

 

Ejemplos :

 

who | wc -l

342

 

Este comando dice cuantos usuarios están conectados al sistema.

who saca por la salida standard una lista de usuarios conectados al sistema

wc -l cuenta el numero de líneas de la entrada standard y lista el resultado.

 

ps -aux|grep joe|sort +5 -6|less

 

El primer comando ps -aux saca información sobre los procesos que corren

actualmente. Esta información entra a la entrada del comando grep joe que busca

una línea que contenga el usuario "joe". La salida de este comando se clasifica

por el sexto campo de cada línea y esta salida se displaya en el less.

 

Instrucciones condicionales.

 

Cada comando Unix retorna un valor de salida el cual puede ser consultado. Este valor está guardado en la variable de solo lectura $?. El valor 0 es bueno, cualquier otro es malo.

 

La instrucción if usa el status del último comando y condicionalmente ejecuta la siguiente instrucción. La sintaxis general es :

 

if test

then

comandos

else

comandos

fi

 

then, else, y fi son palabras reservadas y como tales únicamente serán reconocidas después de una nueva línea o ;(punto y coma). Asegúrate de que terminas cada if con su fi correspondiente.

 

El if se puede anidar :

 

if ...

then ...

else if ... (también se puede usar elif en lugar de else if)

...

fi

fi

 

Ejemplo de if :

 

if who | grep -s keith >/dev/null

then

echo keith está conectado

else

echo keith no está conectado

fi

 

La lista de who se pasa a grep para buscar al usuario keith, la opción -s

consigue que grep trabaje silenciosamente y cualquier mensaje de error es

direccionado al archivo /dev/null.

Dependiendo de que keith se encuentre o no en la lista de usuarios se saca

un mensaje u otro.

 

El operador && se usa para ejecutar un comando, y si es correcto, ejecuta el siguiente comando en la lista. Por ejemplo,en comando1 && comando2, se ejecuta primero comando1 y si es correcto se ejecuta comando2. Esto es equivalente a :

 

if comando1

then

comando2

fi

 

El operador || se usa para ejecutar un comando, y si falla, ejecuta el siguiente comando de la lista. Por ejemplo, en comando1 || comando2, se ejecuta primero comando1 y si falla se ejecuta comando2. Esto es equivalente a :

 

comando1

if test $? -en 0

then

comando2

fi

 

Comprobación de archivos y variables con el comando Test

 

El shell usa un comando llamado test para evaluar expresiones condicionales.

 

test devuelve 0 (verdadero) o 1 (falso), opciones :

 

-b archivo - Verdadero si archivo existe y es un block special.

-c archivo - Verdadero si archivo existe y es un character special.

-d archivo - Verdadero si archivo existe y es un directorio

-e archivo - Verdadero si archivo existe

-f archivo - Verdadero si archivo existe y es un regular file.

-g archivo - Verdadero si archivo existe y es un set-group-id.

-k archivo - Verdadero si archivo tiene su ``sticky'' bit set.

-L archivo - Verdadero si archivo existe y es un symbolic link.

-p archivo - Verdadero si archivo existe y es un named pipe.

-r archivo - Verdadero si archivo existe y es un readable.

-s archivo - Verdadero si if file existe tiene un tamaño > 0.

-S archivo - Verdadero si archivo existe y es un socket.

-t [fd] - Verdadero si fd está abierto en un terminal.

Si fd es omitido, su defecto es 1 (standard output).

-u archivo - Verdadero si archivo existe y su set-user-id bit is set.

-w archivo - Verdadero si archivo existe y es un writable.

-x archivo - Verdadero si archivo existe y es un ejecutable.

-O archivo - Verdadero si archivo existe y es un owned by the effective user id.

-G archivo - Verdadero si archivo existe y es un owned by the effective group id.

 

archivo1 -nt archivo2 - Verdadero si archivo1 es mas nuevo

(according to modification date) que archivo2.

archivo1 -ot archivo2 - Verdadero si archivo1 is mas viejo que archivo2.

archivo1 -ef archivo2 - Verdadero si archivo1 y archivo2 tienen el mismo numero de

device and inode.

 

-z string - Verdadero si la longitud de string es 0.

-n string - Verdadero si la longitud de string no es 0.

 

string1 = string2 - Verdadero si los strings son iguales

string1 != string2 - Verdadero si los strings no son iguales.

! expr - Verdadero si expr es falso.

expr1 -a expr2 - Verdadero si expr1 y expr2 son verdaderos.

expr1 -o expr2 - Verdadero si expr1 o expr2 es verdadero.

arg1 OP arg2 - OP es uno de -eq, -ne, -lt, -le, -gt, or -ge.

-l string - evalua la longitud de string.

 

Instrucciones de control

 

La instrucción case

 

El flujo del programa se controla en base a una palabra dada. Esta palabra se compara con cada patrón hasta que se encuentra uno que haga juego. Cuando se encuentra, se ejecuta el comando asociado y se termina la instrucción.

 

case palabra-dada in

patrón1) comandos

;;

patrón2|patrón3) comandos

;;

patrónN) comandos

;;

esac

 

Un comando puede asociarse con mas de un patrón. Los patrones pueden separarse unos de otros con el símbolo | . El orden de chequeo es el orden en que aparecen los patrones.

 

Para especificar un patrón por defecto se pueden usar wildcards :

 

? comprueba un carácter

* comprueba cualquier número de cualquier

tipo de caracteres

[nnn] comprueba cualquiera de los caracteres

entre corchetes

[!nnn] comprueba cualquier carácter que no este

entre los corchetes

[n-n] comprueba cualquier carácter en el rango

 

La instrucción for

 

El bucle for sigue la siguiente notación general :

 

for variable in lista-de-palabras

do

comandos

done

 

Comandos es una secuencia de uno o mas comandos separados por una línea o por un ; (punto y coma).

 

Las palabras reservadas do y done deben estar precedidas por una línea o por un ; .

 

for variable in lista; do comandos; done

 

Ejemplos :

 

#!/bin/sh

# por cada usuario dado como argumento se

# comprueba si está conectado o no y se da

# el mensaje apropiado

for i in $*

do

if who | grep -s $i > /dev/null

then

echo $i está conectado

else

echo $i no está conectado

fi

done

 

#!/bin/sh

# compara un archivo con el mismo archivo en

# el directorio ?old?

for i in *

do

echo $i:

cmp $i old/$i

echo

done

 

#!/bin/sh

# si la lista-de-palabras se omite, el bucle se

# ejecuta una vez por cada argumento (asume $*)

# Crear los archivos pasados como argumento

for y

do

> $y

done

 

Las instrucciones while y until

 

La instrucción while tiene la forma general :

 

while lista-de-comandos1

do

lista-de-comandos2

done

 

Los comandos de lista-de-comandos1 se ejecutan, y si el status del último comando de la lista es 0, se ejecutan los comandos de lista-de-comandos2.

 

La sequencia se repite mientras el status de lista-de-comandos1 es 0.

 

La instrucción until tiene la forma general :

 

until lista-de-comandos1

do

lista-de-comandos2

done

 

Su función es idéntica a while excepto en que el bucle se ejecuta mientras en status de lista-de-comandos1 no es 0.

 

Ejemplos :

 

#!/bin/sh

while who |grep -s $1 >/dev/null

do

sleep 60

done

echo "$1 está desconectado?

 

El script verifica si el usuario que se pasa como argumento está conectado, mientras

lo está el script espera 60 segundos antes de hacer una nueva verificación.

 

#!/bin/sh

until test -f $FILE

do

sleep 60

done

echo "$FILE now exists"

 

Verifica cada 60 segundos si existe el archivo representado por la variable $FILE.

 

Las instrucciones break y continue.

 

La instrucción break termina la ejecución del bucle mas interior causando la ejecución de la instrucción done mas cercana.

 

Para salir del nivel n, usa : break n, esto causa la ejecución de la instrucción done n.

 

El comando continue causa la ejecución de la instrucción while, until o for en la cual comienza el bucle que contiene el comando continue.

 

Ejemplo :

 

#!/bin/sh

while echo "Por favor introduce un comando"

read respuesta

do

case "$respuesta" in 'fin')

break # no mas comandos

;;

"")

continue # comando nulo

;;

*)

eval $respuesta # ejecuta el comando

;;

esac

done

 

Mientras el usuario introduzca un comando o un string

nulo el script continua funcionando. Para pararlo el

usuario debe teclear ?fin?.

 

Mas funciones shell

 

Aritméticas

 

No existen funciones aritméticas en el shell y por tanto hay que usar el comando expr que sirve para evaluar expresiones matemáticas (ver man expr).

 

Incluir texto en un shell script

 

Se puede incluir texto en un shell usando una forma especial de redireccionamiento. El símbolo << se usa para indicar que el texto debe ser leído hasta una marca dada, por ejemplo :

 

#!/bin/sh

# Este script muestra el mensaje dado, antes de ejecutarse

cat << EOF

Este shell script esta actualmente en desarrollo, por favor

reporte cualquier problema a Daniel. Gracias.

EOF

exec /usr/local/test/bin/test_version

 

Forzar la evaluación de comandos

 

La función eval toma los argumentos de la línea de comandos y los ejecuta como comandos.

 

Por ejemplo :

 

#!bin/sh

echo ?enter a command:?

read command

eval $command

 

Ejecutar un comando sin crear un nuevo proceso

 

Exec ejecuta un comando sin crear un nuevo proceso. Una vez terminada la ejecución el shell continúa.

 

exec zmail -visual

Ejecuta zmail y cuando termina continúa el shell.

 

Controlar la finalización de un shell script

 

Para finalizar un shell script se utiliza el comando exit. Se le puede dar un argumento numérico que toma como status. Si se omite el status será el del último comando ejecutado. Por ejemplo exit 2, devuelve status=2.

 

Tratar las señales del sistema operativo

 

El comando trap se puede usar para capturar o ignorar las señales del sistema operativo. El formato del comando trap es :

 

trap ?lista-comandos? lista-señales

 

Varios traps pueden tener efecto al mismo tiempo. Si se reciben varias señales simultáneamente, serán despachadas en orden ascendente. Para comprobar que traps están establecidas, usa el comando trap sin argumentos.

 

Las señales mas comunes para usar con trap son :

 

0 - salida del shell (por cualquier razón, incluido fin de

archivo)

1 - colgar

2 - interrupción (^C)

3 - quit (^\\ ; causa que el programa produzca un core dump)

9 - kill (no puede ser parada ni ignorada)

15 - terminate; señal por defecto generada por kill

 

Funciones creadas por el programador

 

Las funciones son herramientas poderosas a menudo poco usadas. La sintaxis es:

 

nombre_funcion ()

{

comandos

}

 

Dentro de una función los parámetros posicionales $0, $1, etc. son los argumentos de la función (no los argumentos del script).

 

Dentro de una función se usa return en lugar de exit.

 

Depuración de Shell scripts

 

Para ver donde se produce un error en un script usa el comando :

 

sh -x script argument

 

La opción -x del comando sh lista los comandos y sus argumentos que son ejecutados. Así puedes ver qué partes del script se han ejecutado cuando ocurre el error.

 

La opción -n del comando sh hace que no se ejecute ningún comando, solo chequea la sintaxis.

 

La opción -e en modo no interactivo, hace que si un comando falla se termine inmediatamente el script.

 

La opción -v imprime las líneas de entrada según son leídas

Imagen de julianarmando
+1
0
-1

Yo me pregunto si la shell de alguna manera se podrá integrar junto con otro lenguaje o lanzar algun archivo para mostrar un mensaje pero de entorno gráfico.. me explico.

Que por ejemplo se mostrara con un "echo "loquesea";" pero no en la consola sino en un cuadro en la mitad de la pantalla, como si fuera java :)

Mi blog personal donde hablo mucho de Ubuntu y Linux en general Juarbo - Linux y Tecnología Avanzada

+1
0
-1

Mi blog personal donde hablo mucho de Ubuntu y Linux en general Juarbo - Linux y Tecnología Avanzada

Imagen de quest10
+1
0
-1

julianarmando, así a bote pronto se puede usar zenity o notify-osd. Echale un ojo. ;)

+1
0
-1
Imagen de Inukaze
+1
0
-1

Hola muy buenas , miren estoy haciendo un mini-scripts para slackware que instale google y escriba manualmente la asociacion de archivos "*.crx" . pero algo no me resulta como deseo usando "echo" en "bash"

Miren aqui un ejemplo de tantas lineas que he intentado :

sudo sh -c 'echo "<?xml version="1.0" encoding="utf-8"?>" >> /usr/share/mime/application/x-google-chrome.xml'

Okey , la cuestion es que cuando se escribe dentro de ese archivo la linea queda sin las comillas , de esta menra

<?xml version=1.0 encoding=utf-8?>

y necesito que quede "literalmente" , osea = <?xml version="1.0" encoding="utf-8"?> , necesito que quede con el entrecomillado , para que el sistema lea bien el archivo de configuracion.

Alguien sabe si se puede hacer con echo o tengo que usar algun comando distinto ???

+1
0
-1