Sirviendo información sobre Linux desde 1998

Bash (III) - Variables y funciones

En nuestra tercera entrega sobre el interprete de comandos Bash vamos a empezar a ver como podemos usar de forma practica la informacion que hemos visto en los articulos anteriores. Para empezar y antes de entrar en materia, nada mejor que un ejemplo del clasico "Hola Mundo" en Bash.

#!/bin/bash
#
# Esto es un ejemplo en Bash del clasico "Hola Mundo"
#

echo "Hola Mundo"

Como podeis ver, nada dificil para empezar. Empecemos a explicar un poco que significa cada linea:

#!/bin/bash: Esta linea indica donde se encuentra el interprete de comandos en nuestro sistema. Por defecto todos los sistemas que tengan Bash instalado, lo tendran en el directorio /bin. Al utilizar esta linea, podremos ejecutar el script como un programa normal, ya que el sistema sabra que es un script en Bash y que tiene que hacer con el.

Si el script de ejemplo lo hubiesemos grabado como ejemplo.sh, lo podriamos ejecutar de la siguiente manera:

[ralfm@desktop]# chmod ugo+x ejemplo.sh
[ralfm@desktop]# ./ejemplo.sh 
Hola Mundo

# Esto es un ejemplo en Bash del clasico "Hola Mundo": Esto es un comentario. Todas las lineas que empiecen con el simbolo '#' seran tratadas como comentarios y no se ejecutaran.

echo "Hola Mundo": Esto es el comando que imprime la cadena de texto en pantalla.

Variables

En todo script tendreis que trabajar con variables, mas tarde o mas temprano. Vamos a ver como se definen y usan. Una buena costumbre cuando definamos variables en Bash es utilizar letras mayusculas, esto no es necesario, pero nos ayudara a tener un script mas facil de entender.

Definiendo una variable

#!/bin/bash
#
# Esto es un ejemplo en Bash del clasico "Hola Mundo"
#

MENSAJE="Hola Mundo"
echo $MENSAJE

Hemos definido una variable llamada MENSAJE con el valor "Hola Mundo", y la hemos usado con el comando echo para escribir el valor de la misma. Las variables en Bash se definen como NOMBRE=valor (sin espacios antes o despues del simbolo '=') y su valor se usa, poniendo el simbolo '$' delante del nombre de la variable, $NOMBRE.

Si al utilizar el valor de una variable, el nombre de variable esta seguido de un caracter que sea otra letra, numero o el simbolo '_', tendremos que utilizar los simbolos '{}' alrededor del nombre de la variable.

#!/bin/bash

FICHERO="registro"
echo ${FICHERO}_2006.txt

Usando variables de entorno

#!/bin/bash

echo "El usuario '$USERNAME' ha ejecutado el script $0, en el ordenador '$HOSTNAME'. "

Tambien se pueden usar en nuestro scripts, variables que no hemos definido nosotros. Estas variables son las llamadas 'variables de entorno' del sistema. Teneis una lista con las mas importantes por defecto, en el segundo articulo de esta serie, Bash (II) - Comandos, variables de entorno y combinaciones de teclas. En nuestro ejemplo hemos utilizado $USERNAME y $HOSTNAME para obtener el nombre de usuario y del ordenador. La variable $0 contiene el nombre del script, mas adelante explicaremos esto.

Asignado resultados de comandos a variables

#!/bin/bash

ATRIBUTOS_SCRIPT=`/bin/ls -l $0`

echo "El usuario '$USERNAME' ha ejecutado el script $0, en el ordenador '$HOSTNAME'. "
echo "Los atributos del script son: "
echo $ATRIBUTOS_SCRIPT

Tambien podemos asignar la salida que producen los comandos del sistema a una variable. En nuestro ejemplo hemos asignado la salida del comando 'ls -l a una variable llamada ATRIBUTOS_SCRIPT. Esto nos sera muy util en nuestros scripts para obtener informacion del sistema que podremos utilizar en nuestros scripts.

Usando caracteres especiales en variables

Existen una serie de caracteres que tienen un significado especial en Bash, por ejemplo $ y ". Si queremos usar literalmente estos caracteres en el valor de una variable tendremos que usar el simbolo '\' delante de ellos.

#!/bin/bash

MENSAJE="\"Hola Mundo ...\""
echo "El valor de la variable \$MENSAJE es $MENSAJE"

Variables numericas

Si queremos definir variables numericas para su utilizacion en scripts Bash podemos utilizar el comando let. Nada mejor que un ejemplo para ver como se trabaja con variables numericas.

#!/bin/bash

let A=100
let B=200
let C=$A+$B

echo "A: $A | B: $B | C: $C"

Funciones

En Bash se pueden definir funciones. Una funcion en Bash (denominada subrutina o procedimiento en otros lenguajes de programacion) se podria definir como un script dentro de un script. Sirve para organizar un script en unidades logicas de manera que sea mas facil mantenerlo y programarlo. En Bash las funciones se pueden definir de la siguiente manera:

function nombre_de_funcion(){
  comandos_del_shell
}

Un ejemplo de funcion en un script:

#!/bin/bash

let A=100
let B=200

#
# Funcion suma()
# Suma los variables A y B
#
function suma(){
 let C=$A+$B
 echo "Suma: $C"
}

#
# Funcion resta()
# Resta los variables A y B
#
function resta(){
 let C=$A-$B
 echo "Resta: $C"
}

suma
resta

En fin, esto es todo por hoy. En la proxima entrega hablaremos de las estructuras condicionales: if/else, for, case, select y while/until.

Libros recomendados sobre el tema (solo en ingles), para profundizar y tener a mano todos los detalles:

Articulos anteriores relacionados:

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Hola, Gracias por esta

Hola, Gracias por esta información.

Imagen de AnimAlf

Thnks

No te lo pierdas el siguiente que publicó, es muy cañero: Bash (IV) - Estructuras de control y bucles

SaludOS

que significa el signo $

que significa el signo $ cuando lo utilizamos en codigo.

un ejemplo:

for ((i=32; i<127; i++)); do
ascii="$ascii$(echo -en $(printf "%s%o" "\\" "$i"))"
done
muchas gracias dpor su colaboracion

Imagen de AnimAlf

Antes del parentesis, es para

Antes del parentesis, es para ejecutar algo de shell, es lo equivalente a ponerlo entre estas comillas `lo que se quiera ejecutar`, por ejemplo:

$(ls -l)
o
`ls -l`

si antecede a una palabra, es una variable, cuando se declara la variable no se pone el simbolo, pero cuando se hace referencia a ella sí:

variable=3
echo $variable

Creo que queda claro, luego están las referencias a los argumentos de la llamada al script y el pid (identificador de proceso)

por ejemplo el archivo con el siguiente archivo prueba.sh

#!/bin/bash
ESTO="Más cosas\n"
echo  el pid de $0 es: $$
echo el nombre del script es: $0
echo el primer parámetro: $1
echo el segundo parámetro: $2
printf "${ESTO}Veamos la versión del kernel: $(uname -r)\n"

lo guardas en un archivo, y le das permiso de ejecución chmod a+x prueba.sh y lo lanzas del siguiente modo, por ejemplo

./prueba.sh uno otro

SaludOS

como un comentario jeje literalmente

estaria bien que actualizaras los enlazes con las siguientes partes, me refiero que estoy leyendo la guia y no me interesa ver las entregas pasadas sino continuar con la siguiente entrega, gracias

Funcion Tecla

Buenas tengo un problema que no me funciona esta tecla y no se por que.
menu_prog ()
{
clear
echo -e $BLUE"4) Instalación de Programas:"$ENDCOLOR
echo ""
echo -e "NOTA: Se instalarán los programas que escojamos, simplemente escribimos \"s\" o \"n\" según queramos o no. Para más información acerca del programa, seleccionalo.\n"
echo -e $GREEN" 1) xxxx"
echo " a) COMPILADORES"
echo ""
echo " 0) Instalar TODOS los programas"
echo -e " S) Volver al Menú\n"$ENDCOLOR
echo -n "Escoge una opción: "

La tecla S de volver al menu no me funciona alguien sabe por que?

variable real

como declaro una variable real ¿??

declare XXX NUMERO
NUMERO=23/4
echo " resultado decimal es " $NUMERO

Utilizando el programa bc

Los reales son un poco engorrosos en BASH. Pero puedes utilizar el programa bc para trabajar con ellos, te dejo un ejemplo.

#!/bin/bash

NUMERO1=20.1
NUMERO2=2.5

RESULTADO=`echo "$NUMERO1 + $NUMERO2" | bc`

echo $RESULTADO

--
Rafael Martinez
Webmaster

Pequeño problema.

#!/bin/bash
echo "Inserta un número: "
read Num1
echo "Inserta otro número: "
read Num2
echo "Selecciona la operación que quieres realizar: "
echo "1.- Suma"
echo "2.- Resta"
echo "3.- Producto"
echo "4.- División"
read opcion
case $opcion in
1)
$Res=`echo "$Num1 + $Num2"`;;
*)
echo "Prueba después.";;
esac

Me sale lo siguiente:
Inserta un número:
1
Inserta otro número:
1
Selecciona la operación que quieres realizar:
1.- Suma
2.- Resta
3.- Producto
4.- División
1
segundo.sh: 17: =1: not found

Los números si me los pide, pero a la hora de hacer la operación algo falla, y no sé lo que es :s
Muchas graciasi :)

Re: Pequeño problema.

$Res=`echo "$Num1 + $Num2"`;;

El problema esta en esta linea. La puedes cambiar por esto:

Res=$Num1+$Num2
echo Res
;;

O por esto:

echo $Num1+$Num2;;

Me da "1+1", me devuelve la

Me da "1+1", me devuelve la operación, no el resultado :s

Re: Me da "1+1", me devuelve la

Te falta definir que Num1 y Num2 van a tener valores numéricos y no alfanuméricos.

let Num1=0
let Num2=0

En este mismo artículo tienes una sección sobre esto "Variables numéricas"

--
Rafael Martinez
Linux-es.org

let not found

No encuentra la orden ._.

nombres de archivos con espacio

bueno, tengo problemas con los nombres de archivos con espacio, he simplificado mi script a:

FICHEROS_ORIGEN="/mnt/data/prueba\ base"
ls ${FICHEROS_ORIGEN}

en la línea de comando teclee:

$ ./prueba.sh
ls: no se puede acceder a /mnt/data/prueba\: No existe el fichero o el directorio
ls: no se puede acceder a base: No existe el fichero o el directorio

se me escapa la tortuga en algún lado, agradeceria su ayuda.

fernando

Problema en proceso

Tengo el siguiente script

#!/bin/bash
rdesktop 10.1.2.8;
sleep 2;
/usr/games/glchess

Quiero que dos programas se ejecuten uno despues del otro con cierto retardo, el problema es que hasta que no cierre secion no ejecuta el otro programa.
Gracias d ante mano por la ayuda...

$$variable

Y si quiero optener el valor del argumento dado por una variable, ¿cónmo sería?

$arg=3
${$arg} he probado con esto y no me sale.

Gracias de antemano

Re: $$variable


$arg=3
${$arg} he probado con esto y no me sale.

Prueba con:

arg=3
echo ${arg} 

VARIABLE

Y COMO PASO EL VALOR DE UNA VARIABLE POR PARAMETRO??

curioso ( $0)

Hola

cat pru.sh

#!/bin/ksh
echo " $0 "

- Si se ejecuta :
pru.sh

$0 es igual a pru.sh. Vale correcto.

Pero si lo ejecutamos asi :

. pru.sh

$0 es igual a '-ksh' ... en este ultimo caso
¿ como obtener el nombre del programa ( pru.sh ) ?

Gracias.

COMO SUMO

i al cuadrado + i cuando i=1 hasta que vale 30

case

yo habria puesto el case de la siguiente manera:

case $opcion in
1)let res=$Num1+$Num2;echo $res
;;
*)
echo "Prueba después.";;
esac

tengo porblema con el script

tengo el siguiente problema no me corre el programa me da porblema el case

#programa ; script final
opcion=0;
while [ $opcion -ne 12 ];
do
clear
echo "COMANDOS LINUX"
echo ""

echo "A)Despliega el calendario del mes actual"
echo "B)Muestra en pantalla el espacio ocupadoy el espacio libre en el disco"
echo "C)realiza la creacion de un directorio"
echo "D)Muestra los directorios exitentes y sus propiedades"
echo "E)Ordena los usuarios existentes "
echo "F)muestrame que usuario soy "
echo "G)verificar el estado de la memoria"
echo "H)verificar los procesos del sistema operativo demonios"
echo "I)Muestra la cantidad de espacio swap del sistema"
echo "J)agrega el usuario brasil a root"
echo "K)asignale el alias crear al comando para crear variable y realiza una de estas"
echo "L)crea un directorio con el nombre que se te ocurra"
echo "Z)good bye "
echo ""
echo -ne " HAS RELAIZADO: "
read opcion
case $opcion in
A) cal
sleep 3;;
B) df
sleep 3;;
C)echo escribe el nombre del directorio a crear
read direc
mkdir -p $direc
echo el directorio $direc ya esta funcionando en el servidor
sleep 6;;
D) ls -la
sleep 6;;
E) who| sort
sleep 4;;
F) who
sleep 5;;
G) free
sleep 5;;
H) ps- fea
sleep 6;;
I) grep swapTotal /proc/meminfo
sleep 6;;
J) usermod -a -g brasil root
echo el usuario a sido creado en root
sleep 7;;
K) echo tecle el alias deseado y enseguida crea la variable MUNDIAL
=> alias crear= "env| grep MUNDIAL" && crear
sleep 5;;
L) echo escribe el nombre del directorio a crear
read direc
mkdir -p $direc
echo el directorio $direc ha sido creado
sleep 6;;
Z) exit
sleep 5;;

Lo solucionarás con expr

$Res=`echo "$Num1 + $Num2"`;;
1) el primer $, lo quitas

Res=`expr $Num1 + $Num2`;
echo "El resultado de la Suma es $Res";;

felicidades

Excelente tutorial.

Saludos

ayuda con scripts

Hola me podrian ayudar a resolver estos scripts

1.Escribir un script de tal manera que le solicite al usuario un número, el cual deberá tener un valor entre el rango del 11 al 40.

A partir del valor ingresado, deberá aparecer en pantalla los números desde el ingresado por el usuario hasta el cero, en orden descendente.

Por ejemplo:

12
11
10
9
8
7
6
5
4
3
2
1
0

2.Explicar detalladamente cuál es la función del siguiente script de shell:

# !/bin/bash

INT=1
RESP=s

while [ $RESP == s ]
do
for i in 1 2 3 4 5 6 7 8 9 10
do
clear
echo “Loop número $INT . . “
echo “(Presionar CTRL+C para cancelar)”
sleep 1
INT = `exp $INT + 1`
done
echo “ “
echo -n “Desea continuar? (s/n) “
read RESP
done

3.Escribir un script que solicite un nombre de archivo, verifique que exista y que es un archivo común, lo convierta en ejecutable para el dueño y el grupo y muestre el modo final.

4.Escribir un script que mueva todos los archivos del directorio actual hacia el subdirectorio files del directorio propio del usuario, muestre los nombres de los que mueve e indique cuántos ha movido o que no ha movido ninguno. Si el directorio files no existe, deberá ser creado.

Re: Pequeño problema.

A=`expr 2 - 1`
B=`expr 3 + 8`

Variables

Buenos días
He comenzado ahora a estudiar linux y me encontré con un ejercicio que me da dificultades.
Resulta que que tengo que introducir un par de archivos de texto como variables (hasta ahí muy sencillo), posteriormente tengo que hacer que el número de lineas de cada uno de ellos se compare para que me diga cual tiene más renglones y cual menos. Creo que el problema puede estár en pasar el número de lineas a varibles para luego referirme a ellos en los sucesivos if.
Ej: echo "Introduzca un archivo"
read arg1
echo "Introduzca otro archivo"
read arg2
Primero=`wc -l > one`
Segundo=`wc -l > two`
if [ $Primero > $Segundo ]
then
echo "$arg1 tiene más renglones que $arg2"
else
echo "arg2 tiene las mismas o más lineas que arg1"
fi
¿Alguno me podría dar alguna idea de donde puede estar el error?
Gracias