Una forma facil de matar multiples procesos desde la linea de comandos es la siguiente :
|
1 |
for pid in $(ps -ef | awk '/patron_a_buscar/ {print $2}'); do kill -9 $pid; done |
Una forma facil de matar multiples procesos desde la linea de comandos es la siguiente :
|
1 |
for pid in $(ps -ef | awk '/patron_a_buscar/ {print $2}'); do kill -9 $pid; done |
El comando xargs nos permite construir y ejecutar comandos desde la entrada estándar, el uso de xargs es bien simple, y lo explicare con ejemplos…
Si por ejemplo quisiéramos buscar todos los ficheros .conf del directorio /etc que contengan la palabra root dentro de su contenido… podemos utilizar el comando find (Para buscar todos los ficheros de /etc que terminen en .conf), y luego con ese resultado utilizamos xarg en conjunto con grep (xarg lo utilizaremos para que ejecute el filtro grep con el resultado como entrada).
El comando seria el siguiente:
|
1 |
find /etc -iname "*.conf" | xargs grep "root" |
Y veremos como resultado todos los ficheros con root en su contenido y la linea con la palabra a su lado.
En este ejemplo no hemos utilizado xargs con ninguna opcion, y para el siguiente ejemplo tampoco utilizaremos ninguna opcion para poder indentificar algunas diferencias importantes, por ejemplo si estamos en un directorio y queremos borrar todo su contenido (Normalmente podemos hacer esto con rm -rf *, pero es un ejemplo para que aprendamos como funciona xargs), hariamos lo siguiente:
|
1 |
ls | xargs rm -rf |
Esto nos borraria todos los archivos de el directorio en el que estamos, y aunque no lo veamos el comando que se genero, poniendo de ejemplo que hay 5 archivos es el siguiente:
|
1 |
rm -rf archivo1 archivo2 archivo3 archivo4 archivo5 |
Con la opcion -n podemos especificar el numero de argumentos en una linea, por ejemplo:
|
1 |
ls | xargs -n1 rm -rf |
Mostraria:
|
1 2 3 4 5 |
rm -rf archivo1 rm -rf archivo2 rm -rf archivo3 rm -rf archivo4 rm -rf archivo5 |
Si ponemos -n2, mostraria:
|
1 2 3 |
rm -rf archivo1 archivo2 rm -rf archivo3 archivo 4 ... |
Ahora que sabemos como funciona el comando XARGS, podremos construir una serie de comandos, por ejemplo queremos que todos los ficheros del directorio /etc que terminen con .conf sean movidos a un directorio especifico (En este ejemplo /backup), utilizaremos xargs con la opcion -I, de la siguiente manera:
|
1 |
find /etc -iname "*.conf" | xargs -I ARG cp ARG /backup |
Donde lo que escribamos delante de el primer ARG sera el primer argumento y lo que escribamos delante de el segundo ARG sera el tercer argumento, y el resultado del find seria el segundo, el comando anterior estaria haciendo lo siguiente:
|
1 2 3 4 5 6 7 8 9 |
cp /etc/prueba.conf /backup cp /etc/prueba2.conf /backup cp /etc/prueba3.conf /backup cp /etc/prueba4.conf /backup cp /etc/prueba5.conf /backup cp /etc/prueba6.conf /backup cp /etc/prueba7.conf /backup ... |
De la misma forma se podria construir con el comando AWK de la siguiente forma :
|
1 |
find /etc -iname "*.conf" | awk '{ print "cp",$0,"/backup"}' | bash |
Awk es un lenguaje de programación creado para procesar texto de ficheros y flujos de datos muy utilizado en ambientes Unix, y disponible en literalmente todas las distribuciones de GNU/Linux, es más, es mencionado en la Single Unix Specification como una de las utilidades necesarias en todo sistema Unix, este gano popularidad como una manera de añadir mas funcionalidad a las tuberías de Unix; Sed y Awk inspiraron a Larry Wall a escribir Perl.
En este articulo vamos a aprender a utilizar AWK como una forma de construir comandos para ser ejecutados en serie, como por ejemplo; mover todos los ficheros encontrados con el comando locate a un directorio o apagar una serie de clientes windows como explicamos en un articulo pasado.
Para que vayan entendiendo mejor vamos a ir escribiendo el comando por partes, el problema que se plantea es el siguiente.
1) Se necesita copiar todos los ficheros que terminen en «conf» del directorio /etc a la carpeta /home.
Lo primero que tenemos que plantearnos es lo que vamos hacer, en este caso es encontrar todos los ficheros que empiezen con .conf del directorio /etc, esto lo podemos hacer con el comando locate de la siguiente manera:
locate /etc/*conf
Esto nos lanzaria algo parecido a esto:
/etc/adduser.conf
/etc/ca-certificates.conf
/etc/debconf.conf
/etc/deluser.conf
/etc/gai.conf
Ahora vamos a construir el comando, el problema nos dice que tenemos que copiar estos ficheros a la carpeta /home, a el comando anterior le añadimos una tuberia y usamos awk de la siguiente manera para construir la serie de comandos:
|
1 |
locate /etc/*conf | awk '{ print "cp -rf "$0" /home"}' |
Esto nos lanzaria algo parecido a esto:
|
1 2 3 4 5 |
cp -rf /etc/adduser.conf /home cp -rf /etc/ca-certificates.conf /home cp -rf /etc/debconf.conf /home cp -rf /etc/deluser.conf /home cp -rf /etc/gai.conf /home |
En el comando anterior hemos añadido una tuberia para que la salida del comando locate la mande a la entrada awk, entonces el comando awk ha impreso todas las lineas (Para eso la variable $0) con la cadena «cp -rf » atras, y la cadena «/home» delante, el resultado es una serie de comandos a los cuales solo le faltaria otra tuberia para poder ejecutarlo.
Para ejecutar estos comandos simplemente añadimos otra tuberia y mandamos la salida a el comando bash, para que los ejecute por linea, por ejemplo:
|
1 |
locate /etc/*conf | awk '{ print "cp -rf "$0" /home"}' | bash |
Guiandonos por este ejemplo podemos construir comandos según las necesidades que tengamos…..
Para pasar una variable desde un shell script hacia AWK se utiliza la opción «-v». por ejemplo :
|
1 2 3 |
#!/bin/bash username=”pepe”; awk -v nombre=$username -F: '{$1==nombre print $5,$6}' /etc/passwd; |
Para retornar la salida de awk hacia un shell script, se realiza de la siguiente forma :
|
1 2 3 4 |
#!/bin/bash username=”pepe”; salida=”$(awk -v nombre=$username -F: '{$1==nombre print $5,$6}' /etc/passwd)”; echo $salida; |
AWK maneja arrays asociativos de dimensión 1 por lo que puede utilizarse cualquier índice, incluso simular arrays ndimensionales array[i,j].
Para realizar un pequeño ejemplo, consideraremos el siguiente archivo «texto.txt», el cual contiene los siguientes datos :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
maria 1 juan 2 pepe 2 salvado 2 juan 2 juan 2 maria 1 salvado 2 luis 3 pepe 2 salvado 2 maria 1 juan 2 pepe 2 salvado 2 juan 2 salvado 2 salvado 2 |
Al ejecutar la siguiente instrucción desde la linea de comandos :
|
1 |
awk '{suma[$1] +=$2} END {for (name in suma) print name,suma[name] }' < texto.txt |
Obtendremos como resultado, lo siguiente :
|
1 2 3 4 5 |
maria 3 pepe 6 juan 10 luis 3 salvado 12 |