Sei sulla pagina 1di 17

Tema 3: Linux: Shell de Linux, Programacin con Bash Objetivos: - Entender el uso de scripts in sistemas Linux.

- Aprender comandos y sintax de Bash shell - Formar programas con lenguaje de programacin de Bash

Fundamentos de los shells de Linux El intrprete de lnea de comandos de Linux se llama el shell Capa de insulacin entre sistema operativo y el usuario Lenguaje poderoso; programas se refiere con nombre script Pegar comandos juntos Conocimiento de shell scripting es fundamental para sistema operativo El Lenguaje con los siguientes construcciones: (1) construciones de bucles, (2) construcciones de condicionale, (3) funciones de shell, (4) funciones built-in Porque Scripts? Script importante para administracipn y configuracin Por Ejemplo: Linux arranque: ejecuta el shell scripts en el directorio de /etc/rc.d para restorar el configuracin de sistema y iniciar los servicios. sintaxis es como pegando comandos junto. un manera rpido para hacer prototipos. Cuando no debe usar scripting tareas intensivas de los recursos, velocidad es importante aplicaciones complejos - programacin estructurad es importante tratamiento de ficheros; E/S intensivo necesidad de generar o tratar con grficos o GUIs necesidad de tener aceso directo al hardware de sistema necesidad de utilizar E/S de sockets necesidad de utilizar librarias Ejemplos de Scripts En el caso ms sencillo, el script es solo una lista de comandos guardado en un fichero. Por ejemplo, limpiar ficheros en /var/log
# limpiar # Ejecuta como root cd /var/log cat /dev/null > messages cat /dev/null > wtmp echo "Log limpia."

Un ejemplo de un script ms complicado es la siguiente. (Tenemos que estudiar distintos elementos de este script)

#!/bin/bash # cleanup, version 2 # Ejecutar como root LOG_DIR=/var/log ROOT_UID=0 # LINES=50 # E_XCD=66 # E_NOTROOT=67 #

Only users with $UID 0 have root privileges. Default number of lines saved. Can't change directory? Non-root exit error.

if [ "$UID" -ne "$ROOT_UID" ] then echo "Must be root to run this script." exit $E_NOTROOT fi if [ -n "$1" ] # Test if command line argument present (non-empty). then lines=$1 else lines=$LINES # Default, if not specified on command line. fi cd $LOG_DIR if [ `pwd` != "$LOG_DIR" ] # or if [ "$PWD" != "$LOG_DIR" ] # Not in /var/log?

then echo "Can't change to $LOG_DIR." exit $E_XCD fi # Doublecheck if in right directory, before messing with log file. tail -$lines messages > mesg.temp # Saves last section of message log file. mv mesg.temp messages # Becomes new log directory. cat /dev/null > wtmp # echo "Logs cleaned up." exit 0 ': > wtmp' and '> wtmp' have the same effect.

Un valor cero desde el script cuando exit indica exito. el simbolo #! en primer linea indica que el fichero es listo para un conjunto de comandos. En realidad es un nmero magico de dos bytes que indica el tipo de fichero.

Otros ejemplos que llama interpredores son:

#!/bin/sh #!/bin/bash #!/usr/bin/perl #!/usr/bin/tcl #!/bin/sed -f #!/usr/awk -f

Llamando el script sh < scriptname > chmod 555 scriptname (gives everyone read/execute permission) chmod +rx scriptname (gives everyone read/execute permission) chmod u+rx scriptname (gives only the script owner read/execute

permission)

2.2 Operaciones Basicas Dentro de operaciones bsicas que estamos interesados: caracteres especiales, variables y parametros, quoting, estatus de salir. En este apartado, investigamos estas posibilidades.

Caracteres Especiales \# Comentarios ; Separador de Comandos. Permite dos o ms comandos, echo hola; echo buenos ;; Terminador de sentencia case [Double semicolon] Considera la siguiente ejemplo:
case "$variable" in abc) echo "$variable = abc" ;; xyz) echo "$variable = xyz" ;; esac

En esta ejemplo, utilizamos full quoting. Si tenemos 'STRING' preserva todos los caracteres especiales dentro de STRING. El operador coma: El operador coma enlace operaciones aritmeticas; para que todos estan evaluadas, pero solo se devuelve el ltimo

let "t2 = ((a = 9, 15 / 3))"

# Set "a" and calculate "t2".

Expansion de variables y Sustitucin de subcadenas. La combinacin :> (: con el operador de redireccin >), se puede poner el tamao de fichero a cero, sin cambiar los permisos. Si el fichero no existe, lo crea. .
: > data.xxx # Fichero "data.xxx" ahora vacio

Tiene la misma efecto que cat /dev/null >data.xxx Pero no va a fork un procesos nuevo, debido que ":" es una funcin builtin. La caractera ":" tambien sirve como separador de campo en /etc/passwd, y en la definicin del variable de entorno $PATH.

bash$ echo $PATH /usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games

Mas Caracteres especiales: ? es el operador de prueba; dentro de ciertos expresiones, la caractera ? indica una prueba para una condicin. $ sustitucin de variable [] prueba; la expresin de prueba va dentro de las claves [ ].

var1=5 var2=23skidoo echo $var1 echo $var2 # 5 # 23skidoo

Manipulando y/o expandiendo variables

${parametro} Es lo mismo que $parametro, eg. , el valor del parametro de variable. Se puede utilizarlo para concatenar variables con cadenas. En bash las cadenas y expresiones numericos se trata en una manera similar.
your_id=${USER}-on-${HOSTNAME} echo "$your_id" # echo "Old \$PATH = $PATH" PATH=${PATH}:/opt/bin #Add /opt/bin to $PATH for duration of script. echo "New \$PATH = $PATH"

Sentencias de control: until


until TEST-COMMANDS; do CONSEQUENT-COMMANDS; done

Ejecutar CONSEQUENT-COMMANDS hasta el comando final TEST-COMMANDS tiene un estatus de salida que no es cero.
#!/bin/bash COUNTER=20 until [ $COUNTER -lt 10 ]; do echo COUNTER $COUNTER let COUNTER-=1 done

Sentencias de control: while


while TEST-COMMANDS; do CONSEQUENT-COMMANDS; done

Ejecutar CONSEQUENT-COMMANDS hasta el comando final TEST-COMMANDS tiene un estatus de salida que es cero.
#!/bin/bash COUNTER=0 while [ $COUNTER -lt 10 ]; do echo The counter is $COUNTER let COUNTER=COUNTER+1 done

Sentencia de control: for


for NAME [in WORDS ...]; do COMMANDS; done

Ejecutar COMMANDS para cada miembro en WORDS, con NAME enlazada al miembro actual
for i in vacas cabritos cerdos pollos do echo ``$i es un animal de granja'' done echo -e pero \n GNUs no son ''

Sentencias Condicional: if
if TEST-COMMANDS; then CONSEQUENT-COMMANDS; [elif MORE-TEST-COMMANDS; then MORE-CONSEQUENTS;] [else ALTERNATE-CONSEQUENTS;] fi

Un ejemplo de un script utilizando la sentencia if:


#!/bin/sh X=10 Y=5 if test ``$X'' -gt ``$Y'' ; then echo ``$X is greater than $Y'' elif test ``$X'' -lt ``$Y'' ; then echo ``$X is less than $Y'' else echo ``$X is equal to $Y'' fi

Ejemplo utilizando test


#!/bin/sh if test ``$1'' = ``'' ; then echo ``Usage: backup-lots.sh <filename>'' exit fi for i in 0 1 2 3 4 5 6 7 8 9 ; do NEW_FILE=$1.BAK-$i if test -e $NEW_FILE ; then echo ``backup-lots.sh : warning $NEW_FILE'' echo `` already exists'' else cp $1 $NEW_FILE fi done

Sentencias Condicional: case


`case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac'

Ejecutar selectivamente los COMMANDS basada sobre WORD que match PATTERN. La barra $|$ esta utilizado para separar patrones multiples.

echo -n "Entra el nombre del animal: " read ANIMAL echo -n "El \$ANIMAL tiene " case \$ANIMAL in caballo | perro | gato) echo -n "four";; hombre | kangaroo ) echo -n "two";; *) echo -n "un numero no conocido de";; esac echo "piernes."

Funciones de Shell
[`function'] NAME () { COMMAND-LIST; }

#!/bin/bash function quit { exit } function hola { echo Hola! } hola quit echo foo

#!/bin/sh if test ``$1'' = ``'' ; then echo ``Usage: backup-lots.sh <filename>'' exit fi for i in 0 1 2 3 4 5 6 7 8 9 ; do NEW_FILE=$1.BAK-$i if test -e $NEW_FILE ; then echo ``backup-lots.sh : warning $NEW_FILE'' echo `` already exists'' else cp $1 $NEW_FILE fi done

Sentencias Condicional: case


`case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac'

Ejecutar selectivamente los COMMANDS basada sobre WORD que match PATTERN. La barra $|$ esta utilizado para separar patrones multiples.

echo -n "Entra el nombre del animal: " read ANIMAL echo -n "El \$ANIMAL tiene " case \$ANIMAL in caballo | perro | gato) echo -n "four";; hombre | kangaroo ) echo -n "two";; *) echo -n "un numero no conocido de";; esac echo "piernes."

Factorial con bucle while Funciones en en bash son como programas en C. Este ejemplo es lo mismo del factorial de antes, pero este vez utilizando un bucle while.
function factorial () { N=$1 A=1 while test $N -gt 0 ; do A = 'expr $A '+' $N' N = 'expr $N - 1' done echo $A }

Algunas Bourne Shell Builtins : expander argumentos y hacer redirecciones . Leer y ejecutar los comandos del FILENAME en contexto de shell actual break Salir del bucle cd cambiar directorio actual de trabajo continue resumir la proximo iteracin dentro un bucle. Echo imprime argumentos a salida estandar eval argumentos estan concatenado exec exit Salir del shell export pasar a procesos hijos getopts Parse options to shell scripts or functions. hash kill seal para para proceso pwd imprime directorio actual read lear del entrada del shell return devuelve un funci\'on de shell con valor test, '['} Evaluar un expresin conditional. 'imes imprime los usuarios y tiempos de sistema usado por los hijos.

Variables IFS PATH HOME CDPATH MAILPATH PS1 PS2 OPTIND OPTARG

una lista de caracteres que separar campos utlizado cuando el shell compartir palabras como parte de la expansin lista de directorios que shell puede buscar comandos directorio home de usuario lista de directorios usado por comando cd lista de ficheros que el shell mira para nuevas mensajes de correo cadena primaria de prompt cadena secundaria de prompt el indice de la ltima opcin procesado por getopts el valor de la ltima argumenta procesado por getopts

Ejemplos
# cleanup: Un script para limpiar los ficheros log en /var/log # Ejecutar como root cd /var/log cat /dev/null > messages cat /dev/null > wtmp echo "Los logs esta limpia."

Example 2-2. cleanup An enhanced and generalized version of above #!/bin/bash # cleanup, version 2 # Run as root, of course. if [ -n $1 ] # Test if command line argument present. then lines=$1 else lines=50 # default, if not specified on command line. Fi cd /var/log tail -$lines messages > mesg.temp # Saves last section of message log file. mv mesg.temp messages # cat /dev/null > messages # No longer needed, as the above method is safer. cat /dev/null > wtmp echo "Logs cleaned up." exit 0 # A zero return value from the script upon exit # indicates success to the shell.

script.

Conditionals with variables


#!/bin/bash T1="foo" T2="bar" if [ "$T1" = "$T2" ]; then echo expression evaluated as true else echo expression evaluated as false fi

Caracteres especiales de Bash Algunas caracteres tiene distintos signficacia dependiendo en su contexto. Dos de ellos puede ser las caracteres siguientes: ; Seperador de comandos. Puede poner dos comandos en misma linea. : null command. Exit status 0, alias for true, see below En este ejemplo, vemos la manera de separar dos comandos.

echo hola; echo amigo

Endless loop:
while : do operation-1 operation-2 ... operation-n done if condition then : # Do nothing and branch ahead else take-some-action fi

${} Parameter substitution. ${parameter-default} ${parameter=default} ${parameter+otherwise} ${parameter?err_msg} Si parametro no esta fija, usar default Si parametro no esta fija, fijar al default Si parametro fija, usar 'otherwise", else usar null string Si parametro fjio, usarlo, else imprimir err_msg

#!/bin/bash : ${HOSTNAME?} {USER?} {MAIL?} echo $HOSTNAME echo $USER echo $MAIL echo Critical env. variables set. exit 0

Sustitucin y expansin ${var#pattern}, ${var##pattern} quitar mas corta/mas larga parte de patron si es similar a principio de variable ${var%pattern}, ${var%%pattern} quitar mas corta/mas larga si es similar a final de variable ${var:pos} variable var expandido, empezando con posicin pos ${var:pos:len} expansin a max de longitud len de caracteres de variable var desde la posicin pos ${var/patt/replacement} primer similaridad de patron, dentro var replaced with replacement. ${var//patt/replacement} all matches of pattern, within var replaced with replacement.

Ejemplo
#!/bin/bash var1=abcd-1234-defg echo "var1 = $var1" t=${var1#*-*} echo "var1 (with everything, up to and including first - stripped out) = $t" t=${var1%*-*} echo "var1 (with everything from the last - on stripped out) = $t" path_name=/home/bozo/ideas/thoughts.for.today echo "path_name = $path_name" t=${path_name##/*/} # Same effect as t=`basename $path_name` echo "path_name, stripped of prefixes = $t" t=${path_name%/*.*} # Same effect as t=`dirname $path_name` echo "path_name, stripped of suffixes = $t" t=${path_name:11} echo "$path_name, with first 11 chars stripped off = $t" t=${path_name:11:5} echo "$path_name, with first 11 chars stripped off, length 5 = $t" t=${path_name/bozo/clown} echo "$path_name with bozo replaced = $t" t=${path_name//o/O} echo "$path_name with all o's capitalized = $t" exit 0

Grupo de Comandos (.) Grupo de comandos. \texttt{(a=hello; echo \$a)} { .} Bloque de cdigo. Crea un funci\'on anonimo. Bloque de codigo puede tener E/S rediricionado desde y hacia el.
#!/bin/bash # Bloques de cdigo y E/S redireccin { read fstab } < /etc/fstab echo "Primer linea de /etc/fstab es:" echo "$fstab" exit 0

Redireccin

The concept of a standard input and a standard output is one of the most useful features of UNIX-like operating systems. The idea is that every program, no matter how diverse, should be reading input and generating output in a uniform, clearly understood way. Once you have that, it makes it much easier for programs to talk to one another directly. It is also possible to write generic programs that bridge the input and output of any two programs, which is an amazingly handy ability to have.

> < 2> >> |

Send standard output to a file. Read standard input from a file. Redirect standard error as specified. Append standard output to the specified file. Couple the standard output of one program to the standard input of another program. Copy standard input to a file and also to standard output.

tee script Save the activity on your screen in a file. xargs Read multiple arguments from standard input and use them as arguments to
some specified command.
scriptname >filename command >&2 scriptname >>filename

(redireccionar salida de un comando a stderr) (anadir la salida de scriptname a un fichero)

<< | >| -

redireccionar stdin Tuberia. Salida de un comando a otro o shell forzar redirecci\'on. Sobre-escribir un fichero existente. redirecci\'on desde/hacia stdin or stdout.

Ejemplos:
echo ls -l | sh

cat *.lst | sort | uniq

# ordenar la salida de .lst # ficheros y borrar lineas duplicados.

(cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xvfp -) # Mover arbol de fichero entero desde un directorio a otro

bunzip2 linux-2.2.15.tar.bz2 | tar xvf -

Redireccin y ficheros Hay tres descriptores de ficheros: stdin, stdout y stderr redireccionar stdout a un fichero redireccionar stderr a un fichero redireccionar stdout a un fichero redireccionar stderr a stdout redireccionar stderr y stdout a un fichero redireccionar stderr y stdout a stdout redireccionar stderr y stdout a stderr

1 representa stdout 2 representa stderr


grep da * 2> grep-errors.txt

Escribir sderr a un fichero

grep da * 1>&2

Escribir stdout a misma descriptor de fichero que stderr

Escribir sterr a misma descriptor de fichero que stdout


grep * 2>&1 rm -f $(find / -name core) &> /dev/null

Tuberias

ls -l | sed -e "s/[aeio]/u/g" ls -l | grep "\.txt$"

Acceder Parametros $0, $1,etc. parametros positional (desde linea de comandos o desde funcin, o un variable) $# numero de argumentos o parametros posicional en linea de comandos $$ id de proceso de script, utilizado a menudo en scripts para construir nombre de ficheros temporal $? estatus de salida (exit) de funcin o de script $* todo los parametros positionales $@ lo mismo de $*, pero para cada parametro es un string en comillas $flags passed to script $! PID de ltima job ejecutando en fondo = asignacin de variables (no espacio antes y despues de &) Obtener valor de return de un programa

Valor de salida return value de una programa esta guardad en un variable especial, denomida $?. Ejemplo de como capturar valor de salida:
#!/bin/bash cd /dada &> /dev/null echo rv: $? cd $(pwd) &> /dev/null echo rv: $?

Comparicin de Cadenas s1 = s2 s1 igual a s2 s1 != s2 s1 no es igual a s2 s1 < s2 s1 > s2 -n s1 s1 no es null z s1 s1 es null

#!/bin/bash S1='string' S2='String' if [ $S1=$S2 ]; then echo "S1('$S1') no es igula a S2('$S2')" fi if [ $S1=$S1 ]; then echo "S1('$S1') es igual a S1('$S1')" fi

Sentencia de if/then
#!/bin/bash if [ condition-true ] then command 1 command 2 ... else # Opcional para anadir mas chequeos command 3 command 4 ... fi if [ 0 ] then echo "0 es verdad." else echo "0 es falso." fi if [ ] #NULL (empty condition) then echo "NULL es verdad." else echo "NULL es falso." fi if [ xyz ] #string then echo "string aleatorio es verdad." else echo "string aleatorio es falso." fi

if [ -x filename ]; then elif

Equivalence of [ ] and test


#!/bin/bash if test -z $1 then echo "No command-line arguments." else echo "First command-line argument is $1." fi # Both code blocks are functionally identical. if [ -z $1 ] # if [ -z $1 # also works, but outputs an error message. then echo "No command-line arguments." else echo "First command-line argument is $1." fi exit 0

Tests, command chaining, redireccin


#!/bin/bash filename=sys.log if [ ! -f $filename ] then touch $filename; echo "Creating file." else cat /dev/null > $filename; echo "Cleaning out file." fi # Nota /var/log/messages tiene que tener permisos (644) para que este funciona tail /var/log/messages > $filename echo "$filename contains tail end of system log." exit 0

Aritmetica y comparaciones de cadenas

#!/bin/bash a=4 b=5

# a y b puede estar tratado como enteros o strings. if [ $a -ne $b ] then echo "$a is not equal to $b" echo "(arithmetic comparison)" fi echo if [ $a != $b ] then echo "$a is not equal to $b." echo "(string comparison)" fi echo Operadores Aritmeticas Arithmetic operators: +, -, *, / Arithmetic relational operators: -lt (<), Using expr: Arithmetic Operators
#!/bin/bash echo Arithmetic Operators echo a=`expr 5 + 3` echo 5 + 3 = $a a=`expr $a + 1` echo echo a + 1 = $a echo \(incrementing a variable\) a=`expr 5 % 3` # modulo echo echo 5 mod 3 = $a

-gt (>), -le (<=), -ge (>=), -eq (==),

-ne (!=)

Logical Operators
#!/bin/bash echo Logical Operators a=3 echo a = $a b=`expr $a \> 10` echo 'b=`expr $a \> 10`, therefore...' echo "If a > 10, b = 0 (false)" echo b = $b b=`expr $a \< 10` echo "If a < 10, b = 1 (true)" echo b = $b

Comparison Operators

#!/bin/bash echo Comparison Operators echo a=zipper echo a is $a if [ `expr $a = snap` ] # Force re-evaluation of variable 'a' then echo "a is not zipper" fi

String Operators
#!/bin/bash echo String Operators echo a=1234zipper43231 echo The string being operated upon is $a. # index: position of substring b=`expr index $a 23` echo Numerical position of first 23 in $a is $b. # substr: print substring, starting position & length specified b=`expr substr $a 2 6` echo Substring of $a, starting at position 2 and 6 chars long is $b. # length: length of string b=`expr length $a` echo Length of $a is $b. # 'match' operations similarly to 'grep' b=`expr match $a [0-9]*` echo Number of digits at the beginning of $a is $b. b=`expr match $a '\([0-9]*\)'` echo The digits at the beginning of $a are $b.

exit 0

Letting let do some arithmetic

#!/bin/bash let a=11 # Same as 'a=11' let a=a+5 # Equivalent to let "a # (double quotes makes echo "a = $a" let "a <<= 3" # Equivalent of let "a echo "a left-shifted 3

= a + 5" it more readable)

= a << 3" places = $a"

let "a /= 4" # Equivalent to let "a = a / 4" echo $a let "a -= 5" # Equivalent to let "a = a - 5" echo $a let "a = a * 10" echo $a let "a %= 8" echo $a exit 0

xargs [-0prtx] [-e[eof-str]] [-i[replace-str]] [-l[maxlines]] [-n max-args] [-s max-chars][-P max-procs] [-null] [--eof[=eof-str]] [--replace[=replace-str]] [--max-lines[=max-lines]] [--interactive] [-maxchars=max-chars] [--verbose] [--exit] [--max-procs=maxprocs] [--max-args=max-args] [--norun-if-empty] [-version] [--help] [command [initial-arguments]] Read arguments from standard input, construct a command line using those arguments and arguments provided on its own command line, and execute the constructed commands. Example: Suppose you have some time on your hands and you want to grep through every file in the /usr/local filesystem for the string "datum". First, generate a list of the files using the find command; then pipe the results of that find to grep via the xargs command. (If you don't use xargs, grep will look only at the names of the files for the string "datum", and not look in the files themselves.) In other words, use find /usr/local -type f -print | xargs grep "datum"

--null, -0 --eof[=eof-str], -e[eofstr] --help --replace[=replace-str], i[replace-str] --max-lines[=max-lines], l[max-lines] --max-args=max-args, -n maxargs --interactive, -p

Input files are terminated by Null rather than the end-of-file character. Treat the specified string as the end-of-file marker. Display a listing of the possible arguments to xargs. Replace occurrences of replace-str in the initial arguments with names read from standard input. Limit commands to at most max-lines nonblank lines per command (default 1). Limit commands to at most max-args. Prompt the user before executing a generated command line.

--no-run-if-empty, -r --msax-chars=max-chars, -s max-chars --verbose, -t --version --exit, -x --max-procs=max-procs, -P max-procs

If the generated command line is empty, don't run it. Specify a maximum length for a command line. Before executing the command, display it to standard output. Output the version number and exit. Exit if the size specified by -s is exceeded. Specify an upper limit of processes to be simultaneously

Potrebbero piacerti anche