Archivo de la categoría: Bash Scripting

Chequear la batería del portátil desde línea de comandos

Aunque todas las distribuciones actuales tienen entornos gráficos con aplicaciones que controlan en todo momento el estado de la batería del portátil y nos muestran avisos cuando queda poca batería, si usáis un entorno más liviano (tipo openbox) y/o queréis comprobarlo por vuestra cuenta, aquí os indico cómo podéis hacerlo.

Para chequear el nivel de la batería podéis usar este script:

REMAINING=`cat /proc/acpi/battery/BAT0/state | awk '/remaining/ {print $3}'`
TOTAL=`cat /proc/acpi/battery/BAT0/state | awk '/present rate/ {print $3}'`
echo "$REMAINING * 100 / $TOTAL" |bc

Y con este otro script podéis controlar también el adaptador para ver cuándo está online y cuándo offline. Este script hace uso del anterior y así, si está sin cable de corriente y la batería baja de un nivel que especificamos se apaga el equipo (es el comando «h» que se ve ahí). El script sería éste:

BAT=`/usr/local/bin/show_bat.sh`
MIN_BAT=10
AC_ADAPTER=`cat /proc/acpi/ac_adapter/ADP0/state | awk '{print $2}'`
if [ $AC_ADAPTER = "off-line" ]; then
        if [ $BAT -lt $MIN_BAT ]; then
                if [ $BAT -lt 3 ]; then
                        echo "El equipo se quedón sin batería" > $HOME/LEEME.txt
                        /usr/local/bin/h
                else
                        zenity --warning --text="Batería baja" --display=:0.0
                fi
        fi
fi
Espero que os resulte útil.

Paralelizando tareas en la línea de comandos

Los procesadores actuales, como bien sabéis, tienen varios cores. Esto significa que en teoría pueden ejecutar varias cosas en paralelo. Así, si tienen 4 cores, podrían ejecutar 4 procesos al mismo tiempo.

El problema es que normalmente las aplicaciones no están diseñadas para sacar todo el rendimiento a nuestros procesadores con todos sus cores, de forma que a veces está trabajando un core mientras los otros apenas hacen nada.

En GNU/Linux tenemos un comando (desarrollado por la propia fundación GNU) que permite ejecutar varias tareas en paralelo. Se llama parallelSe encuentra disponible para todas las distros más importantes directamente desde los repositorios.

El ejemplo más sencillo es el de comprimir varios archivos. Veamos cómo lo haríamos normalmente:

gzip *

Vamos a ejecutar este comando con el comando time delante para que al finalizar nos diga cuánto ha tardado (así podremos luego comparar más fácilmente). Además, le pondremos la opción -1, que hará que comprima más y tardará un poquito más:

[ user ] [~/a] > time gzip -1 * 
gzip -1 * 10,80s user 0,40s system 96% cpu 11,622 total

En mi PC obtengo un uso de sistema del 96% y 11,6 segundos de tiempo en ejecutarlo.

Se obtiene un 96% de uso de CPU porque para el comando time, 100% es el máximo uso de un core. Como tenemos 4 cores (en el caso de mi CPU), el total sería 400%, por lo que se están desperdiciando aproximadamente(*) 3/4 partes de procesador.

Para llevar a cabo esta tarea con parallel tendríamos que hacerlo así:

[ user ] [~/a] > ls | time parallel gzip -1
[... información sobre parallel ...]

parallel gzip -1 10,93s user 0,53s system 317% cpu 3,605 total

Lo que da como resultado un 317% de uso de CPU y un total de 3,6 segundos de ejecución.

El hecho de que se obtenga 317% de uso de CPU se explica por lo que decíamos antes. time tiene en cuenta 100% por cada core. Por tanto, aquí se está aprovechando mucho mejor la CPU. En nuestro ejemplo hemos comprimido sólo 4 archivos de 66 megas cada uno. Si comprimiéramos más y durara más el proceso, poco a poco el % de uso aumentaría aprovechando aún más todos los cores, es decir, cuanto más dure el proceso más partido sacará.

Si queréis comprobar de una manera más visual qué porcentaje de cada core se está usando en cada momento podéis usar la utilidad htop.

Parallel tiene muchas más opciones. Podéis incluso usarlo para usar no sólo los cores de un equipo, sino las cpus de varios equipos en red. Un parámetro interesante es el que permite especificar qué capacidad de cpu queremos usar para la tarea. Es el parámetro -j. Siguiendo con el ejemplo anterior, podríamos poner esto:

[ user ] [~/a] > ls | time parallel -j 50% gzip -1
[ ... información sobre parallel ... ]

parallel -j 50% gzip -1 10,84s user 0,46s system 188% cpu 6,005 total

Con esto indicamos que se use la mitad de la CPU. En este caso el resultado ha sido 164% de ocupación de CPU y unos 6 segundos, es decir, como usamos la mitad, tardamos el doble -aproximadamente- que antes.

Aquí tenéis el tutorial de GNU por si le queréis sacar todo el pringue a este comando.

Más info aquí.

(*) Decimos aproximadamente porque el sistema operativo está ejecutando más cosas aparte de nuestro comando gzip.

Ejecutando comandos como root dentro de un script

A veces, dentro de un script, se necesita ejecutar un comando como superusuario. Una posibilidad es usando el comando sudo, por ejemplo:

sudo ls /root

Si lo ejecutáis sin el sudo (es decir, como vuestro usuario normal del sistema) no os va a dejar porque no tenéis permiso para ver el contenido del directorio /root. Si lo ejecutáis con sudo sí que podréis. Eso sí, os pide vuestro password -para comprobar que no es cualquiera que se ha sentado un momento en vuestro PC y os quiere fastidiar el equipo-.

Para que esto funcione, vuestro usuario tiene que tener permisos de sudo. Esto se hace automáticamente para el usuario que se define en la instalación de sistemas operativos como Ubuntu y derivados.

En cualquier caso, aquí tenéis más información sobre sudo y cómo configurarlo para un usuario.

Así, si en un script necesitáis ejecutar algo con permisos de root podéis usar sudo. Ahora bien, tended en cuenta que os va a pedir el password, por lo que no podéis lanzarlo y marcharos, ya que se quedará esperando que pongáis el password de vuestro usuario. Imaginad que lanzáis un script que hace mogollón de cosas -en las que tarda un tiempo- y luego, al rato, en uno de los comandos que hay en el script, usa sudo para ejecutarse como root. Tendréis que estar sentados todo el rato hasta que os la pida.

Para salvar esto podéis usar la opción -S, que permite que se le pase el password en la línea de comandos. Se usaría así:

echo PASSWORD | sudo -S ls /root

Evidentemente, el comando que ejecutaréis en el sudo, normalmente será algo más complicado que éste ;-P (y más útil).

Por tanto, con sudo -S podemos, bien pedir el password al principio del script (con read) o bien cogerlo de algún sitio. En este último caso hay que tener presente que el password estaría almacenado en claro en ese «sitio», por lo que conviene que tenga permisos de lectura sólo para el propio usuairo (algo como «chmod 600 fichero«, por ejemplo).

Espero que os resulte útil.