Cómo aprender el script de shell y cómo escribirlo
1. Conceptos básicos del scripting de Linux
1.1 Introducción básica a la sintaxis
1.1.1 Inicio
El programa debe comenzar con lo siguiente línea (debe estar en la primera línea del archivo):
#!/bin/sh
El símbolo #! se usa para indicarle al sistema que los parámetros detrás de él son los programas utilizados para ejecutar el archivo. En este ejemplo usamos /bin/sh para ejecutar el programa.
Cuando editas un script, si quieres ejecutarlo, también debes hacerlo ejecutable.
Para hacer ejecutable el script:
Compile chmod +x filename para que pueda ejecutarse con ./filename
1.1.2 Comentarios
Al realizar programación de shell, una oración que comienza con # indica un comentario hasta el final de la línea. Recomendamos sinceramente utilizar comentarios en sus programas.
Si utiliza comentarios, incluso si no ha utilizado el script durante mucho tiempo, podrá comprender el papel del script
y cómo funciona en un corto período de tiempo. tiempo.
1.1.3 Variables
En otros lenguajes de programación hay que utilizar variables. En la programación de shell, todas las variables se componen de cadenas y no es necesario declarar variables
. Para asignar un valor a una variable, puedes escribir:
#!/bin/sh
#Asignar un valor a una variable:
a=" hola mundo"
# Ahora imprima el contenido de la variable a:
echo "A es:"
echo $a
A veces los nombres de variables son fáciles de confundir con otro texto, como:
num=2
echo "este es el $numnd"
Esto no imprime "este es el 2do" ", pero solo imprime "este es el", porque el shell buscará el valor de la variable numnd,
pero esta variable no tiene valor. Puedes usar llaves para indicarle al shell que lo que queremos imprimir es la variable num:
num=2
echo "this is the ${num}nd" p>
Esto se imprimirá: este es el segundo
1.1.4 Variables de entorno
Las variables procesadas por la palabra clave export se denominan variables de entorno. No discutiremos las variables de entorno porque normalmente solo se usan en scripts de inicio de sesión.
1.1.5 Comandos de Shell y control de procesos
Se pueden utilizar tres tipos de comandos en los scripts de Shell:
1) Comandos de Unix:
Aunque puedes usar cualquier comando de Unix en un script de shell, todavía hay algunos comandos relativamente más utilizados. Estos comandos se utilizan normalmente
para operaciones de archivos y texto.
Sintaxis y funciones de comandos comunes
echo "algo de texto": imprime contenido de texto en la pantalla
ls: lista de archivos
wc -l filewc -w filewc -c file: Cuente el número de líneas en el archivo Cuente el número de palabras en el archivo Calcule el número de caracteres en el archivo.
cp sourcefile destfile: Copia del archivo.
mv oldname newname: cambie el nombre del archivo o mueva el archivo
rm file: elimine el archivo
grep 'pattern' file: busque una cadena en el archivo, por ejemplo: grep 'searchstring' file.txt
cut -b colnum file: especifique el rango de contenidos del archivo que se mostrarán y envíelos al dispositivo de salida estándar. Por ejemplo: salida
Los caracteres 5.º a 9.º de cada línea cortada -b5- 9 file.txt no deben confundirse con el comando cat.
Estos son dos comandos completamente diferentes
cat file.txt: envía el contenido del archivo al dispositivo de salida estándar (pantalla)
archivo somefile: obtiene el tipo de archivo
read var: solicita entrada al usuario y asigna la entrada a la variable
sort file.txt: archivo file.txt Ordena las líneas en el archivo de texto
uniq: Elimina las filas y columnas que aparecen en el archivo de texto Por ejemplo: sort. file.txt | uniq
expr: realizar operaciones matemáticasEjemplo: agregar 2 y 3expr 2 "+ " 3
buscar: buscar archivos como: buscar buscar según el nombre del archivo. nombre nombre de archivo -print
tee: datos de salida al dispositivo de salida estándar (pantalla) y archivos como: somecommand | tee outfile
archivo de nombre base: devuelve el nombre del archivo sin una ruta, por ejemplo: nombre base /bin/tux devolverá tux
archivo dirname: devuelve la ruta del archivo, por ejemplo: dirname /bin/ tux devolverá /bin
archivo principal: imprime las primeras líneas del archivo de texto
archivo final: imprime las últimas líneas del archivo de texto
sed: Sed es un programa básico de búsqueda y reemplazo. Puede leer texto de la entrada estándar (como una canalización de comandos) y enviar los resultados a la salida estándar (la pantalla). Este comando utiliza expresiones regulares (ver Referencia) para buscar.
No debe confundirse con los comodines del shell. Por ejemplo: reemplace linuxfocus con
LinuxFocus: cat text.file | sed 's/linuxfocus/LinuxFocus/' > newtext.file
awk: awk se usa para extraer archivos de texto campo. De forma predeterminada, el separador de campo es un espacio. Puede utilizar -F para especificar otros separadores.
cat file.txt | awk -F, '{print $1 "," $3 }'Aquí usamos, como separador de campos para imprimir el primero y el tercero al mismo tiempo
campos. Si el contenido del archivo es el siguiente: Adam Bor, 34, IndiaKerry Miller, 22, EE. UU.
El resultado del comando es: Adam Bor, IndiaKerry Miller, EE. UU.
2) Concepto : canalización, orientación pesada y acento grave
Estos no son comandos del sistema, pero son realmente importantes.
La tubería (|) toma la salida de un comando como entrada para otro comando.
grep "hello" file.txt | wc -l
Busque líneas que contengan "hello" en file.txt y cuente el número de líneas.
Aquí la salida del comando grep se utiliza como entrada del comando wc. Por supuesto, puedes utilizar varios comandos.
Redirección: genera los resultados del comando en un archivo en lugar de la salida estándar (pantalla).
>Escribir en el archivo y sobrescribir el archivo antiguo
>>Agregar al final del archivo, conservando el contenido del archivo antiguo.
Barra invertida
Utilice la barra invertida para utilizar la salida de un comando como parámetro de línea de comando para otro comando.
Comando:
find . -mtime -1 -type f -print
Se utiliza para buscar las últimas 24 horas (-mtime –2 significa las últimas 48 horas) archivos modificados. Si
quieres empaquetar todos los archivos encontrados, puedes usar el siguiente script:
#!/bin/sh
# Las marcas son comillas invertidas (` ) comillas no normales ('):
tar -zcvf lastmod.tar.gz `find .mtime -1 -type f -print`
3) Control de procesos
1.if
La expresión "if" ejecuta la parte después de entonces si la condición es verdadera:
si ....; entonces
....
elif ....; entonces
....
si no
.. .. p>
fi
En la mayoría de los casos, puede utilizar comandos de prueba para probar las condiciones. Por ejemplo, puede comparar cadenas, determinar si un archivo
existe y es legible, etc.
Por lo general, "[ ]" se utiliza para indicar pruebas condicionales. Tenga en cuenta que los espacios aquí son importantes. Asegúrese de que haya espacios entre corchetes.
[ -f "somefile" ]: determina si es un archivo
[ -x "/bin/ls" ]: determina si /bin/ls existe y tiene permisos ejecutables
[ -n "$var" ]: Determina si la variable $var tiene un valor
[ "$a" = "$b" ]: Determina si $a y $ b son iguales
Ejecute la prueba man para ver todos los tipos que se pueden comparar y juzgar mediante expresiones de prueba.
Ejecute el siguiente script directamente:
#!/bin/sh
if [ "$SHELL" = "/bin/bash" ]; / p>
echo "tu shell de inicio de sesión es bash (bourne again shell)"
else
echo "tu shell de inicio de sesión no es bash sino $SHELL"
fi
La variable $SHELL contiene el nombre del shell de inicio de sesión, que comparamos con /bin/bash.
Operadores de acceso directo
A los amigos que estén familiarizados con el lenguaje C les puede gustar la siguiente expresión:
[ -f "/etc/shadow" ] && echo "This la computadora usa contraseñas ocultas"
Aquí && es un operador de acceso directo. Si la expresión de la izquierda es verdadera, se ejecutará la declaración de la derecha.
También puedes considerarlo como la operación AND en operaciones lógicas. El ejemplo anterior indica que si el archivo /etc/shadow existe
entonces se imprimirá "Esta computadora usa contraseñas ocultas".
La misma operación OR (||) también está
disponible en la programación de shell. Aquí hay un ejemplo:
#!/bin/sh
mailfolder=/var/spool/mail/james
[ -r "$mailfolder" ] ' '{ echo "No se puede leer $mailfolder" ; salir 1;
echo "$mailfolder tiene correo de:"
grep "^De " $mailfolder
El script primero determina si la carpeta de correo es legible. Si es legible, imprima la línea "De" en el archivo. Si no es legible
La operación OR surte efecto y el script se cierra después de imprimir el mensaje de error. Aquí hay un problema, es decir, debemos tener dos comandos:
-Imprimir mensaje de error
-Salir del programa
Usamos llaves para declarar la función anónima El formulario junta dos comandos y los usa como un solo comando. Las funciones generales se mencionan a continuación.
También podemos usar expresiones if para hacer cualquier cosa sin los operadores AND u, pero es mucho más conveniente usar los operadores AND u.
2.case
caso: la expresión se puede utilizar para hacer coincidir una cadena determinada en lugar de un número.
caso... en
...) haz algo aquí ;;
esac
Veamos un ejemplo. El comando file puede identificar el tipo de archivo de un archivo determinado, por ejemplo:
archivo lf.gz
Esto devolverá:
lf.gz: gzip datos comprimidos, desinflados, nombre de archivo original,
Última modificación: lunes 27 de agosto 23:09:18 2001, sistema operativo: Unix
Aprovechamos esto y escribimos un script llamado smartzip, cuyo script puede descomprimir automáticamente archivos comprimidos de tipo bzip2, gzip y zip:
#!/bin/sh
ftype=`file "$1"`
case "$ftype" en
"$1: archivo Zip"*)
descomprimir "$1" ;;
"$1: comprimido gzip"*)< / p>
gunzip "$1" ;;
"$1: bzip2 comprimido"*)
bunzip2 "$1" ;;
*) echo " El archivo $1 no se puede descomprimir con smartzip";;
esac
Puedes notar que aquí usamos una variable especial $1. Esta variable contiene el valor del primer parámetro pasado al programa.
En otras palabras, cuando ejecutamos:
smartzip artículos.zip
$1 es la cadena artículos.zip
3.
La expresión select es una aplicación de extensión de bash, especialmente buena para uso interactivo. El usuario puede elegir entre un conjunto diferente de valores.
seleccione var en... ; do
romper
hecho
.... ahora se puede usar $var.. ..
Aquí tienes un ejemplo:
#!/bin/sh
echo "¿Cuál es tu sistema operativo favorito?"
seleccione var en "Linux" "Gnu Hurd" "BSD gratuito" "Otro"; do
break
done
echo "Has seleccionado $var"
El siguiente es el resultado de ejecutar el script:
¿Cuál es tu sistema operativo favorito?
1) Linux
2) Gnu Hurd
3) BSD gratuito
4) Otro
# 1
Has seleccionado Linux
4. bucle
expresión de bucle:
mientras...; hacer
....
hecho
while-loop se ejecutará hasta que la expresión sea verdadera. se ejecutará mientras la expresión que probamos sea verdadera.
La palabra clave "break" se utiliza para salir del bucle. La palabra clave "continuar" se utiliza para saltar directamente al siguiente bucle sin ejecutar la parte restante.
La expresión del bucle for mira una lista de cadenas (cadenas separadas por espacios) y la asigna a una variable:
for var in ....; > p>
....
hecho
En el siguiente ejemplo, ABC se imprimirá en la pantalla respectivamente:
#!/bin / sh
for var in A B C ; do
echo "var is $var"
done
Lo siguiente es más útil El script showrpm, su función es imprimir información estadística de los paquetes RPM:
#!/bin/sh
# enumera un resumen del contenido de varios paquetes RPM
# USO: showrpm rpmfile1 rpmfile2 ...
# EJEMPLO: showrpm /cdrom/RedHat/RPMS/*.rpm
para paquete rpm en $*; p>
si [ -r "$rpmpackage" ];entonces
echo "================ $rpmpackage ======= === ===="
rpm -qi -p $rpmpackage
else
echo "ERROR: no se puede leer el archivo $rpmpackage"
fi
hecho
Aquí aparece la segunda variable especial $*, que contiene los valores de todos los parámetros de línea de comando ingresados.
Si ejecuta showrpm openssh.rpm w3m.rpm webgrep.rpm
En este momento $* contiene 3 cadenas, a saber, openssh.rpm, w3m.rpm y webgrep.rpm.
5. Comillas
El programa expande los comodines y las variables antes de pasar cualquier parámetro al programa. La llamada expansión aquí significa que el programa reemplazará los caracteres comodín
(como *) con el nombre de archivo apropiado y reemplazará sus variables con valores de variable. Para evitar que el programa realice esta sustitución, puede utilizar comillas
: Veamos un ejemplo, suponiendo que hay algunos archivos en el directorio actual, dos archivos jpg, mail.jpg y tux.jpg.
1.2 Compile el script SHELL
#ch#!/bin/sh mod +x filename
cho *.jpg ./filename para ejecutar su script.
Esto imprimirá los resultados de "mail.jpg tux.jpg".
Las comillas (simples y dobles) evitarán esta expansión comodín:
#!/bin/sh
echo "*.jpg"
p >echo '*.jpg'
Esto imprimirá "*.jpg" dos veces.
Las comillas simples son más restrictivas. Previene cualquier expansión variable. Las comillas dobles evitan la expansión con comodines pero permiten la expansión variable.
#!/bin/sh
echo $SHELL
echo "$SHELL"
echo '$SHELL'
El resultado de la ejecución es:
/bin/bash
/bin/bash
$SHELL
Finalmente, hay Una forma de evitar esta expansión es utilizar el carácter de escape: la barra invertida:
echo *.jpg
echo $SHELL
Esto generará:
*.jpg
$SHELL
6. Aquí documentos
Cuando se van a pasar varias líneas de texto a un comando, aquí documentos (Nota del traductor: todavía no he visto una traducción adecuada de esta palabra)
Un buen método. Es útil escribir un texto útil para cada script. En este momento, si tenemos los documentos aquí
, no tenemos que usar la función de eco para generar línea por línea.
Un "documento aquí" desplazado 2
--) shift;break;; # fin de las opciones
-*) echo "error: no existe esa opción $1. -h para obtener ayuda ";salida 1;;
*) pausa;;
esac
hecho
echo "opt_f es $opt_f" p>
echo "opt_l es $opt_l"
echo "el primer argumento es $1"
echo "el segundo argumento es $2"
Puedes ejecutar el script es así:
cmdparser -l hello -f -- -somefile1 somefile2
El resultado devuelto es:
opt_f es 1
opt_l es hola
el primer argumento es -algún archivo1
el segundo argumento es algún archivo2
¿Cómo funciona este script? El script primero recorre todos los parámetros de entrada de la línea de comando, comparando los parámetros de entrada
con la expresión case y, si hay una coincidencia, establece una variable y elimina el parámetro. Según la convención de los sistemas Unix,
La primera entrada debe ser el parámetro que contiene el signo menos.
Ejemplo de la parte 2
Ahora analicemos cómo escribir un script. Pasos generales. Cualquier buen script debe tener ayuda y parámetros de entrada. Y es una muy buena idea escribir un pseudo script (framework.sh) que contenga la estructura del marco requerida por la mayoría de los scripts. En este momento, al escribir un nuevo script, solo necesitamos ejecutar el comando de copia:
cp framework.sh myscript
Luego inserte nuestra propia función.
Veamos dos ejemplos más:
Conversión de binario a decimal
El script b2d convierte un número binario (como 1101) al número decimal correspondiente.
Este también es un ejemplo del uso del comando expr para realizar operaciones matemáticas:
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat <
b2h -- convertir binario a decimal
USO: b2h [- h] binarionum
OPCIONES: -h texto de ayuda
EJEMPLO: b2h 111010
devolverá 58
AYUDA
salir 0
}
error()
{
# imprimir un error y salir
echo "$1 "
salir 1
}
lastchar()
{
# devolver el último carácter de una cadena en $rval
if [ -z "$1" ] entonces
# cadena vacía
rval=""
return
fi
# wc pone algo de espacio detrás de la salida, es por eso que necesitamos sed:
numofchar=`echo -n "$1" | wc -c | sed 's/ //g' `
# ahora corta el último carácter
rval=`echo -n "$1" |
}
chop()
{
# elimina el último carácter de la cadena y lo devuelve en $rval
if [ -z "$1" ]; entonces
# cadena vacía
rval=""
return
fi
# wc pone algo de espacio detrás de la salida, por eso necesitamos sed:
numofchar=`echo -n "$1" | wc -c | ' `
if [ "$numofchar" = "1" ] entonces
# solo un carácter en la cadena
rval=""
return
fi
numofcharminus1=`expr $numofchar "-" 1`
# ahora corta todo menos el último carácter:
rval=`echo -n "$1" | cut -b 0-${numofcharminus1}`
}
mientras [ -n "$1" ]; p>
caso $1 en
-h) ayuda;shift 1;; # se llama a la función de ayuda
--) shift;break;; # fin de las opciones
-h) help;shift 1;; p>
-*) error "error: no existe esa opción $1. -h para obtener ayuda";;
p>
*) break;;
esac
hecho
# El programa principal
sum=0
peso=1
# se debe proporcionar un argumento:
[ -z "$1" ] && ayuda
binnum="$1"
binnumorig="$1"
mientras [ -n "$binnum" ]; hacer
lastchar "$binnum"
if [ "$rval" = "1" ]; entonces
sum=`expr "$peso" "+" "$sum"`
fi
# eliminar la última posición en $binnum
cortar "$binnum"
binnum="$rval"
weight=`expr "$weight" "*" 2`
done
echo "binary $binnumorig is decimal $sum"
El algoritmo utilizado por este script es utilizar pesos decimales y binarios (1, 2,4,8,16,..), por ejemplo, el "10" binario se puede convertir a decimal así:
0 * 1 + 1 * 2 = 2
Para obtener un único número binario utilizamos la función lastchar. Esta función usa wc -c para contar el número de caracteres y luego usa el comando cortar para eliminar el último carácter. La función de la función Chop es eliminar el último carácter.
File Rotator
Quizás eres de esas personas que quiere guardar todos los correos electrónicos salientes en un archivo, pero después de unos meses
En el futuro, este archivo puede llegar a ser tan grande que el acceso al archivo se vuelve más lento. El siguiente script rotatefile
puede resolver este problema. Este script puede cambiar el nombre del archivo guardado de correo (suponiendo que sea outmail) a outmail.1,
Y para outmail.1, se convierte en outmail.2 y así sucesivamente...