Bash: Ejemplos

Por Paco Aldarias Raya

Impreso: 1 de mayo 2007

Email: pacolinux arroba inicia punto es

Web: http://aldarias.es/pacodebian

Con Linux Debian. En Valencia (España)

El documento tiene version .html, y .pdf, cambiando en el navegador la parte final podrás acceder a ambos.

Este documento es de libre reproducción siempre que se cite su fuente.

Realizado con: LATEX

Índice General

1 Introducción

2 bash

Vamos a ver ejemplo de uso del bash

3 Arbol de directorios

Para obtener el arbol de directorios.

func_recursiva()
    {
    for OBJ in *
    do
        if [ -L "${OBJ}" ]
        then
            #echo "[e] ${OBJ} <-- Enlace"
            continue
        fi

        (
        if [ -d "${OBJ}" ]
        then
            #echo "[d] ${OBJ} <-- Directorio"
            cd "${OBJ}"
            pwd
            #du -s -c -h
            func_recursiva
        fi
        )

#echo "[f] ${OBJ} <- Fichero"

 done
 }


func_recursiva

4 Renombrar ficheros

Elimina una extensión .tar final de archivo.tar.bz2.tar para dejarlo en archivo.tar.bz2.

  1. Suponiendo que el nombre del archivo no contenga "." y que los archivos esten en el directorio en el que ejecutes esto:

    for nombre in *.tar.bz2.tar; do
       nuevo_nombre=`echo $nombre | gawk -F. '{print $1"."$2"."$3}'`
       mv $nombre $nuevo_nombre
    done
    

  2. Este guión, con la opción -ss, elimina el sufijo indicado de los objetivos:

    for fich in *.tar; do mv fich $(nombase -ss.tar $fich);done
    

  3. El signo del dolar indica el final de línea; la construcción s/x/y/ es la clásica utilizada para sustituir x por y:

    rename 's/.tar$//' *.tar
    

5 Borrar los archivos contenidos en un fichero

Esto borra los ficheros contenidos en fichero.txt, q es de la forma /carpeta/fichero1.txt /carpeta/fichero2.txt

  1. xargs -i rm "{}" < fichero.txt
    

  2. for linea in 'cat fichero.txt'
    do
       rm $linea;
    done
    

6 Borrar los ficheros que comiencen con p en el directorio actual y en todos sus subdirectorios

find ./ -name "p*" -exec rm -f {} \;

find -name 'p*' -type f -exec rm {} \;

7 Mover los ficheros

Que contienen el texto Way a la carpeta /wind/musica/way/:
find /lector -name "*Way*" -exec mv  {} /wind/musica/way/ \;

8 Para descomprimir todos los archivos zip de una carpeta en otra

echo DESCOPRIMIENDO  ZIPS
echo Ejemplo: ./unzip.sh  /origen/ /destino

cd $1
for i in $(ls *.zip); do
f=$(echo $i | cut -d. -f1);
echo [*] Descomprimiendo $i en $2$f;
mkdir $1$f;
cd $1$f;
unzip $1$i -d $2/$f;
done

9 Copiar un fichero en otro poniendo la fecha y hora

echo Ejemplo: ./copiar.sh fichero
echo copiando $1 $1$(date +%d-%m-%Y-%H-%M)
cp $1 $1$(date +%d-%m-%Y-%H-%M)

10 Analizar el arranque y realizar algo

Se trata de tener un arranque del dma controlado.

Me surgio la necesidad de que al arrancar mi disco duro, el cual no iba bien. Me salía este error:

Oct  9 12:24:42 pacohost kernel: hda: dma_intr: error=0x84
{ DriveStatus ErrorBadCRC }

Oct  9 12:24:42 pacohost kernel: hda: dma_intr: status=0x51
{ DriveReady SeekComplete Error }

La idea era comprobar que si en el arranque sale este error desactive el dma, paraque no salga mas este error.

Veamos los ficheros que utilizo:

Aquí analizo la salida de dmesg, si contiene la cadena status, aplico el script hd.sh que desactiva el dma.

cat /etc/rc2.d/S01ifhd.sh
#!/bin/bash
echo ANALISIS DMA:
if [ -n "$(dmesg | grep 'status=0x51')" ]; then
   echo "Error de dma"
   /root/hd.sh
else
   echo OK DMA
fi

cat /root/hd.sh
hdparm -k1 -c0 -d0 -X64 /dev/hda

11 Enviar n mensajes de correo

Vamos a ver la forma de enviar n mesajes a un email:

Veamos el script:

echo Ejempplo: ./mailbucle.sh 10 spam@hotmail.com
echo enviando $1 mensajes a $2
for i in `seq 1 $1`;
        do
        #echo "SPAMMMMMMMMMMMMMMMM" | mail -s "" paco
        mail -u usuario -s "encabezado" $2  < kk.txt

Siendo kk.txt el fichero q se envia.

12 Clonar usuarios

Esto permite copiar todos los ficheros de un usuario en /etc/skel, para q al crear un usuario tenga la misma configuración.

echo Ejemplo -siendo root-: ./skel.sh paco
usu=$1
echo Copiando ficheros del usuario $usu
cd /home/$usu
tar cpBf /etc/skel/$usu.tar.gz .

echo Extrayendo esqueleto del usuario $usu
cd /etc/skel/
tar xvBpf $usu.tar.gz
rm $usu.tar.gz

Usando ssh:

ssh usuario@maquina_remnota tar -cvpSf - / | tar -xvpf -

13 Sustituir un texto por otro

13.1 sec

Sustituye .o por .ko
cat util | sed -e "s/.o/.ko/" > util1
mv util1 util

13.2 tr

cat xx
abc def
ghi abc
jkl mno
abc pqr

tr abc 123 < xx
123 def
ghi 123
jkl mno
123 pqr

14 Quitar los blancos de los nombre de los archivos

for i in *; do
   nuevo=`echo $i | sed -s 's/\ //g'`;
   mv "${i}" ${nuevo};
done

O tambien así:

for i in *; do mv "$i" "`echo $i | tr ' ' '_'`"; done

15 Buscar todas las imagenes y renombrarlas por la hora actual

El script renombraba las imagenes en función de la fecha y hora, y en el caso de que varias fotos fueran hechas en en mismo segundo, añadía una letra al nombre (a, b o c).

#! /bin/bash
shopt -s extglob # for improved file pattern matching
for imgname in *.+(jpg|JPG);
do
   newname="$(head $imgname|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; s/:/-/g; s/$/.jpg/; p}'|uniq)"
   # if there is already another file with the same name append an extension (b or c).
   # Just thinking a bit more this can be improved, but IMHO it will work OK:
   if ls ${newname%%.jpg}* &> /dev/null; then
       if   [ -f ${newname%%.jpg}b.jpg ]; then newname=${newname%%.jpg}c.jpg
       elif [ -f ${newname} ]; then newname=${newname%%.jpg}b.jpg
       fi
   fi

   mv ${imgname} ${newname}
done

16 Renombrar canciones

Vamos a cambiar de nombre a muchos archivos, son archivos mp3 y la estructura es la siguiente:

Grupo - cancion - num - Disco.mp3  (el grupo tiene espacios en blanco)

y quiero que termine en num-cancion.mp3.

Script para bash

for i in *.mp3
do
        titulo=`id3 -lR $i | grep -e "^Title" | cut -f2- -d ' '`
        artista=`id3 -lR | grep -e "^Artist" | cut -f2- -d ' '`
        album=`id3 -lR | grep -e "^Album" | cut -f2- -d ' '`
        num=`id3 -lR | grep -e "^Track" | cut -f2- -d' '`
        mv "$i" "$artista-$titulo-$num-$album.mp3"
done

Lees directamente de cada fichero mp3 la información que tiene para renombrar el archivo con su contenido

17 Sacar las ips de las máquinas conectadas en la red indicada

17.1 opcion

# Nmap-pacolinx
# Este script saca las ips de las máquinas conectadas en la red indicada
# Por Paco Aldarias
# Fecha: 15.05.04
# pacolinux arroba inicia punto es
# Valencia - España

t=temp.txt # fichero temporal
f=nmap.txt # fichero resultado
r=192.168.0.1-3   # rango de busqueda de la red

echo [Nmap-pacolinx] Maquinas conectadas en la red $r
nmap -sP -n  $r > $t
lineas=`wc -l < $t`  # cogemos la linea
I=3
while [ $I -lt  $lineas ] # recorremos todas la lineas menos la ultima
do
linea=`sed -n ${I}l $t`
ip=`echo $linea | cut -d" " -f2`
echo $ip >> $f
I=`expr $I + 1`
done
cat $f
rm -f $t $f

17.2 opcion

esto tb se puede hacer asi:

nmap -sP 192.168.0.* |grep appears |cut -f3 -d" " |tr \( " " |tr \) " " \
> nmap.txt

Esto filtra la linea q tienes las ips:

nmap -sP 192.168.0.* |grep appears
Es decir saca esto:
Host paco (192.168.0.1) appears to be up.

Esto saca la ip, q la 3ra cadena:

nmap -sP 192.168.0.1 |grep appears |cut -f3 -d" "
Es decir saca esto:
(192.168.0.1)

La última parte reemplaza los parentesis por blancos:

nmap -sP 192.168.0.* |grep appears |cut -f3 -d" " |tr \( " " |tr \) " "
Es decir saca esto: 192.168.0.1

17.3 opcion

nmap -sP 192.168.0.0-1 | awk '/appears to be up/ {print $3}' | sed 's/[()]//g' \
> nmap.txt

18 Sacar el nombre de la maquina o dns

La orden es host x.x.x.x siendo x.x.x.x la ip.

Ejemplo:

#host 192.168.0.1
Name: paco
Address: 192.168.0.1

Queremos que saque el nombre, en este paco seria:
paco

Se puede hacer asi:

host 192.168.0.1 | grep Name | cut -f2 -d " "

o tb así:

host 192.168.0.1 | awk '/Name: / {print $2}'

19 Reducir fotos

apt-get install libjpeg-progs
mkdir ../fotos-reducidas
for a in `ls *.jpg`; do
  djpeg -scale 1/4 $a | cjpeg -q 95 > ../fotos-reducidas/$a
done

20 Cambiar todos los enlaces de las paginas de una carpeta por otro enlace

Esto cambia el enlace http://aldarias.es/pacodebian por http://www.iespana.es/pacolatex en todas las paginas web del directorio.

find . -type f -name \*.html -print | while read f ; do
  sed -i 's^http://aldarias.es/pacodebian^http://www.iespana.es/pacolatex^g' "$f"
done

o tb

sed -i 's^http://aldarias.es/pacodebian^http://www.iespana.es/pacolatex^g'
$(find . -type f -name \*.html)

21 Reemplazar un texto por un fichero

cat a.txt

a
b
c
d
e

cat b.txt

A
B
C
D

sed '/^c/rb.txt' a.txt

a
b
c
A
B
C
D
d
e

22 Quitar un texto en un fichero

Este scrip elimina la cadena x90 de los ficheros que se le pasan. Para ello usa grep -v x90 para sacar todo menos ese texto.

cat apache.sh

# Script que elimna una cadena de los ficheros indicados.
# Por Paco aldarias
# 31.03.05
# http://www.linux-es.org/art.php?id=208

c="x90"
# Eliminado cadena $c

f=/var/log/apache/access.log
echo $f
cat $f | grep -v $c > $f

f=/var/log/apache/access.log.1
echo $f
cat $f | grep -v $c > $f

echo Ficheros comprimidos
find /var/log/apache/ -type f -name \access*.gz -print | while read f ; do
      echo $f
      gunzip -c $f | grep -v $c |  gzip  >  $f
done

23 Obtener la edad

echo $(( `date +%Y` - 1966 ))

24 Recursos del pc con bash

#!/bin/bash
# Por Paco Aldarias.
# 12.4.06
# recursos.sh
echo "********************************************************************************************"

h=$(hostname)
echo "* NOMBRE PC [$h]"

kernel=$(uname -mnrs)
tpo=$(uptime | cut -d "," -f1)
usu=$(users)
echo "* TIEMPO [ENCENDIDO $tpo] [USUARIOS: $usu] [KERNEL: $kernel]"

cpui=$(cat /proc/cpuinfo | grep "model name" | tail -f -n 1 |  cut -c 14-)
#usuario=$(atsar -u 1 3 | tail -n 1 |  awk -F " " '{print $2}')
#sistema=$(atsar -u 1 3 | tail -n 1 |  awk -F " " '{print $4}')
#total=$(expr $usuario + $sistema)
#echo "* CPU: [$cpui]  [Usuario: $usuario %] [Sistema $sistema %] [Total: $total %]"

memt=$(/usr/bin/free | grep "Mem" | awk -F " " '{print $2}')
memf=$(/usr/bin/free | grep "Mem" | awk -F " " '{print $3}')
mems=$(/usr/bin/free | grep "Swap" | awk -F " " '{print $2}')
echo "* MEMORIA: [Total $memt] [Fisica usada: $memf] [Swap usada: $mems]"

ip0=`/sbin/ifconfig eth0 | grep "inet addr:" | awk '{print $2}' | cut -c  6-`
mac0=`/sbin/ifconfig eth0 | grep "HWaddr" | awk '{print $5}'`
ad0=$(lspci  | grep Ethernet | sed -e 2d | cut  -c 35-)
/usr/sbin/iptotal -r 5 eth0 > iptotal.txt
in0=`cat iptotal.txt |  awk '{print $5}'`
out0=`cat iptotal.txt |  awk '{print $8}'`
echo "* RED ETH0: [IP: $ip0] [MAC: $mac0] [Tarjeta: $ad0] [Entra: $in0 KB/s] [Sale: $out0 KB/s]"

ip1=`/sbin/ifconfig eth1 | grep "inet addr:" | awk '{print $2}' | cut -c  6-`
mac1=`/sbin/ifconfig eth1 | grep "HWaddr" | awk '{print $5}'`
ad1=$(lspci | grep Ethernet | sed -e 1d | cut  -c 35-)
/usr/sbin/iptotal -r 5 eth1 > iptotal.txt
in1=`cat iptotal.txt |  awk '{print $5}'`
out1=`cat iptotal.txt |  awk '{print $8}'`
echo "* RED ETH1 [IP: $ip1]  [MAC: $mac1] [Tarjeta: $ad1]  [Entra: $in1 KB/s] [Sale: $out1 KB/s]"

ps aux  > procesos.txt 2>/dev/null
total=`wc -l < procesos.txt`
total=`expr $total - 1`
ps aux  | grep root  > procesos.txt 2>/dev/null
root=`wc -l < procesos.txt`
root=`expr $root - 2`
echo "* PROCESOS: [total: $total] [Root: $root]"
#cat top.txt | sed -e '1,7d' | head -f 1

#hda1t=$(df | grep hda1  | awk '{print $2}')
#hda1u=$(df | grep hda1  | awk '{print $3}')
#hda1d=$(df | grep hda1  | awk '{print $4}')
#echo "* HDA1: [total: $hda1t] [Usado: $hda1u]  [Disponible: $hda1d] "
echo "* DISCOS: "
df
echo "********************************************************************************************"

25 Script del dns dinamico cdmon

Este script es para poder actalizar la ip dinamica, del dns cdmon. http://www.cdmon.com

#!/bin/bash
#
############################ Autor
# Enrique Garcia Alvarez <kike>
# kike arroba eldemonionegro punto com
# http://www.eldemonionegro.com
#
# Si mejoras o modificas este script, por favor comunica las mejoras al autor.
# Gracias
#
# Software para la administracion de dominios
# Copyright (C) 2005-2006
#
############################# Licencia
# Este programa es software libre. Puede redistribuirlo y/o modificarlo
# bajo los teminos de la Licencia Publica General de GNU segun es publicada
# por la Free Software Foundation, bien de la version 2 de dicha Licencia
# o bien (segun su eleccion) de cualquier version posterior.
#
# Este programa se distribuye con la esperanza de que sea util,
# pero SIN NINGUNA GARANTIA, incluso sin la garantia MERCANTIL implicita o
# sin garantizar la CONVENIENCIA PARA UN PROPOSITO PARTICULAR.
# Vease la Licencia Publica General de GNU para mas detalles.
#
# Deberia haber recibido una copia de la Licencia Publica General junto
# con este programa. Si no ha sido asi, escriba a la
# Free Software Foundation, Inc., en 675 Mass Ave, Cambridge, MA 02139, EEUU.
# MIRA AQUI PARA SABER MAS ==>> http://www.gnu.org/copyleft/gpl.html
#
############################# License
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# SEE HERE FOR MORE ==>> http://www.gnu.org/copyleft/gpl.html
#
############################ PROTOCOLO
# Para poder actualizar su IP tiene que hacer una llamada a la siguiente URL:
#   https://dinamico.cdmon.org/onlineService.php
# con los argumentos via GET siguientes:
#   enctype=MD5
#   n=nombre_de_usuario
#   p=contrasea_codificada_con_md5
# si la IP que quiere actualizar es diferente a la IP que le asigna el sistema
# puede definir una IP propia con el argumento "cip"
#   cip=x.x.x.x
# de modo que tendremos:
#   https://dinamico.cdmon.org/onlineService.php?enctype=>>
#   >>MD5&n=usuario&p=1bc29b36f623ba82aaf6724fd3b16718&cip=x.x.x.x
# donde cip es opcional ya que al hacer la peticin via URL el servidor devuelve
# un resultado.
#
#   RESULTADOS:
# la peticion https nos devuelve una variable con el formato siguiente:
#   &resultat=resultado de la peticin del servidor&
# donde tenemos las siguientes opciones:
#
# Cuando se hace una peticin sin la variable cip y la autentificacin ha sido
# correcta nos devuelve la IP actual que detecta el servidor.
#   &resultat=guardatok&newip=x.x.x.x&
#
# Cuando hemos mandado nuestra IP mediante la variable cip y la autentificacin
# ha sido satisfactoria.
#   &resultat=customok&
#
# Nos devuelve este resultado cuando la autentificacin ha sido
# pero la IP es erronea.
#   &resultat=badip&
#
# Nos devuelve este resultado cuando la autentificacin no ha sido satisfactoria.
#   &resultat=errorlogin&
#
# Nos devuelve este resultado en raras ocasiones, solo cuando modificamos el
# archivo que procesa todas las peticiones para obligar a todos los usuarios a
# actualizar a una nueva version de la aplicacion. En su caso solo tendra
# que ponerse en contacto con nosotros para obtener
# la nueva URL para hacer la peticion.
#   &resultat=novaversio&
#
############################ INICIO
## Datos de usuario de CDMON.ORG
# USUARIO = es el nombre de usuario para entrar en CDMON.ORG
# PASSWORDMD5 = Es la contrasenia para entrar en CDMON.ORG encriptada con
# el algoritmo MD5. Hay programas (tambien online) para ello.

USUARIO=aldarias
#PASSWORD=perla02
#PASSWORDMD5=$(echo $PASSWORD | md5sum | cut -d " " -f1)
PASSWORDMD5="e360db7b55e4a9744e941b619796bd84"
## Datos propios de la maquina donde ejecutamos el script
# IFZ = Interfaz de red que se conecta a Internet
# EMAIL = Direccion de correo donde enviar las notificaciones de los cambios

IFZ=eth0
EMAIL=faldarias526v@cv.gva.es
HOST=aldarias.es

GET_IP="https://dinamico.cdmon.org/onlineService.php?enctype=MD5&n=$USUARIO&p=$PASSWORDMD5"
IP_DNS_ONLINE=`wget --no-check-certificate $GET_IP -o /dev/null -q -O /dev/stdout | cut -f2 -d\& | cut -f2 -d=`
IP_ACTUAL=`ifconfig $IFZ | grep "inet addr" | cut -f2 -d: | cut -f1 -d' '`

echo -e "IP DNS $IP_DNS_ONLINE  IP ACTUAL $IP_ACTUAL"

if [ "$IP_DNS_ONLINE" != "$IP_ACTUAL" ]; then

CHANGE_IP="https://dinamico.cdmon.org/onlineService.php?enctype=MD5&n=$USUARIO&p=$PASSWORDMD5&cip=$IP_ACTUAL"
RESULTADO=`wget --no-check-certificate $CHANGE_IP -o /dev/null -O /dev/stdout`

MENSAJE="Ha habido un cambio en la IP de los nombres de dominio.\n"
MENSAJE=$MENSAJE"Se han actualizado los servidores DNS dinamicos de CDMON.\n"
MENSAJE=$MENSAJE"El resultado devuelto ha sido el siguiente:\n"

#echo -e "$IP_DNS_ONLINE $IP_ACTUAL $MENSAJE $RESULTADO. Mirar: /root/cdmon.txt" | mail $EMAIL -s "cambio de IP"
#echo "$(date +%Y-%M-%d-%H-%m) ACTUAL: $IP_ACTUAL; NUEVA:IP_DNS_ONLINE" >> /root/cdmon.txt

echo -e "$IP_DNS_ONLINE $IP_ACTUAL $MENSAJE $RESULTADO.\n"

fi

############################ FIN

26 Bibliografía

  1. HANDY ONE-LINERS FOR SED
    http://sed.sourceforge.net/grabbag/tutorials/


Índice de Materias

Sobre este documento...

Bash: Ejemplos

This document was generated using the LaTeX2HTML translator Version 2002-2-1 (1.71)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The command line arguments were:
latex2html bash -split 0 -local_icons 1 -show_section_numbers -no_auto_link -no_navigation

The translation was initiated by Paco on 2007-05-01


Paco 2007-05-01