Recetas Bash¶
Configuración¶
- Configuración de los locales para que funcione todo bien:
export LANG=es_ES.UTF-8
- Listar con colorines:
ls -h --color
. Para que salga por defecto, se añade un alias en el .bashrc:alias ls='ls -h --color'
- Mantener el histórico de comandos entre sesiones: añadir
shopt -s histappend
en el.bahsrc
Genérico¶
Ignorar mayúsculas o minúsculas en un for en Bash¶
shopt -s nocaseglob
Emular el comando tree de dos¶
ls -R | grep : | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/ /' -e 's/-/|/'
Copia recursiva de ciertos ficheros¶
cp -R --copy-contents *.jpg origen/ destino
Sistema¶
Generar número aleatorio¶
# Devuelve un número aleatorio entre 1 y 100
echo $[ ( $RANDOM % 100 ) + 1 ]
Monitoriza la memoria libre¶
#!/bin/bash
while [ true ] ; # se estará ejecutando indefinidamente
do
mem=`free -m |awk 'NR==2 {print $4}'`
# free -> da la memoria libre del sistema
# -m : en megas
# awk -> extrae texto
# NR==2 : la 2ª línea
# {print $4}: la 4ª columna
if [ $mem -lt 10 ]; # Cuando sea menor de 10
then
echo "La memoria libre es menor de 10MB" | /bin/mail -s "ERROR MEMORIA" sarita@correo.com
fi
sleep 5 # Esperamos 5 segundos, antes de la siguiente ejecución del bucle
done # fin while
Informe diario de los servidores OAS¶
#!/bin/bash
# /root/test_oas
################################################
# #Comprueba el estado de los servidores OAS y #
# # envia correo con la información #
# # #
# # Notas: #
# # #
# # - Se ejecuta todas los noches via crontab #
# # #
# # Versiones: #
# # #
# # - 1/4/04: Creacióscript (R.Hernando) #
# # - 12/10/04: modif (RFS y JGVF) #
# # - version 2 (30/05/07): #
# # solo envia el correo en caso de errores #
# ##############################################
# -----------------------
# Variables
# -----------------------
FICHERO=/root/estado_oas.tmp
FECHA=`date +"%d%h%y"`
SERVIDOR=`hostname -s`
CORREO="0" #Flag para enviar el correo (si permanece como 0 no se envia, si ocurre algun error se modifica a 1 y se envia el correo)
# ----------------
# Servidor PreExplotacion10g
# ----------------
echo '=================================================' >> $FICHERO
echo 'ULTIMA COMPROBACION DE SERVIDOR PREEXPLOTACION10g' >> $FICHERO
echo '=================================================' >> $FICHERO
# Comprueba los logs de mas de 500MB
echo 'Ficheros de mas 500 MB: ' >> $FICHERO
echo '-------------------------- ' >> $FICHERO
find / -type f \( -size +500000k \) -exec ls -lh {} \; | grep -v "/backup" | grep -v "/proc" | awk '{print $9 " --> " $5 "\n"}' >> $FICHERO
tail -2 $FICHERO | grep "\-\->"
if [ $? = 0 ] # Existe algun fichero de mas de 500 MB
then
CORREO=1
else
echo "No hay ninguna" >> $FICHERO
fi
# Comprueba el estado de las instancias
echo >> $FICHERO
echo 'Estado de las instancias: ' >> $FICHERO
echo '------------------------- ' >> $FICHERO
su - ias10g -c 'opmnctl status | grep -v dcm-daemon | grep -v home | grep -v logloaderd | grep -E "Init|Stop|Down"' >> $FICHERO
if [ $? = 0 ] #Existe alguna instancia chunga
then
CORREO=1
else
echo "todas arriba" >> $FICHERO
fi
# Comprueba el espacio libre en el sistema de ficheros
echo >> $FICHERO
echo 'ULTIMA COMPROBACION DEL Espacio disponible en el Sistema de Ficheros: ' >> $FICHERO
echo '--------------------------------------------- ' >> $FICHERO
echo -e 'Particion \t Disponible' >> $FICHERO
PARTICIONES=`df -h | awk '{print $5}' |grep -v Us|cut -d'%' -f1`
for i in $PARTICIONES
do
if [ $i -ge 90 ] #Alguna particion ocupa mas del 90%
then
CORREO=1
fi
done
df -h | awk '{print $6 "\t\t" $5 "\t" $4}' | grep -v '/dev/shm' | grep -v 'Mounted' >> $FICHERO
# ------------
# Envia correo
# ------------
#mail -s "Estado OAS10g $SErVIDOR el $FECHA" sa-sic@jcyl.es < $FICHERO
if [ "$CORREO" = "1" ]
then
mail -s "ERRORES en $SERVIDOR el $FECHA" sa-sic@jcyl.es < $FICHERO
else
mail -s "$SERVIDOR OK el $FECHA" sa-sic@jcyl.es < /dev/null
fi
#vaciamos $FICHERO
> $FICHERO
Ficheros¶
Quitar líneas repetidas en un fichero¶
cat fichero | uniq
Previamente el fichero ha de estar ordenado.
Nota: con
sort -u
ordenamos y quitamos las líneas repetidas.
Generar web a partir de markdown¶
#!/bin/bash
# Genera una estructura html a partir de ficheros md (markdown)
# 1. Genera la estructura de directorios
# 2. Construye los html
# 3. Genera un fichero índice con un enlace a todos los documentos
OUTPUT=HTML
if [ ! -d $OUTPUT ];
then
mkdir $OUTPUT
fi
files=($(find ./ -type f -name '*.md'))
for i in ${files[*]}
do
printf " Procesando %s..." "${i}"
if [ ! -d "$OUTPUT/$(dirname ${i})" ];
then
mkdir "$OUTPUT/$(dirname ${i})"
printf ".."
fi
pandoc -s -S -t html "${i}" -o "${OUTPUT}/$(dirname ${i})/$(basename ${i%.md}.html)"
printf "... ok\n"
done
Corrige el nombre de los ficheros Unix para que no den problemas si se copian en sistemas de ficheros Windows¶
rename -v 's/[^\x00-\x7F]|\?|\://g' *
Cambiar extensión de un grupo de ficheros¶
Se cambian todos los ficheros con extensión .MOD de un directorio a extensión .mpeg:
for i in *.MOD; do mv "$i" "${i[@]/%MOD/mpeg}"; done
Se hace lo mismo, pero recursivamente en los subdirectorios:
for i in `ls -r */*.MOD`; do mv -v "$i" "${i[@]/%MOD/mpeg}"; done
Multimedia¶
Renombrar ficheros según las etiquetas mp3¶
Para renombrar un fichero:
#!/bin/bash
# Renombra el fichero según las etiquetas mp3, de la forma: NºCanción-Título
TITLE="`id3info "$1" | grep '^=== TIT2' | sed -e 's/.*: //g'`"
#ARTIST="`id3info "$1" | grep '^=== TPE1' | sed -e 's/.*: //g'`"
#ALBUM="`id3info "$1" | grep '^=== TALB' | sed -e 's/.*: //g'`"
#YEAR="`id3info "$1" | grep '^=== TYER' | sed -e 's/.*: //g'`"
TRACKNUM="`id3info "$1" | grep '=== TRCK'| sed -e 's/.*: //g' | cut -d / -f 1`"
#echo "$TRACKNUM - $TITLE.mp3"
mv $1 "$TRACKNUM - $TITLE.mp3"
Para renombrar varios ficheros se llama a este script de la forma
for i in *mp3; do renameMp3.sh $i; done
Convierte un disco en ape y cue en los flac correspondientes¶
# Convertir el ape en flac
ffmpeg -i audio.ape audio.flac
rm audio.ape
# Si tiene un fichero cue dividirlo en pistas:
cuebreakpoints audio.cue | shnsplit -o flac audio.flac -f audio.cue -t "%n - %t"
rm audio.cue
# Etiquetar las pistas
metaflac --export-tags-to=tag.txt audio.flac
rm audio.flac
metaflac --remove-all *.flac
metaflac --import-tags-from=tag.txt *.flac
rm tag.txt
# Añadir carátula
metaflac --import-picture-from=folder.jpg *.flac
# Cambiar el título y el número de pista
metaflac --remove-tag=Title *.flac
for file in *.flac; do titulo=`expr "$file" : '[0-9][0-9] - \(.*\)\.flac$'`; track=`expr "$file" : '^\([0-9][0-9]\) - .*\.flac'`; metaflac --set-tag="Title=$titulo" "$file"; metaflac --set-tag="TrackNumber=$track" "$file"; done
Convierte todos los .flac del directorio actual en .mp3¶
# /opt/bin/flac2mp3.sh
for file in *.flac; do
# Extension
OUTF="${file[@]/%flac/mp3}"
# Si no existe la carátula se extrae
if [ ! -f folder.jpg ]; then
metaflac --export-picture-to=folder.jpg "$file"
fi
# Se extraen las etiquetas
ARTIST=$(metaflac "$file" --show-tag=ARTIST | sed s/.*=//g)
TITLE=$(metaflac "$file" --show-tag=TITLE | sed s/.*=//g)
ALBUM=$(metaflac "$file" --show-tag=ALBUM | sed s/.*=//g)
GENRE=$(metaflac "$file" --show-tag=GENRE | sed s/.*=//g)
TRACKNUMBER=$(metaflac "$file" --show-tag=TRACKNUMBER | sed s/.*=//g)
DATE=$(metaflac "$file" --show-tag=DATE | sed s/.*=//g)
COMMENT=$(metaflac "$file" --show-tag=COMMENT | sed s/.*=//g)
# Se convierte a mp3 con las etiquetas y la carátula
flac -c -d -s "$file" | lame -h -b 320 --add-id3v2 --pad-id3v2 --ignore-tag-errors \
--ta "$ARTIST" --tt "$TITLE" --tl "$ALBUM" --tg "${GENRE:-12}" \
--tn "${TRACKNUMBER:-0}" --ty "$DATE" --tc "$COMMENT" --ti "folder.jpg" - "$OUTF"
done
# Mover los mp3 a un directorio
mkdir mp3
mv *.mp3 mp3/
Convertir un pdf en varias imágenes¶
Necesita imagemagic y ghostscript.
Genera una imagen con cada página del pdf
convert -density 300 musica.pdf musica.png
Convertir todos los png a svg¶
for i in *.png; do convert "$i" "${i[@]/%png/svg}" ; done
Reescala imágenes¶
En este caso carátulas de calibre
#!/bin/bash
# Reescala las carátulas de calibre para que no ocupen tanto
# .. Debe existir el fichero resize.txt (se utiliza como
# .. flag para no reescalar continuamente las mismas carátulas
# .. (estropeándolas poco a poco)
while read file
do
nconvert -quiet -ratio -resize 680 680 -rflag decr -q 60 -overwrite "$file"
done < <(find . -newer resize.txt -name \cover.jpg)
touch resize.txt
Reducir imagen¶
Reducir tamaño de una imagen con buena calidad (por ejemplo para generar un pdf)
convert -resize 60% -filter Lanczos -density 150 -quality 100 esb_original.png esb.png
Automatización¶
Crea un correo a partir de la plantilla correspondiente¶
#!/usr/bin/bash
# correo.sh
# ....Crea un nuevo mensaje de correo
# ....a partir de una de las plantillas de outlook
#
# ....Uso: correo.sh <tipo>
# ....Los distintos tipos son:
# .... * deploy : a SGF2-DES voy a desplegar en desarrollo
# .... * deployOK : a SGF2-DES he desplegado en desarrollo
# .... * preFC : a FC hay una nueva versión en preexplotación
# .... * expFC : a FC hay una nueva versión en explotación
# .... * preFPO : a FPO hay una nueva versión en preexplotación
# .... * expFPO : a FPO hay una nueva versión en explotación
# .... * preFIP : a FIP hay una nueva versión en preexplotación
# .... * exp : a jefes hay una nueva versión en explotación
# .... * ausencia : a todos vacaciones, moscosos, cursos y demás
# Variables
DIR_PLANTILLAS="C:\Users\hervelro\AppData\Roaming\Microsoft\Plantillas"
case $1 in
deploy) PLANTILLA="Voy a desplegar en desarrollo.oft";;
deployOK) PLANTILLA="hecho despliegue en des.oft";;
preFC) PLANTILLA="SGF2_FC - Pase a preexplotación.oft";;
expFC) PLANTILLA="SGF2_FC - Pase a explotación.oft";;
preFPO) PLANTILLA="SGF2_FPO - Pase a preexplotación.oft";;
expFPO) PLANTILLA="SGF2_FPO - Pase a explotación.oft";;
preFIP) PLANTILLA="SGF2_FIP - Pase a preexplotación.oft";;
exp) PLANTILLA="SGF2 - Nueva versión en explotación.oft";;
ausencia) PLANTILLA="SGF2 - Ausencia.oft";;
*) echo "Opción incorrecta.
Las posibles opciones son:
deploy,
deployOK,
preFC,
preFPO,
preFIP,
exp,
ausencia";
exit 1;;
esac
start "" "${DIR_PLANTILLAS}"/"${PLANTILLA}"
exit 0
Copia un fichero al NAS desde el trabajo a través del proxy, con scp¶
# C:\cmder\bin\cpnas.sh
# Copia de un fichero dado al synology desde el trabajo vía el proxy ntlm
# Por defecto lo copia a /tmp
# Nota: la conexión tiene que ser con el usuario admin, ya que usuarios con menos privilegios
#no tienen habilitado Tcp Forwarding en sesiones SSH
# Nota2: parece que desde la junta han cortado la conexión a ritos.ddns.jazztel.es.
# Así que ahora lo hago con un ping, para que se conecte a la ip en lugar de al nombre.
ip_ritos=$(ping -n 1 ritos.ddns.jazztel.es| grep -m 1 -oE '([0-9]{1,3}\.){3}[0-9]{1,3}')
# Explicación del grep
# -m 1 -> solo la primera aparición
# -oE -> la palabra que cumple la expresión regular
#([0-9]{1,3}\.){3}[0-9]{1,3} -> xxx.xxx.xxx.xxx donde cada xxx puede ser de 1 a 3 dígitos
if [[ $1 == "-h" ]]
then
printf "%b" "cpnas [-r] Fichero-a-copiar [Destino]\n"
printf "%b" "\t-r: Copia remota\n"
printf "%b" "\tPor defecto el Destino en copia normal es /tmp y en copia remota el directorio actual\n"
exit 0
fi
if [[ $1 == "-r" ]]
then
REVERSO=1
ORIGEN=$2
if [[ -n "$3" ]]
then
DESTINO=$3
else
DESTINO="."
fi
else
REVERSO=0
ORIGEN=$1
if [[ -n "$2" ]]
then
DESTINO=$2
else
DESTINO="/tmp"
fi
fi
printf "%b" "\nSe va copiar "
if (( REVERSO == 1 ))
then
printf "%b" "desde "
else
printf "%b" "al "
fi
printf "%b" "NAS el fichero $ORIGEN a $DESTINO\n"
printf "%b" "\n"
printf "%b" "\n\nContinuar?\n"
select respuesta in Si No
do
if [ "$respuesta" == "No" ]
then
printf "%b" "\nHasta otra\n"
exit 0
elif [ "$respuesta" == "Si" ]
then
if (( REVERSO == 1 ))
then
scp -r -o "ProxyCommand connect -H localhost:5865 %h %p" -P 443 admin@$ip_ritos:"$ORIGEN" "$DESTINO"
else
scp -o "ProxyCommand connect -H localhost:5865 %h %p" -P 443 "$ORIGEN" admin@$ip_ritos:"$DESTINO"
fi
exit 0
fi
done
# -o "ProxyCommand connect -H localhost:5865 %h %p" -> se conecta utilizando el proxy habilitado en localhost:5865 (proxy ntlm)
# -P 443 -> se conecta al puerto 443 (redirigido por el router al 2222 del nas
# admin@ritos.ddns.jazztel.es -> usuario admin
# $* -> se pasan todos los parámetros, usualmente será el nombre del fichero. También se puede
# pasar -r para que la copia sea del nas al ordenador
Copia de seguridad de la Wiki¶
wget -m ftp://rhernand:*******@ftp.cluster010.hosting.ovh.net/wiki/* -P /volume2/backup/wiki
tar -zcvf /volume2/backup/wiki/backup-$(date +%Y-%m-%d-%H-%M-%S).tar.gz /volume2/backup/wiki/ftp.cluster010.hosting.ovh.net/
Conversión dng a jpg¶
#/opt/dng2jpg.sh
# Convierte todos los ficheros dng de un directorio a jpg (con imagemagic)
for file in *.dng; do
OUT="${file[@]/%dng/jpg}"
echo "Convirtiendo '$file' en '$OUT'"
convert "$file" "$OUT"
done
Actualiza Web¶
# /opt/bin/actualizaWeb.sh
# Compila la nueva web
# hugo update ...
cd /var/services/homes/roberto/Drive/Aplicaciones/web
/opt/bin/hugo -v -d /volume2/www > /tmp/hugo.log
# Actualiza la web vía ftp
lftp -u rhernand,******* -d -e "mirror -vneR --ignore-time /volume2/www /www" ftp.cluster010.hosting.ovh.net > /tmp/ftp.log
Borrar los ficheros de log de más de 1 día de duración¶
#!/bin/bash
echo "Cleaning logs over $1 days old"
find /log_dir -ctime "$1" -name '*log' -exec rm {} \;
Borra líneas de un fichero, mediante sed¶
En este ejemplo las líneas 1 a 10
sed -n -e :a -e '1,10!{P;N;D;};N;ba'
Búsqueda¶
Busca todas las cadenas de caracteres que puedan coincidir con una dirección IP¶
grep -m 1 -oE '([0-9]{1,3}\.){3}[0-9]{1,3}'
Buscar clases java dentro de jars¶
Cómo buscar clases dentro de un directorio con jar:
find . -name "*.jar" |xargs grep -il NombreClase
Buscar cadena de texto en todos los ficheros¶
find -type f -exec grep -l "jcyl_sanidad_proxy" {} +
y si queremos que la búsqueda sea exacta (por palabras)
find -type f -exec grep -lw "jcyl_sanidad_proxy" {} +
awk¶
Cambiar delimitador de un fichero¶
Tenemos un csv generado con Excel, delimitado por comas:
Con
awk '{$1=$1}1' FS="," OFS="\t" file4.csv > file4.txt
pasaríamos a tener:
{$1=$1}1
: Reinicia el bufferFS=","
: Se le dice a awk que el delimitador actual es,
OFS="\t"
: Se le dice a awk que el nuevo delimitador pasa a ser\t
Convertir columnas en filas¶
Se tiene el fichero:
haciendo
awk '{for(i=1;i<=NF;i++){print $i}}' file5.txt > file5_new.txt
se tiene:
Convertir filas columnas en columnas¶
Partiendo del fichero anterior, si hacemos
cat file5_new.txt | tr '\n' ' ' | awk '{$1=$1}1' FS=" " OFS="\t" > file5_restore.txt
Obtener suma de una columna¶
Tenemos el fichero
Si se quiere la suma de la columna col3:
awk 'BEGIN{FS="\t";count=0}{if(NR>1){count+=$3}}END{print count}' file6.txt
se obtiene: 171