Copyright © 2005-2019 LinuxTotal.com.mx
Se concede permiso para copiar, distribuir y/o modificar este documento siempre y cuando se cite al autor y la fuente de linuxtotal.com.mx y según los términos de la GNU Free Documentation License, Versión 1.2 o cualquiera posterior publicada por la Free Software Foundation.
Entre los administradores de sistemas Linux es común el término 'one liners', algo asi como 'los de una línea', y se refiere a un comando o mejor dicho a un conjunto de comandos que en una sola línea de la interface de comandos, combinados adecuadamente producirán un resultado útil y práctico. La unión de estos comandos generalmente se realiza a través del signo barra |, pipe en inglés.
Por ejemplo, si necesitas saber cuantos archivos hay en el directorio actual, el siguiente grupo de comandos lo hará:
ls | wc -l
Hay que recordar un simple principio cuando se usan pipes |, y es que el comando a la izquierda le 'pasa' el resultado de su ejecución al comando a la derecha. En este caso, la salida de ls
se convierte en la entrada de wc
que con la opción l contará las líneas resultantes. Una variante de esto mismo puede ser el siguiente
ls | cat -n
Con la opción n el comando cat
numera las líneas de la salida previa. Creo que con estos ejemplos es suficiente para tener la idea de lo que se trata de hacer a través de un 'one liner'. Veamos ahora unos ejemplos más elaborados.
Digamos que te interesa continuamente saber cuáles son los 5 procesos que consumen más ciclos del CPU:
ps -eo pcpu,user,pid,cmd | sort -r | head -5
Aqui, usas la opción o del comando ps
que permite personalizar la salida del mismo, indicando las columnas que deseas sean mostradas. La opción e del mismo comando indica salida 'extended' es decir procesos de todos los usuarios (más sobre procesos en este artículo de LinuxTotal.com.mx). Toda esta primera salida, que puede ser bastante extensa es tomada por sort
que a través de la opción r realiza un ordenamiento inverso en base a la primera columna, que es 'pcpu', que indicará precisamente el porcentaje de uso de cada proceso en el CPU. Y por último esta salida es enviada al comando head
que muestra las primeras 5 líneas de la salida previa.
Si te gusto el comando o piensas usarlo de manera continua, te conviene entonces crear un alias del mismo, y colocarlo dentro de '.bashrc' o archivo similar para que sea cargado el inicio de la sesión, asi solo tendrás que invocar el alias y no todo el comando.
alias p5="ps -eo pcpu,user,pid,cmd | sort -r | head -5"
Una situación común para administradores de servidores Linux con varias decenas o cientos de usuarios es la de obtener listas rápidas de los usuarios del sistema. Múltiples variantes de 'one liners' se pueden crear para estos casos, una muy simple puede ser la siguiente:
cat /etc/passwd | sort
Pero si solo necesitas el nombre de usuario (username), lo de arriba produce demasiada información, puedes arreglar aun más el comando con lo siguiente:
cat /etc/passwd | sort | cut -d":" -f1
Eso ya produce un resultado mucho mejor, ya que solo muestra los nombres de usuario. El comando cut
permite a través de la opción d indicar cual es el caracter que se utiliza como separador de campos, que en este caso es ':', y con f1 se indica que extraiga el primer campo, que es precisamente el nombre de usuario. Entonces, cat /etc/passwd
muestra todo el archivo de usuarios del sistema, sort
lo ordena, y después cut
extrae solo la primera columna.
Pero si observac con atención, realmente el resultado no es del todo útil, porque tendrás nombres de usuarios del sistema, es decir usernames como apache, bin, lp, etc. Solo se requiere en la lista nombres de usuarios de usuarios reales, es decir de seres humanos, asi que probemos de otro modo:
cat /etc/passwd | sort | gawk '$3 >= 500 {print $1 }' FS=":"
gawk
evalua cada línea de la salida previa (cat /etc/passwd | sort
), y si el tercer campo $3, que es el UID User Id de cada usuario, es mayor o igual a 500 (la mayoría de las distribuciones modernas de Linux comienzan numerando a los usuarios normales a partir de este número), entonces la acción se ejecuta, que esta indicada entre { } llaves, y esta acción es imprimir el primer campo $1. El separador de campor esta indicado a través de la opción FS (field separator).
Veamos otra situación donde tienes un directorio repleto de archivos php revuelto con archivos html y algunos otros archivos con diferentes extensiones. Todos los archivos php necesitas respaldarlos, puede ser el mismo nombre que ya tienen pero agregándole la extensión '.resp' de respaldo al final. El siguiente 'one liner' deberá cumplir con el trabajo:
for f in *.php; do cp $f $f.resp; done
Un ciclo recorrerá todos los archivos en el directorio actual que terminen con 'php' (for f in *.php;
), el nombre de cada archivo se almacenará en la variable $f, la siguiente parte, el interior del ciclo, hará una simple copia (cp
) asi, 'archivo.php' será copiado a 'archivo.php.resp'. En este ejemplo habrás notado que en vez de |, usé ; como separador de comandos, porque no quiero encadenarlos o entubarlos sino que uno se ejecute después del otro y eso se logra con ; como separador de comandos.
¿Que tal hacer copias masivas, a modo de respaldos?, bien, el siguiente comando es un clásico, hay varias versiones del mismo, pero mas o menos es algo como lo siguiente:
tar cf - . | (cd /usr/backups/; tar xfp -)
Copia (realmente produce un paquete comprimido) completa y recursivamente el directorio actual (tar cf - .
), entonces el paquete es enviado al siguiente comando entubado por | ((cd /usr/backups/; tar xfp -)
), los paréntesis crean un subshell en el que se cambia al directorio indicado y extrae x el contenido del paquete, todo el directorio y subdirectorios originales en una nueva ubicación. La opción p en el segundo tar
preserva la fecha, permisos, etc. de cada archivo. Después de completarse la copia, el prompt del shell regresa al directorio original.
Una variante del previo 'one liner' es cuando necesitas hacer lo mismo, pero en un servidor remoto, no en el mismo equipo como previamente se mostró:
tar cf - . | ssh sergio@servidor.remoto tar xfp - -C /usr/respaldos/sergio
En este caso, una sesión de ssh
es establecida después de que el comando inicial tar
hizo su trabajo, la opción C indica al segundo tar
cambiar de directorio, que será '/usr/respaldos/sergio' en el servidor remoto y ahí es donde la extracción se realizará completando el respaldo.
Procesamiento de texto es otro lugar común para los 'one liners', cosas asombrosas pueden realizarse con el conjunto y orden correcto de comandos. En el siguiente ejemplo, un reporte de correos entrantes pudiera lucir como lo que sigue:
$> cat correos_entrantes 2008-07-01 08:23:17 usuario1@ejemplo.com 2008-07-01 08:25:20 usuario2@someplace.com 2008-07-01 08:32:41 alguien@server.net 2008-07-01 08:35:03 spam no recibido, filtrado 2008-07-01 08:39:57 usuario1@ejemplo.com ...
Se te pide un reporte con lista ordenada alfabéticamente de los correos entrantes. Muchos correos se repiten a través del reporte original, y solo se necesita uno de cada uno. El siguiente 'one liner' lo resuelve completamente:
grep '@' incoming_email | gawk '{print $3}' | sort | uniq
La salida o resultado es el siguiente:
alguien@server.net usuario1@ejemplo.com usuario2@someplace.com
grep
filtra las líneas que contienen un caracter '@'. A continuación gawk
extrae del resultado el tercer campo que es la dirección de correo electrónico, después esta lista de correos es ordenada alfabéticamente con sort
. Esto es necesario para que agrupe los correos similares, ya que el último comando uniq
sin opción alguna omite las líneas repetidas de la lista ordenada previamente. El resultado final es una lista de correos pero solo uno de cada uno, ya que no tiene caso mostrar las repeticiones.
Estoy consciente de que puede haber mejores y más simples variaciones de los comandos mostrados en este artículo. La idea es introducir a los principantes o incluso a usuarios ya más acostumbrados a la línea de comandos pero que desean mejorar sus habilidades en la formación de comandos elaborados. Si tu eres un administrador de sistemas es una buena práctica, crear o modificar a partir de otros, tus propios 'one liners', clasificarlos y tenerlos a la mano para cuando los necesites, nunca se sabe. Por ejemplo, en el último ejemplo, digamos que necesitas saber cuantos correos distintos hay en el resultado final, a lo que ya tienes solo necesitas agregar wc -l
para obtener el resultado.
Recuerda siempre el espíritu detrás de Linux y del movimiento Open Source, "compartir", asi que si tienes un buen 'one liner' por ahí deja que todos nos beneficiemos de el, compártelo.
Si encuentras útil la información que proveé LinuxTotal, considera realizar un donativo que estimule a seguir proporcionando contenido de calidad y utilidad. Gracias.
Dona a través de paypal::
O a través de bitcoins:
¿Olvidaste o perdiste la contraseña del usuario 'root' de MySQL?, no hay problema, solo sigue estás sencillas instrucciones y p....
Lo primero que debes hacer una vez que instalas un servidor de base de datos MySQL (casi todas las distros actuales lo instalan po....
Imagínate que eres un administrador de sistemas Linux que trabaja desde un equipo Windows y usas Putty para conectarte a los serv....
mysqldump es una utilieria cliente de MySQL que te permite respaldar bases de datos. Aprende por ejemplos como utilizarlo. Puedes....
En Linux hay diversas herramientas para empaquetar y comprimir archivos, tomando en cuenta que empaquetar es juntar dos o más arc....
Cuando tu creas un documento de texto en MSDOS/Windows (como por ejemplo en notepad.exe), Windows añade al final de cada línea u....
Este es un pequeño y útil tip que te permitirá crear PDF's a partir de páginas del manual. Cuando deseas ver la ayuda de un co....
En este archivo de configuración se indica el modo en que los mensajes del sistema son bitacorizados a través de la utileria sys....
ssh es quizás (en mi opinión) la mejor herramienta de comunicación que existe cuando se trata de establecer contacto con un ser....
Linux es un sistema multiusuario, por lo tanto, la tarea de añadir, modificar, eliminar y en general administrar usuarios se conv....