# rm-rf.es | Administración de sistemas

Bitácora personal de un SysAdmin Gnu/Linux, Windows, BSD...

tee linux: mandar la salida de un comando a dos sitios


Tee Linux
Imágen: wikipedia

Tee es un comando Linux (bueno, realmente está disponible en Unix, 4DOS/4NT y Windows PowerShell) que permite copiar la entrada estándar de un comando a un archivo y así mismo seguir teniendo salida estándar por pantalla/terminal.
Copia la entrada estándar a cada ARCHIVO, y también a salida estándar.

Vamos a ver un ejemplo sencillo, ejecutamos el comando ps y a su vez volcamos su salida a un fichero:

$ ps | tee ps.txt
  PID TTY          TIME CMD
 2901 pts/6    00:00:00 bash
 3111 pts/6    00:00:00 ps
 3112 pts/6    00:00:00 tee
$ cat ps.txt
  PID TTY          TIME CMD
 2901 pts/6    00:00:00 bash
 3111 pts/6    00:00:00 ps
 3112 pts/6    00:00:00 tee

Hemos verificado que el contenido de la salida se ha almacenado en el fichero ps.txt y a su vez seguimos visualizandolo por pantalla, si no usaramos el comando tee y volcaramos la salida a un fichero no lo veríamos por pantalla (ver artículo redirigir stdin, stdout y stderr en Unix/Linux):

$ ps > ps.txt

El comando tee tiene muchas más posibilidades, recuerdo por ejemplo el artículo en el que explicabamos como guardar un fichero dentro de VIM cuando no tenemos permisos en vim:

:w !sudo tee %
[sudo] password for alex:

Cómo encontrar fallos e inconsistencias en los ficheros passwd y shadow


Linux passwordExiste un comando llamado pwck que mediante su ejecución verifica que la información contenida en los ficheros de autenticación /etc/passwd y /etc/shadow es correcta. Básicamente comprueba el número de campos en cada una de las entradas de los ficheros, verifica la existencia de los campos de login, UID y GID además de revisar que el directorio home de cada usuario existe y la shell que utiliza.

Su ejecución es simple, ejecutamos como root el comando y examinamos la salida, en este ejemplo vemos inconsistencia con los directorios home de varios usuarios (no existen:

# pwck
usuario «lp»: directorio «/var/spool/lpd» no existe
usuario «news»: directorio «/var/spool/news» no existe
usuario «uucp»: directorio «/var/spool/uucp» no existe
usuario «www-data»: directorio «/var/www» no existe
pwck: sin cambios

Si por ejemplo pusieramos una shell incorrecta al usuario www-data nos avisaría del fallo:

# pwck
usuario «www-data»: directorio «/var/www» no existe
usuario «www-data»: programa «/bin/shtest» no existe

Podemos probar (¡no lo hagáis con usuarios importantes o en servidores en producción!)a eliminar la columna del grupo en el usuario. pwck nos avisará y de forma activa nos indicará si queremos eliminar la línea incorrecta:

# pwck
entrada del archivo de contraseñas no válida
¿eliminar la línea «www-data:x:33::www-data:/var/www:/bin/sh»? no
ninguna entrada del fichero de contraseñas concuerda con /etc/passwd
¿eliminar la línea «www-data:*:14889:0:99999:7:::»? no

Si aceptamos las modificaciones nos indicará que se han realizado cambios en los archivos:

pwck: los archivos se han actualizado

Cómo evitar los saltos de línea en el comando unix df


Cuando el nombre de una partición o volúmen es demasiado largo, al mostrarla con el comando df se crea un salto de línea para mantener la estructura de las columnas y tabulaciones:

# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                      447G  6.3G  417G   2% /
/dev/sdb1             996M   39M  906M   5% /tmp
/dev/sda1              99M   24M   70M  26% /boot

Esto puede ser un problema en algunas ocasiones en las que queramos recoger los datos de la salida del comando. Para evitarlo, únicamente tenemos que utilizar el parámetro

-P

y se respetará el nombre y el resto de información en la misma línea:

# df -hP
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00  447G  6.3G  417G   2% /
/dev/sdb1             996M   39M  906M   5% /tmp
/dev/sda1              99M   24M   70M  26% /boot

Un truco simple que puede parecer una tontería pero es muy útil en ciertas ocasiones.

Comando DATE en bash: sumar y restar años, días o meses a la fecha actual


El comando date, a través del parámetro

-d, --date=STRING

permite mostrar y calcular la fecha distinta a la actual a partir de la suma o resta de X años, meses, días, minutos o segundos. Esto es útil cuando queremos por ejemplo añadir o restar 7 días a la fecha actual. Vamos a ver unos cuantos ejemplos:

Sumar 7 días a la fecha actual y mostrarlo en formato estándar:

$ date --date='+7 day'
vie may 13 17:40:47 CEST 2011

Restar 7 días a la fecha actual y mostrarlo en formato timestamp:

$ date +%s --date='-7 day'
1304091656

Sumar un año a la fecha actual con formato de fecha y hora:

$ date +%c --date='+1 year'
dom 06 may 2012 17:41:53 CEST

Restar dos meses a la fecha actual:

$ date --date='-2 month'
dom mar  6 16:42:48 CET 2011

Y así muchos más ejemplos. Seguro que os resulta muy útil dentro de scripts en bash por ejemplo.

Linux: enviar señales a un proceso con el comando kill


Kill es un comando unix/linux que permite enviar señales a uno o varios procesos del sistema a través de la shell (bash, ksh, etc). Las señales más utilizadas suele ser la de matar un proceso (9 ó SIGKILL), pararlo (TERM) o reiniciarlo (1 ó HUP) pero hay muchas más que pueden ser útiles en ocasiones. El listado completo de señales disponibles puede visualizarse ejecutando

kill -l

:

$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX

Para solicitar la finalización de un proceso, se utiliza la señal TERM, que es la señal por defecto si no se especifica otra. así que para solicitar el fin de ejecución de uno o varios procesos únicamente tenemos que ejecutar

kill

seguido de los PID correspondientes:

# kill 3454 3459 3750

Para forzar que uno o varios procesos terminen de forma inmediata (sin solicitar ni preguntar…) usamos la señal SIGKILL (9). Hay que ser cautos al usar esta señal porque fuerza a los procesos a terminar inmediatamente sin permitirles terminar de forma limpia, es decir, puede que no borre los PID, que no deje terminar las peticiones pendientes, etc:

# kill -9 6574

Si quisieramos forzar que todos los procesos con un determinado nombre finalicen inmediatamente usaríamos

killall

en lugar de

kill

:

# killall -9 httpd

Otro ejemplo sería el de suspender un proceso, para ello le enviamos la señal de STOP (19) seguida del proceso. Si no conocemos el ID de la señal podemos hacerlo también a través del nombre. En esta señal el proceso quedaría suspendido, por lo que todavía figuraría en la lista de procesos y podríamos reanudarlo posteriormente (próximo ejemplo):

# kill -19 5227

ó

# kill -STOP  5227

Ahora que sabemos suspender procesos, es interesante conocer como reactivarlos, para ello usamos la señal CONT (18). En este ejemplo vamos a “revivir” el proceso anterior:

# kill -18 5227

ó

# kill -CONT  5227

Una de las señales más importantes es HUP (1). Esta señal para y reinicia el proceso indicado, también se puede aplicar con el nombre del proceso además del ID.

# kill -HUP 9873

ó

# kill -HUP script.sh

En caso de querer utilizarlo para por ejemplo, reiniciar todos los procesos httpd usaríamos

killall

en lugar de kill:

# killall -HUP httpd

Estos son algunos ejemplos de utilización de señales sobre procesos, como siempre os digo, podéis revisar las páginas man para profundizar sobre todas las señales disponibles.

Utilizar variables dentro de sed


Si necesitamos utilizar variables dentro de la ejecución del comando sed, si lo hacemos del modo “estandar” no funcionará correctamente:

sed -i '/${VARIABLE}/d' fichero

Será necesario utilizar comillas dobles en lugar de comillas simples, de ese modo funcionará correctamente:

sed -i "/${VARIABLE}/d" fichero

/etc/rc.local: Ejecutar comandos o scripts en el arranque de *nix


Si no queremos crear un script único (aunque suele ser lo recomendable) para la ejecución de un comando o un script cada vez que iniciamos un sistema tipo Unix (BSD, Gnu/Linux, etc) tenemos la posibilidad de llamarlo desde el fichero /etc/rc.local

Cualquier comando que coloquemos o script al que llamemos en dicho fichero será ejecutado al final del arranque, es decir, cuando todos los scripts que tenemos en el runlevel correspondiente hayan sido ejecutados.

Por defecto el fichero únicamente muestra el siguiente comentario:

# cat /etc/rc.local 

#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

A partir de aquí simplemente habría que añadir los comandos que quisieramos ejecutar, es básicamente un script en bash:

#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

# Ejemplo de creación de fichero en el arranque
touch ~/test.txt
# Asignamos permisos a un fichero
chmod 0644 ~/test.txt
# Ejecutamos un script
/bin/sh ~/test.sh

Unix: diferencias entre los comandos cat, more y less


Los comandos cat, more y less permiten mostrar el contenido de ficheros de texto desde la línea de comandos en sistemas Unix, las principales características y diferencias de cada uno de ellos son las siguientes:

Comando Unix CAT

El comando ‘cat’ imprimirá por pantalla el contenido del fichero sin ningún tipo de paginación ni posibilidad de modificarlo. Básicamente concatena archivos o la salida estándar en la salida estándar. Podemos pasarle parámetros como:

  -A, --show-all           lo mismo que -vET
  -b, --number-nonblank    numera las líneas que no están vacías
  -e                       lo mismo que -vE
  -E, --show-ends          muestra un $ al final de cada línea
  -n, --number             numera todas las líneas
  -s, --squeeze-blank      nunca muestra más de una línea vacía,
  -t                       equivalente a -vT
  -T, --show-tabs          muestra los caracteres de tabulación como ^I
  -u                       (sin efecto)
  -v, --show-nonprinting   utiliza la notación ^ y M-, salvo para LFD y TAB
      --help     muestra esta ayuda y finaliza
      --version  informa de la versión y finaliza

Mostrar el contenido de un fichero:

$ cat fichero

Concatenar dos ficheros de texto en uno:

$ cat fichero1 fichero2 > fichero3

Comando Unix MORE

Al igual que ‘cat’, ‘more’ permite visualizar por pantalla el contenido de un fichero de texto, con la diferencia con el anterior de que ‘more’ pagina los resultados. Primero mostrará por pantalla todo lo que se pueda visualizar sin hacer scroll y después, pulsando la tecla espacio avanzará de igual modo por el fichero.

$ more fichero
texto de ejemplo
texto de ejemplo
texto de ejemplo
--Más--(23%)

También podemos especificarle el número de líneas a mostrar y otros parámetros:

uso: more [-dflpcsu] [+númlíneas | +/patrón] nombre1 nombre2 ...

Comando Unix LESS

El comando ‘less’ es el más completo de los tres, pues puede hacer todo lo que hace ‘more’ añadiendo mayor capacidad de navegación por el fichero (avanzar y retroceder) además de que sus comandos están basados en el editor ‘vi’, del cual se diferencia en que no tiene que leer todo el contenido del fichero antes de ser abierto. Tiene una gran cantidad de opciones y parámetros, como siempre lo recomendable:

$ less --help