UNIX

Cheat sheets

Comandos útiles

Alias SSH

Para asimilar un identificador a una pareja user@host, editar el fichero ~/.ssh/config y añadir un bloque como el siguiente (fuente):

Host example
  HostName example.com
  User exampleuser

Tunel de un puerto remoto por SSH

(Fuente) Para conducir el tráfico hasta un host:puerto remoto canalizándolo por un tunel seguro, se puede utilizar el comando ssh. Por ejemplo, vamos a tunelizar una conexión contra el puerto telnet de la máquina remota telnet.example.com por medio del usuario ssh-user para tenerlo disponible en el puerto 2000 local de nuestra máquina:

ssh -f ssh-user@telnet.example.com -L 2000:telnet.example.com:23 -N

A partir de ahora podremos conectarnos al telnet conectando con localhost:2000.

Uso básico de screen

En esta cheat sheet se reúnen bastantes comandos útiles. A continuación indico el uso típico:

  1. Arrancamos una sesión:

     shell ~$ screen
    
  2. Aparece una splashscreen que cerramos pulsando enter y ya podemos trabajar
  3. Lanzamos un comando:

     screenshell_1 ~$ top
    
  4. Para cerrar la sesión screen que acabamos de abrir, tan sólo hay que lanzar el comando exit (en este ejemplo, parando previamente el comando top que habíamos lanzado). Ahora sin embargo pretendemos dejarla abierta, con el comando top en ejecución, para volver a ella más adelante. Es lo que se llama un detach (sirve para recordar la tecla que se pulsa al final de la combinación de teclas). Para ello pulsamos la combinación de teclas:

     "Ctrl-a" "d"
    
  5. Habremos vuelto a nuestro bash inicial. Cuando en cualquier momento queramos recuperar la sesión screen, lo haremos con el comando:

     shell ~$ screen -r
    
  6. Ahora estaremos viendo de nuevo la salida del comando top que habíamos dejado arrancado dentro de la sesión screen. Volvemos a abandonar la sesión sin cerrarla procediendo por tanto como en el paso 4:

     "Ctrl-a" "d"
    
  7. De vuelta al bash inicial, vamos a abrir una segunda sesión screen para ver cómo podemos movernos a una u a otra. Arrancamos la sesión como hicimos con la primera:

     shell ~$ screen
    
  8. Cerramos la splashscreen y ejecutamos algún comando para reconocer la sesión cuando volvamos a ella. Por ejemplo:

     screenshell_2 ~$ ping 8.8.8.8
    
  9. Abandonamos la sesión dejándola abierta:

     "Ctrl-a" "d"
    
  10. De vuelta al bash inicial ahora tenemos dos sesiones screen lanzadas. Ahora el comando screen -r no se puede lanzar sin especificar el identificador de la sesión tras la opción -r. Obtenemos la lista de sesiones con el siguiente comando:

    shell ~$ screen -list
    There are screens on:
        12629.pts-7.eduardo-HP-Folio-13	(04/04/15 13:55:03)	(Detached)
        12609.pts-7.eduardo-HP-Folio-13	(04/04/15 13:54:51)	(Detached)
    2 Sockets in /var/run/screen/S-edumoreno.
    
  11. Ahora, para recuperar una de ella, por ejemplo la más vieja que contenía lanzado el comando top incorporaremos el identificador de la sesión tras la opción -r:

    shell ~$ screen -r 12609.pts-7.eduardo-HP-Folio-13
    
  12. Como se comentaba en el punto 4, para cerrar las sesiones simplemente saldremos con exit, aunque también, y sobre todo en caso de que la sesión se quedara bloqueada con algún comando que no se pudiera cerrar, se puede matar la sesión con la siguiente combinación de teclas:

    "Ctrl-a" "k"
    

Búqueda de ficheros que contienen una cadena

#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for file in `find .`
do
fgrep "[cadena a buscar]" $file > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo $file
fi
done
IFS=$SAVEIFS

En realidad el script anterior hace lo mismo que el simple comando siguiente:

$ fgrep -rl "[cadena a buscar]" .

Ajustes de permisos a ficheros y directorios por separado

$ #Para los ficheros:
$ find . ! -type d -exec chmod 664 {} \;
$ #Para los directorios:
$ find . -type d -exec chmod 775 {} \;

Renombrado de ficheros de mayúsculas a minúsculas

(Fuente)

#!/bin/sh
for f in *; do
g=`expr "xxx$f" : 'xxx\(.*\)' | tr '[A-Z]' '[a-z]'`
mv "$f" "$g"
done

Redirección de salidas

Para redirigir ambas salidas de un programa (estandar y error) hacer lo siguiente:

$ COMANDO > FICHERO_O_DISPOSITIVO 2>&1

En esta página se documenta con más detalle este tema.

Ejecución remota de aplicaciones XWindow

  1. Abrir el servidor X (Cygwin)
  2. Iniciar sesión remota: ssh -X [usuario]@[máquina]
  3. Ejecutar la aplicación

MySQL

Ficheros de configuración importantes

Solución al problema de los alias (alternatives) de Java6 en Ubuntu

Los paquetes de Java 6 (1.6) en Ubuntu tienen problemas a la hora de ajustar los alias en /etc/alternatives cuando antes ha estado instalada otra versión (1.5 por ejemplo). Se puede forzar la generación de los alias mediante las siguientes ordenes:

$ update-java-alternatives --list
$ sudo update-java-alternatives --set [elegir el identificador de la lista que muestra el comando anterior]

Bits SUID, SGID y sticky

Manual de LuCAS

Autentificación automática por SSH

Conseguiremos que la autentificación del cliente se haga por medio de una pareja de claves privada/pública en lugar de con identificador de usuario/password. Primero generamos la pareja de claves pública-privada ejecutando en el cliente ssh-keygen:

$ ssh-keygen  -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx user@machine

Las claves se almacenan por defecto en ~/.ssh/, quedando el directorio así:

$ ls -l
total 12
-rw-------  1 user user  883 2005-08-13 14:16 id_rsa
-rw-r--r--  1 user user  223 2005-08-13 14:16 id_rsa.pub
-rw-r--r--  1 user user 1344 2005-08-04 02:14 known_hosts

Los ficheros id_rsa e id_rsa.pub contienen respectivamente las claves privada y pública. El fichero known_hosts contiene la lista de las claves públicas de las máquinas reconocidas.

Ahora se debe copiar la clave pública al servidor, al fichero ~/.ssh/authorized_keys. Para ello se utiliza el comando ssh-copy-id:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@machine1
$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@machine2

ssh-copy-id es un script que se conecta a la máquina y copia el archivo (indicado por la opción -i) en ~/.ssh/authorized_keys, y ajusta los permisos a los valores adecuados.

Si no se dispone del programa ssh-copy-id se puede realizar una copia manual a la máquina remota del fichero conteniendo la clave pública (por ejemplo usando scp o sftp) y añadir su contenido al fichero ~/.ssh/authorized_keys.

Ahora la conexión debería funcionar sin necesidad de introducir la clave. Si no es así es posible que sea un problema de permisos en los ficheros. Los permisos correctos deben ser similares a estos:

$ chmod go-w ~ ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys

La conexión SSH se realizará indicando el fichero con la clave privada como argumento de la siguiente forma:

$ ssh -i ~/.ssh/id_rsa user@machine

(Si el nombre del fichero con la clave privada es precisamente el del ejemplo, es decir id_rsa, creo que no es necesario indicarlo con la opción -i).

Configuración de Firefox para ejecución de applets Java

(Fuente)

$ cd `<directorio de instalación de Mozilla>`/plugins  # Normalmente /usr/lib/firefox/plugins

o

$ cd `<home del usuario>`/.mozilla/plugins
$ ln -s `<directorio de instalación del JRE>`/plugin/i386/ns7/libjavaplugin_oji.so

Organización de menús cuando se mezclan aplicaciones KDE y Gnome

GNU/Linux nos permite tener varios sistemas de escritorio diferentes instalados y funcionando, pero inevitablemente nos encontramos con una mezcla de opciones y programas de cada entorno en los menús principales. Existen aplicaciones precisamente para limpiar automáticamente las entradas del menú que no corresponden a tu sistema de escritorio habitual, y dejarlas apartadas y ordenadas de alguna manera. Con Gnome y KDE instalados a la vez, hay dos programas para aquellos Gnomeros que han querido probar KDE y para los KDEeros que han querido probar Gnome.

Error “error while loading shared libraries: …”

Runtime error. The linker hasn’t found your libraries. Either they are not installed properly or the linker doesn’t know where they are (most probably in /usr/local/lib). To get your linker to update its list of libraries type:

$ ldconfig /usr/local/lib

or as a temporary measure:

$ export LD_LIBRARY_PATH="/usr/local/lib"

Compartir ficheros con Samba

Aparte de instalar y configurar Samba (fichero /etc/samba/smb.conf) hay que dar de alta los usuarios UNIX que se usarán a través de Samba y asignarles un password para el acceso por el mismo. Esto se hace con el comando:

$ sudo smbpasswd -a usuario

Migración masiva de usuarios

(Fuente)

Para los casos en los que sea necesario replicar los usuarios de un servidor Linux a otro o en los que se vaya a migrar a un servidor con más recursos, el siguiente procedimiento puede ser de utilidad.

Los escenarios son varios, desde los servidores que ejecutan algún tipo de base de datos, los que tienen ciertas aplicaciones, los que alojan páginas Web, etcétera. Para fines de la demostración pensaremos que el servidor está dedicado como servidor de archivos, mismos que se almacenan en el home de cada uno de los usuarios. NOTA: El presente procedimiento da por hecho que se hayan realizado las configuraciones necesarias en el nuevo servidor.

Primero, lo que debe respaldarse es la lista de usuarios con su respectiva contraseña. El archivo /etc/passwd contiene las cuentas de los usuarios en el sistema bajo el siguiente formato de ejemplo:

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/
nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
nitsuga:x:500:500::/home/nitsuga:/bin/bash
nitsuga2:x:501:501::/home/nitsuga2:/bin/bash
nitsuga3:x:502:502::/home/nitsuga3:/bin/bash

Como se observa, el segundo campo respectivo al hash de la contraseña no se muestra. La contraseña se encuentra en el archivo /etc/shadow

root:$1$/7zmwgAa$Jd5ja7nsC4nTm
O3s0.Z1j1:13445:0:99999:7:::
bin:*:13445:0:99999:7:::
daemon:*:13445:0:99999:7:::
adm:*:13445:0:99999:7:::
nitsuga:$1$QwPqN0Vc$dn9OIyE3HQUh5W4Yh/.aQ.:13498:2:1:1:::
nitsuga2:$1$635CQht0$rFIbilzKqfc1zStqeOwlk/:13496:2:45:7:::
nitsuga3:$1$635CQht0$rFIbilzKqfc1zStqeOwlk/:13496:2:45:7:::

Se procederá a unir el usuario con su contraseña utilizando el comando pwunconv para “desactivar” el shadow, quedando así las contraseñas en el archivo passwd.

root:$1$/7zmwgAa$Jd5ja7nsC4n
TmO3s0.Z1j1:0:0:root:/root:/bin/bash
bin:*:1:1:bin:/bin:/sbin/nologin
daemon:*:2:2:daemon:/sbin:/sbin/
nologin
adm:*:3:4:adm:/var/adm:/sbin/nologin
nitsuga:$1$QwPqN0Vc$dn9OIyE3HQUh5W4Yh/.aQ.:500:500::/home/
nitsuga:/bin/bash
nitsuga2:$1$635CQht0$rFIbilzKqfc1zStqeOwlk/:501:501::/home/nitsuga2:/bin/bash
nitsuga3:$1$635CQht0$rFIbilzKqfc1zStqeOwlk/:502:502::/home/nitsuga3:/bin/bash

Depuración de /etc/passwd

Se copiará el archivo /etc/passwd a uno de trabajo /etc/passwd.migracion. Ahora se editará el archivo y se quitarán todos los usuarios propios del sistema (root, usuarios de demonios, etcétera) dejando sólo los usuarios que van a ser autenticados.

nitsuga:$1$QwPqN0Vc$dn9OIyE3HQUh5W4Yh/.aQ.:500:500::/home/nitsuga:/bin/bash
nitsuga2:$1$635CQht0$rFIbilzKqfc1zStqeOwlk/:501:501::/home/nitsuga2:/bin/bash
nitsuga3:$1$635CQht0$rFIbilzKqfc1zStqeOwlk/:502:502::/home/nitsuga2:/bin/bash

También se copiará el archivo /etc/group a /etc/group.migracion

root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm
adm:x:4:root,adm,daemon
nitsuga:x:500:
nitsuga2:x:501:
nitsuga3:x:502:
nitsuga8:x:507:

Y se editará para dejar sólo los grupos de los usuarios:

nitsuga:x:500:
nitsuga2:x:501:
nitsuga3:x:502:

Ahora se respaldará el home de los usuarios, suponiendo que se encuentra bajo el directorio/home, se hará lo siguiente desde raíz (/):

[root@localhost /]# tar -cpzvf home.tgz home/

En el que las banderas:

Ahora bien, se realizará la transferencia de los archivos home.tgz, passwd.migracion y group.migracion al nuevo servidor:

[root@localhost /]# scp /home.tgz root@nuevoservidor

[root@localhost /]# scp /etc/passwd.migracion root@nuevoservidor

[root@localhost /]# scp /etc/group.migracion root@nuevoservidor

Una vez en el nuevo servidor se deberá verificar que no se repitan tanto los UID como los GID entre los dos servidores. Se realizará:

[root@localhost /]# cp –p home.tgz / ; tar –zxvf home.tgz

[root@localhost /]# cp –p passwd.migracion /etc ; pwunconv ; cat passwd.migracion >> passwd; pwconv

[root@localhost /]# cp –p group.migracion /etc ; cat group.migracion >> group

Eliminar petición password en sudo

Es necesario reconfigurar el fichero /etc/sudoers para que no se solicite el password del usuario a la hora de hacer sudo, dado que necesitamos que se haga sudo desde un proceso que no tendrá interacción con el usuario. Para conseguir esto hay que hacer dos cosas:

  1. Incorporar el usuario que nos interesa al grupo sudo del sistema
  2. Situar al final del fichero de configuración /etc/sudoers lo siguiente:
%sudo ALL=NOPASSWD: ALL

Hay que fijarse que la linea anterior normalmente ya aparece en el fichero pero comentada con una almohadilla. Se puede aprovechar la linea quitando el carácter almohadilla del principio, pero hay que tener en cuenta que no es suficiente con eso. Hay que mover la linea al final del fichero ya que las lineas siguientes pueden sobreescribir su efecto.

Importante: La edición del fichero /etc/sudoers sólo se puede hacer con el comando visudo. Este comando hay que lanzarlo con sudo a su vez, por lo que se hará de la siguiente forma:

$ sudo visudo

Proxy HTTP en consola

Setting up proxy at Firefox do not have effects at console, which means your wget, ssh, apt-get, yum etc do not access through the proxy you set at Firfox browser. To setup http proxy at console, you can do as bellow, assume the proxy IP is 219.93.2.113 and port 3128:

$ export http_proxy='http://219.93.2.113:3128/'

Remember, you have to specified http://, and to know more about export, check out HERE. To clear your http proxy and use back yours, do this:

$ export http_proxy=''

Convertir nombres de ficheros de ISO a UTF-8

Al migrar una web, o al copiar un sistema de archivos, te puedes encontrar con nombres de ficheros en otras codificaciones de caracteres. Mediante el siguiente comando transformaríamos los nombres de ficheros desde ISO-8869-1 a UTF-8:

$ convmv -r -f ISO-8859-1 -t UTF-8  --notest *

Backup de un FileSystem

Backup:

$ dd if=/dev/hdx | gzip > /path/to/image.gz

Restauración:

$ gzip -dc /path/to/image.gz | dd of=/dev/hdx

Montar un fichero .img

(Fuente). Primero hay que averiguar el offset de la partición que queremos montar:

fdisk -l /ruta/fichero.img

Esto nos mostrará el tamaño del bloque y el bloque de comienzo de la partición. Por ejemplo:

edumoreno@eduardo-HP-Folio-13:~/Descargas$ fdisk -l RetroPie.img
Disk RetroPie.img: 3,7 GiB, 3965190144 bytes, 7744512 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb847d94e

Disposit.     Inicio  Start   Final Sectores  Size Id Tipo
RetroPie.img1 *        8192  124927   116736   57M  e W95 FAT16 (LBA)
RetroPie.img2        124928 7744511  7619584  3,6G 83 Linux

El offset se calculará multiplicando el bloque de comienzo por el tamaño de bloque. En el ejemplo, para la segunda partición:

offset = 124928 * 512 = 63963136

Por tanto el comando para montar será:

sudo mount -o loop,offset=63963136 RetroPie.img /mnt/tmp

Manipulación de PDFs

División en múltiples ficheros (uno por página):

$ pdftk largepdfile.pdf burst

Fusión de varios ficheros en uno:

$ pdftk *.pdf cat output onelargepdfile.pdf

Obtener hash MD5 de una cadena

$ echo -n "<cadena>"|md5sum

System + MySQL backup script

#!/bin/bash
# System + MySQL backup script
# Full backup day - Sun (rest of the day do incremental backup)
# Copyright (c) 2005-2006 nixCraft `<http://www.cyberciti.biz/fb/>`
# This script is licensed under GNU GPL version 2.0 or above
# Automatically generated by http://bash.cyberciti.biz/backup/wizard-ftp-script.php
# ---------------------------------------------------------------------

### System Setup ###
DIRS="/var/spool/sms /var/log/smstools /root"
BACKUP=/tmp/backup.$$
NOW=$(date +"%d-%m-%Y")
INCFILE="/var/tar-inc-backup.dat"
DAY=$(date +"%a")
# echo $DAY >> /root/dates
FULLBACKUP="Sun"

### MySQL Setup ###
MUSER="mysqluser"
MPASS="mysqlpwd"
MHOST="localhost"
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"
GZIP="$(which gzip)"

### FTP server Setup ###
FTPD="//incremental"
FTPU="ftpuser"
FTPP="ftppwd"
FTPS="ftphost"
NCFTP="$(which ncftpput)"

### Other stuff ###
EMAILID="user@domain.com"

### Start Backup for file system ###
[ ! -d $BACKUP ] && mkdir -p $BACKUP || :

### See if we want to make a full backup ###
if [ "$DAY" == "$FULLBACKUP" ]; then
  FTPD="//full"
  FILE="fs-full-$NOW.tar.gz"
  tar -zcvf $BACKUP/$FILE $DIRS
else
  i=$(date +"%Hh%Mm%Ss")
  FILE="fs-i-$NOW-$i.tar.gz"
  tar -g $INCFILE -zcvf $BACKUP/$FILE $DIRS
fi

### Start MySQL Backup ###
# Get all databases name
DBS="$($MYSQL -u $MUSER -h $MHOST -p$MPASS -Bse 'show databases')"
for db in $DBS
do
 FILE=$BACKUP/mysql-$db.$NOW-$(date +"%T").gz
 $MYSQLDUMP -u $MUSER -h $MHOST -p$MPASS $db | $GZIP -9 > $FILE
done

### Dump backup using FTP ###
#Start FTP backup using ncftp
ncftp -u"$FTPU" -p"$FTPP" $FTPS<<EOF
mkdir $FTPD
mkdir $FTPD/$NOW
cd $FTPD/$NOW
lcd $BACKUP
mput *
quit
EOF

### Find out if ftp backup failed or not ###
if [ "$?" == "0" ]; then
 rm -f $BACKUP/*
else
 T=/tmp/backup.fail
 echo "Date: $(date)">$T
 echo "Hostname: $(hostname)" >>$T
 echo "Backup failed" >>$T
 mail  -s "BACKUP FAILED" "$EMAILID" <$T
 rm -f $T
fi