La consola de Unix

Curso FLOQQ

https://slid.es/alexfernandez/unix-floqq

Quién soy



Ingeniero de software con 15+ años de experiencia
Desarrollador senior en MediaSmart Mobile
Cacharreador impenitente desde siempre
@pinchito, alexfernandez, alejandrofer

Requisitos


Tener curiosidad


Saber lo que es un ordenador


Acceso a una consola Unix:

Ubuntu, otro Linux, Mac OS X

Servidor en la nube, Cygwin en Windows


No asustarse por ver una pantalla en negro sobre blanco

Vamos a ver


50+ comandos


Teoría y práctica


Expresiones regulares


Scripts para automatización


30+ ejercicios (con soluciones)

Sesiones

  1. Hola, mundo (Bash)
  2. Introducción a Unix
  3. Ficheros
  4. Texto
  5. Procesos
  6. Enlazando comandos
  7. Comandos y opciones
  8. Buscando comandos
  9. Expresiones regulares
  10. Seguridad
  11. Comandos avanzados
  12. Algunos trucos
  13. Scripts de bash

¡Hola, Mundo!


Soy Bash


Quiero conocerte


Me llaman consola o terminal


¡Sé un montón de trucos!

Mi Primer Comando


echo <cadena>

Pinta una línea de texto


$ echo hola, mundo
hola, mundo

Pinta la cadena "hola, mundo"


$ echo "hola, mundo"
hola, mundo
Igual, con comillas

Convenciones


<variable>

Una variable que se le pasa a un comando


$ 

Prompt (pie): espera entrada del usuario

Odio, odio la casilla parpadeante


salida

Salida de un comando (sin pie)

Ejercicio 1: eco eco


$ echo hola; mundo
hola
bash: mundo: no se encontró la orden
NO funciona

echo no reconoce todos los caracteres

¿Cuáles son los caracteres de control?

Prueba todos los que se te ocurran

Prueba con comillas:

$ echo "hola; mundo"
"hola; mundo"

Ejercicio 2: instala Homebrew


Homebrew es un gestor de paquetes para Mac OS X


Se instala corriendo este comando:

$ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

A partir de ahí se instala cualquier paquete fácilmente:

$ brew install wget

Ejercicio 3: Instala CygWin


Si estás en Windows, puedes instalar CygWin


En 32 bits, baja y corre setup-x86.exe


En 64 bits: setup-x86_64.exe



Introducción a Unix


La consola es tu amiga

Breve historia de Unix


Creado por Thompson y Ritchie (~1972)


Basado en Multics
Bell Labs → universidades → empresas → amateurs

Fuente: Wikipedia

¿Dónde está hoy Unix?


¿Perdido en los datacenters viejunos?

¡Está por todas partes!

~8% de ordenadores y portátiles (Mac OS X, Linux)
62~82% de servidores (Linux, BSD)
60~90% de móviles (Android + iOS)
~92% de tablets (Android + iOS)
~99% de superordenadores (Linux)

Fuente: Wikipedia

Filosofía de Unix


Haz una única cosa, y hazla bien


Programas que trabajan juntos


Usa texto: la interfaz universal


Todo son ficheros


Variantes

Fuente: United States Naval Academy

Piezas de un Unix


Herramientas de desarrollo (compilador)


Kernel (núcleo)

Librería de C


Consola (shell)


Comandos

Ejemplo: GNU/Linux


Compilador: GCC (GNU Compiler Collection)


Kernel: Linux

Librería de C: Glibc (GNU C Library)


Consola: GNU Bash


Comandos: GNU CoreUtils

The GNU project

Creado en 1984 por Richard Stallman

Filosofía de software libre

Permite distribución, estudio, y modificación

¿Qué es Bash?


La shell de GNU/Linux (y Mac OS X)


Versión mejorada de Bourne Shell

con funcionalidad adicional


Chiste: Bourne-Again SHell

(Como born-again Christian: cristiano renacido)


¿qué es una shell?


Una interfaz de usuario


En Unix, un intérprete de comandos


Cada comando es una orden directa

que puede mostrar una salida

o no


Historia de bash


Bourne Shell: creada 1977 en por Steve Bourne


Bash: creada en 1989 por Brian Fox
para el proyecto GNU
Adoptada por Mac OS X Panther en 2003

Nos gustan los colores


En serio, nos encantan

Ejercicio 1: instala git

Debian

$ su
Contraseña:
# apt-get install git 

Ubuntu

$ sudo apt-get install git 

RedHat / Fedora

# yum install git 

Mac OS

$ brew install git

Ejercicio 2: baja el proyecto


$ git clone 

Baja un repositorio, normalmente de código


$ git clone https://github.com/alexfernandez/floqq-unix
Cloning into 'floqq-unix'...
remote: Counting objects: 15, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 15 (delta 3), reused 10 (delta 2)
Unpacking objects: 100% (15/15), done.
Checking connectivity... done. 
Baja el repositorio floqq-unix

Ejercicio 3: baja el zip


Si por cualquier motivo no tienes git...


$ wget http://alexfernandez.github.io/floqq-unix.zip
[...]
$ unzip floqq-unix.zip
[...]
$ cd floqq-unix 


... Y si todo falla, hazlo con las herramientas que conozcas

Ficheros


Todo son ficheros

file


file <fichero>

Muestra el tipo de un fichero

(mirando el contenido del fichero, no la extensión)


$ file floqq-unix
floqq-unix/: directory 

Muestra que floqq-unix es un directorio 


pwd


pwd 

Muestra el directorio de trabajo (directorio actual)


$ pwd 
/home/usuario

Se empieza siempre en el directorio home


Ficheros en Unix


/ 

Se usa para separar directorios (carpetas)

Por sí solo, representa el directorio raíz (root)

/home/usuario/floqq-unix 

El directorio raíz contiene uno llamado home

home contiene usuario

y así sucesivamente:

home → usuario → floqq-unix

cd


cd <directorio>

Cambia al Directorio especificado


$ cd floqq-unix

Cambia al directorio del proyecto


$ cd .. 

Cambia al directorio padre

ls


ls 

LiSta el contenido del directorio actual

ls <directorio>

Lista el directorio pedido

ls <fichero1> <fichero2> ...

Lista los ficheros pedidos


$ ls
ejemplo.txt  LICENSE  página.html  pic  README.md  soluciones.md 

Lista el directorio de trabajo

Estructura de directorios


  • /bin: binarios de sistema
  • /boot: arranque
  • /dev: dispositivos
  • /etc: configuración
  • /home: directorios personales
  • /lib: librerías de sistema
  • /root: home del usuario root
  • /sbin: binarios del superusuario (root)
  • /usr: programas del usuario (todos en realidad)
  • /var: contenido variable: logs, páginas web
  • ...

tree

tree <directorio>

Muestra el contenido del directorio en árbol (TREE)


$ tree /etc
/etc
├── a2ps.cfg
├── a2ps-site.cfg
├── acpi
│   ├── events
│   │   └── powerbtn-acpi-support
│   └── powerbtn-acpi-support.sh
...
└── zlibc.conf

299 directories, 2099 files 

Muestra el contenido de /etc

cat


cat <fichero1> <fichero2>

ConCATena ficheros


$ cat ejemplo.txt página.html
<contenido de ejemplo.txt>
<contenido de página.html>

Muestra el contenido de ambos ficheros concatenado

touch


touch <fichero>

Toca (TOUCH) un fichero

  • Si no existe, lo crea.
  • Si existe, pone fecha de modificación actual.


$ touch novedad 

Crea un fichero vacío que se llama novedad

cp


cp <original> <nuevo>

CoPia el fichero original a uno nuevo


$ cp ejemplo.txt copia.txt 

Crea una copia de ejemplo.txt

mv


mv <antiguo> <nuevo>

MueVe el fichero antiguo al nuevo

mv <fichero1> <fichero2>... <destino>

Mueve varios ficheros a un directorio


En Unix no hay renombrado; mv hace las funciones


$ mv ejemplo.txt pic/movido.txt 

Mueve al directorio pic y renombra a la vez

Globbing


Patrones:

  • "*": cualquier cosa
  • "?": un carácter


$ mv *.md pic/ 

Mueve todos los archivos con extensión .jpg a pic

$ mv LICE?SE pic/ 

Mueve LICENSE, LICEPSE, LICE1SE... a pic

rm


rm <fichero>

Elimina (ReMove) un fichero


$ rm novedad 

Borra el fichero creado antes


$ rm noexiste
rm: no se puede borrar «noexiste»: No existe el fichero o el directorio 

Avisa de que no se puede borrar

mkdir


mkdir <directorio>

Crea un directorio


$ mkdir nuevodir 

Crea el directorio vacío

rmdir


rmdir <directorio>

Elimina un directorio


$ rmdir nuevodir

Elimina el directorio que creamos antes

(No se puede eliminar un directorio si no está vacío)

ln


ln -s <origen> <destino>  

Crea un enlace simbólico de un fichero a una ruta


$ ln -s ejemplo.txt pic/defuera.txt
$ ls pic
bash.png  defuera.txt
$ cd pic
$ ln -s ../ejemplo.txt dedentro.txt
$ ls
bash.png  dedentro.txt  defuera.txt

Crea un enlace simbólico de ejemplo.txt

Desde fuera no funciona


df


df -h 

Muestra el espacio libre en disco (Disk Free) para Humanos


$ df -h
S.ficheros     Tamaño Usados  Disp Uso% Montado en
/dev/sda1        113G    96G   12G  90% /
udev              10M      0   10M   0% /dev
tmpfs            388M   460K  388M   1% /run
tmpfs            5,0M      0  5,0M   0% /run/lock
tmpfs            1,8G   6,4M  1,8G   1% /run/shm 

Hay 96 GB usados y 12 GB disponibles en mi disco duro

Ejercicio 1: crea muchos


Crea varios ficheros vacíos en el directorio de trabajo:

prueba1.txt, prueba2.png, prueba3.fake


Verifica si file asigna tipos diferentes a los tres ficheros


Bórralos con un solo comando

Ejercicio 2: directorio no vacío


Crea un directorio ejemplo


Crea varios ficheros dentro:

prueba1.txt, prueba2.png


Intenta borrar el directorio


¿Qué hay que hacer para borrarlo?

Ejercicio 3: de vuelta


Repasa el capítulo ejecutando todos los comandos

en tu máquina


Deja todos los ficheros como estaban

Ejercicio 4: liberación


Comprueba el espacio libre en tu disco duro


Borra algunos ficheros grandes (usando comandos)


Comprueba de nuevo el espacio y verifica las ganancias

Texto


La interfaz universal

wc


wc <fichero>

Cuenta las palabras de un fichero (Word Count)

(y las líneas y los caracteres)


$ wc ejemplo.txt
   5  30 169 ejemplo.txt 

Cuenta el fichero de ejemplo

5 líneas, 30 palabras, 169 caracteres

Grep


grep <patrón> <fichero>

Busca el patrón en el fichero

(de Global Regular Expression Print)


$ grep abad ejemplo.txt
Dábale arroz a la zorra el abad. 

Filtra la única línea que contiene "abad"

cut


cut <opción> <file>...

Corta (CUT) caracteres o campos de un fichero


$ cut -c5-7 ejemplo.txt
abr
ale
[...]

Corta los caracteres del 5 al 7 de cada línea

$ cut -d' ' -f2 ejemplo.txt
cabra
arroz
[...]

Corta la segunda palabra de cada frase

head


head -c <caracteres> <fichero>...

Muestra los primeros caracteres de la entrada


$ head -c 12 página.html 
Muestra el inicio de página.html

tail


tail <fichero>...

Muestra las últimas líneas de un fichero


$ tail página.html 
Muestra el final de página.html

less


less <fichero>

Muestra el contenido del fichero, paginado

Versión sofisticada de more


$ less ejemplo.txt 

Muestra la primera (y única) página

Usa los cursores, página arriba y abajo

nano


nano <fichero>

Edita un fichero


Es un editor sencillo pero potente

Editor por defecto en Debian

Pulsa ^X (control-X) para salir

Ejercicio 1: cuenta palabras


Cuenta las palabras de todos los ficheros .md

Ejercicio 2: búsqueda recursiva


Comprueba si algún fichero del directorio
contiene la palabra "ejercicios"

Ejercicio 3: hasta <


Saca el contenido de las líneas de página.html

hasta el primer "<"

Procesos


Organización de tareas

Anatomía de un proceso Unix


Identificado con un process id (pid)


Corre de forma independiente


Tiene su propio espacio de memoria


Cada usuario tiene sus propios procesos

ps


ps x

Lista los procesos del usuario

(Process Status)


$ ps x
  PID TTY      STAT   TIME COMMAND
 2630 ?        Ssl    0:56 x-session-manager
 2658 ?        Ss     0:01 /usr/bin/ssh-agent /usr/bin/dbus-launch ...
[...]
30141 pts/4    Ss+    0:00 bash
Lista mis procesos

kill


kill -9 <pid>

Mata el proceso (KILL)

Con -9 envía la señal SIGKILL

Por defecto envía la señal SIGTERM (bastante pobre)


$ ps x
PID TTY STAT TIME COMMAND
2630 ? Ssl 0:56 x-session-manager
[...]
30141 pts/4 Ss+ 0:00 bash
$ kill -9 30141 

Mata el último bash

free


free 

Muestra la memoria libre (FREE)


$ free
             total       used       free     shared    buffers     cached
Mem:       3970764    3623364     347400     231608      14888     532480
-/+ buffers/cache:    3075996     894768
Swap:      5105660    2303880    2801780 

Hay  3 GB ocupados, casi 1 GB libre

top


top 

Muestra un listado interactivo de procesos


$ top 

Se maneja con el teclado:

  • M: ordena por Memoria
  • P: ordena por CPU
  • q: sale del programa (Quit)

time


time <comando>

Cuenta el tiempo que tarda en ejecutarse el comando


$ time wc /var/log/nginx/access.log.1
  226237  4325023 47378781 /var/log/nginx/access.log.1

real    0m0.897s
user    0m0.796s
sys     0m0.028s

Apenas un segundo para contar un fichero de 200k líneas

sleep


sleep <segundos>

Duerme durante los segundos pedidos


$ time sleep 1

real    0m1.003s
user    0m0.000s
sys    0m0.000s 

Duerme durante un segundo (y 3 ms)

Operador and (&&)


<comando1> && <comando2>

Ejecuta el primer comando y luego el segundo

Si el primero falla, no ejecuta el segundo


$ cd pic && ls && cd ..
bash.png 

Entra en el directorio pic, lo lista y sale de nuevo

Background (&)


<comando> & 

Ejecuta el comando en background


$ wget http://hugefiles.com/hugefile.txt & 

Inicia la descarga de un fichero enorme en background

Ejercicio 1: kill top


Arranca en un terminal un comando top


Luego mátalo desde otro terminal

Ejercicio 2: aviso


Haz un comando que te avise tras 60 segundos


Hazlo de forma que puedas trabajar mientras

en la misma consola



Ejercicio 3: memoria al inicio


Reinicia el ordenador


Comprueba cuánta memoria libre hay


Arranca un programa y verifica cómo ha cambiado

Ejercicio 4: asesino en serie


Intenta matar todos los procesos que puedas

Comprueba si el sistema se queda inestable

¡Reinicia!

Enlazando Comandos


Programas que trabajan juntos

Salida de un comando (>)


'comando' > 'fichero'

Redirige la salida de un comando a un fichero

Por defecto, los comandos muestra su salida

en la salida estándar (standard output, o stdout)


$ cat README.md soluciones.md > combinado.md

Combina dos ficheros en uno

Entrada de un comando (<)


'comando' < 'fichero'

Envía un fichero a la entrada de un comando

Por defecto, los comandos leen de la entrada estándar

(standard input, o stdin)


$ grep arroz < ejemplo.txt 

Busca la cadena arroz en el fichero

Tuberías Unix (|)


<comando1> | <comando2>

Enchufa la salida de un comando a la entrada de otro

Permite aplicar múltiples filtros


$ cat ejemplo.txt | grep "arroz" | grep "abad"
Dábale arroz a la zorra el abad

Filtra las líneas que contengan "arroz" y "abad"


¿Qué es un filtro?


Un programa que modifica la entrada

y escribe en la salida


Recibe y entrega texto


Puede hacer transformaciones arbitrarias

sort


sort <fichero>...

Ordena alfabéticamente la entrada


$ sort ejemplo.txt
Colecciono moscas, pero no estoy loco.
Dábale arroz a la zorra el abad.
Dame pan y llámame tonto.
La cabra se subió al monte.
Líneas separadas por saltos de línea.

Ordena ejemplo.txt alfabéticamente

uniq


uniq <fichero>...

Líneas únicas (UNIQue) en la entrada

¡Sólo une líneas adyacentes!

uniq -c <fichero>....

Cuenta las líneas únicas y las imprime


$ cat ejemplo.txt | sort | uniq -c 

Cuenta las líneas duplicadas en un fichero

wc

wc -l <fichero>... 

Cuenta las líneas de la entrada

wc -w <fichero>...
Cuenta las palabras de la entrada

$ wc -w *
     30 ejemplo.txt
    171 LICENSE
  45402 linuxwords
     35 página.html
wc: pic: Es un directorio
      0 pic
      7 README.md
    335 soluciones.md
  45980 total 
Cuenta las palabras en el directorio de proyecto

Salida de un comando, Añadiendo (>>)


'comando' >> 'fichero'

Añade la salida del comando al final del fichero


$ echo "hola, mundo" >> ejemplo.txt
Añade "hola, mundo" al final de ejemplo.txt

Ejercicio 1: etc


Muestra el contenido de /etc en árbol, paginado

(no todo a la vez)

Ejercicio 2: cuenta procesos


Cuenta cuántos procesos están corriendo
con el usuario actual

Ejercicio 3: iniciales


Busca un fichero diccionario Unix, una palabra por línea

(Debian: /etc/dictionaries-common/words)


Averigua cuál es la inicial por la que empiezan más palabras

Opciones

Porque es bueno tenerlas

cd (otra vez)


Valores especiales para cd:

$ cd / 

Cambia al directorio raíz del disco

$ cd

Cambia al directorio home del usuario

$ cd .. 
Cambia al directorio superior
$ cd - 
Cambia al último directorio visitado

Ficheros ocultos


.myfile 

Fichero oculto: no aparece en listados normales


Muy usados para configuración en $HOME

ls (otra vez)

ls -a 

Lista archivos ocultos (All)

ls -l 

Listado Largo

ls -R 

Listado Recursivo

ls -r 

Listado al Revés

ls -t 

Listado por Tiempo

Opciones largas y cortas


<comando> --<larga>

Opción larga: una o más palabras

<comando> -<corta>

Opción corta: una letra


$ ls -a
[...]
$ ls --all
[...]

Los dos comandos son idénticos

Manual: -h, --human-readable

cp (otra vez)


cp -f <origen> <destino>

Copia un fichero forzando (sin confirmar)


cp -i <origen> <destino>

Copia un fichero interactivo (pide confirmación)


cp -r <origen> <destino>
cp -R <origen> <destino>

Copia directorios recursivamente

mv (otra vez)


mv -f <origen> <destino>

Mueve un fichero forzando (sin confirmar)


mv -i <origen> <destino>
Mueve un fichero interactivo (pide confirmación)

mv -v <origen> <destino>
Mueve un fichero verboso (mostrando los nombres)

head (otra vez)


head -c <caracteres> <fichero>...

Muestra los primeros caracteres de un fichero


$ head -c 10 página.html
La cabra s$

Muestra el inicio de página.html

tail (otra vez)


tail -f <fichero>...

Sigue (Follow) el final del fichero

Muy útil para vigilar ficheros de log


$ tail -f /var/log/nginx/access.log
Muestra el final del log y lo sigue según va creciendo

split


split -b <bytes> <file> <prefix>

Corta el fichero en trozos del mismo tamaño con un prefijo


$ split -b 100 ejemplo.txt trozo
$ ls
ejemplo.txt  [...]  trozoaa  trozoab 

Corta el fichero de ejemplo en dos trozos

du

du <fichero>... 

Muestra el espacio ocupado (Disk Usage) por los ficheros

du -sh <fichero>...

Muestra el Sumario de uso para Humanos


$ du -sh *
4,0K    ejemplo.txt
4,0K    LICENSE
400K    linuxwords
4,0K    página.html
32K    pic
4,0K    README.md
4,0K    soluciones.md 

Espacio ocupado por ficheros y directorios

find


find <camino> <opciones>

Encuentra (FIND) el fichero en el camino


$ find . -name *.png
./pic/bash.png 

Encuentra ficheros por nombre en el directorio actual (.)

grep (otra vez)


grep [opciones] <patrón> [<fichero...>]

Busca una cadena patrón en uno o más ficheros

grep -i 

Busca una cadena insensible a mayúsculas (case insensitive)

grep -v 

Búsqueda inversa

grep -r 

Busca recursivamente en los directorios dados

tar

Archiva (Tape ARchive)

tar -czf <destino.tar.gz> <fichero1> <fichero2>... 

Comprime los ficheros en el destino

tar -xzf <origen.tar.gz> 

Descomprime el fichero origen


$ tar -czf pic.tar.gz pic
$ mv pic.tar.gz ..
$ cd ..
$ tar -xzf pic.tar.gz

Comprime un directorio y lo descomprime en otro sitio

ps (otra vez)

ps aux 

Muestra todos los procesos del sistema, estilo BSD

$ ps aux
USER       PID %CPU %MEM    VSZ  RSS TTY STAT START  TIME COMMAND
root         1  0.0  0.0  13228   52 ?    Ss  abr25  0:04 init [2]        
root         2  0.0  0.0      0    0 ?    S   abr25  0:00 [kthreadd]
[...]
Sin el -
ps -ef 

Muestra todos los procesos del sistema, estilo estándar

$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 abr25 ?        00:00:04 init [2]        
[...]

Señales Unix


Cada proceso puede recibir varias señales

  • SIGTERM: TERMina elegantemente
  • SIGKILL: mata con saña
  • SIGHUP: la consola ha colgado (Hang UP)

kill (otra vez)


kill -<señal> <pid>

Envía al proceso la señal pedida

Señal identificada por número o por nombre

$ 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 

Lista las señales disponibles

$ kill -9 5837

Envía la señal SIGKILL a un proceso

Ejercicio 1: último modificado


Encontrar el último fichero modificado en un directorio

Ejercicio 2: comprime con bzip2


Comprimir un directorio con Bzip2 (extensión .tar.bz)

Moverlo y descomprimirlo en otro directorio

Ejercicio 3: sin D ni d


Mostrar las líneas del fichero de prueba ejemplo.txt

que no contienen la letra "d"

(en mayúsculas o minúsculas)

Ejercicio 4: cuenta procesos de usuario


Extrae todos los usuarios con procesos en la máquina

y cuántos procesos tiene cada uno

Buscando Comandos

Mucha tela que cortar

man

man <comando>

Muestra el manual del comando

man <sección> <comando >

Muestra la página de la sección dada:

  1. programas
  2. llamadas de sistema
  3. biblioteca del sistema
  4. ficheros especiales
  5. ficheros
$ man 5 hosts 

Muestra el manual del fichero /etc/hosts

apropos


apropos <palabra>

Busca comandos sobre la palabra

Mira en la descripción y el manual


$ apropos permisos
access (2)           - comprueba los permisos de usuario para un fichero
chmod (1)            - cambia los permisos de acceso de ficheros
chmod (2)            - cambia los permisos de un fichero
[...]
fchmod (2)           - cambia los permisos de un fichero
ioperm (2)           - establece permisos en los puertos de entrada/salida 

Comandos (1) y llamadas de sistema (2)

which


which <comando>

Muestra la ruta donde reside el comando


$ which find
/usr/bin/find

Encuentra el fichero ejecutable donde reside find


$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/home/usuario/bin

Muestra el camino (PATH) donde se buscan los ejecutables

--help

<comando> --help
<comando> -h
<comando> -?

Muestra la ayuda interactiva de un comando (generalmente) 


$ apropos --help
Modo de empleo: apropos [OPCIÓN...] KEYWORD...
Project-Id-Version: man-db 2.3.20
[...]
  -d, --debug                emit debugging messages
  -v, --verbose              print verbose warning messages
[...]
  -?, --help                 da esta lista de ayuda
      --usage                da un mensaje corto de modo de empleo
  -V, --version              muestra la versión del programa

Muestra la ayuda de apropos

--verbose


<comando> --verbose
<comando> -v

Ejecuta un comando de forma verbosa

(generalmente)

(y sí, está en el DRAE)

<comando> -vv, -vvv, -vvvv 

A veces se puede obtener la salida muy, muy, muy verbosa

$ vlc -vvv 

Ejecuta el reproductor VLC con máxima información

info

info <comando>

Muestra información sobre el comando


Navegación manual

  • espacio: pagina hacia atrás
  • borrar: pagina hacia delante
  • p: previo
  • n: siguiente (next)


(Mejor man)

history


history 

Muestra el historial de comandos

history -c 
Borra el historial

$ history
 1149  ls
 1150  cd ..
[...]
 2146  history
 2147  history | less 

Últimos comandos ejecutados

Y por supuesto, internet



Busca "Unix <función>"

Ejercicio 1: movidas


Busca en la historia cuántas veces has usado mv

Ejercicio 2b: Bonus round


Busca la cadena "-l" en la ayuda de ls

Pista: puede que haya que "escapar" el guión, usando "\-l"

Ejercicio 3: acceso remoto


¿Qué programa usarías  para acceso remoto?

(remote login)

Expresiones regulares

Un mal necesario

¿Qué es una expresión regular?


Se usa para buscar en textos


Una expresión regular intenta casar con un texto

(hace matching)


Cuando hay coincidencia la expresión regular casa

y la búsqueda tiene éxito

cualquier Carácter


. 

Casa con cualquier carácter


"."

Expresión regular para un solo carácter

Busca coincidencias con un texto


egrep


egrep <patrón> <fichero>

Hace el matching con una expresión regular por líneas


$ egrep "." página.html
<html>
<head>
<title>
[...]
Muestra los tags HTML abiertos

Repetición


+ 

Repetido una o más veces

"pa(ta)+"

Casa con: pata, patata, patatatata...


* 

Repetido 0 o más veces

"tomates*"

Casa con: tomate, tomates, tomatesss...

Inicio y fin de línea


^ 

Inicio de línea

"^la"

Casa con "la niña" pero no con "Mírala".


$ 

Fin de línea

"na$"

Casa con "Lasagna" pero no con "Empana"

Espacio blanco (whitespace)


\s 

ESpacio blanco. Casa con: espacio, tabulador (\t),

salto de línea (\n) y retorno de carro (\r)


"54\s+54"

Captura "54        54", "54

54", "54   \t\t   54"

Palabra


\w 

Carácter de palabra (Word), alfanumérico:

  • A-Z
  • a-z
  • 0-9
  • "_"
  • marcas diacríticas


"\w+\s\w+"

Casa con dos palabras seguidas con espacio en medio

No espacio, no palabra


\S 

Cualquier carácter que no sea un espacio blanco

\W 

Cualquier carácter no alfanumérico o "_"


"\w+\W\w+"

Casa con dos palabras separadas por lo que sea:

"hola    hola", "hola^\|/*hola"

Literal


Cualquier carácter que aparece

en una expresión regular hace de sí mismo

excepto caracteres de control: ^.[$()|*+?{\


Por ejemplo: cualquier cadena a-z, A-Z, números, diacríticos

"hola"

Casa con el literal "hola"

Más repetición


?

Presente una vez o ninguna

"pa(ta)?ta"

Casa con: pata, patata


{<n>,<m>}

Repetido entre n y m veces

"pa(ta){1,2}"
Casa con: pata, patata

Escapado


\ 

Convierte un carácter de control en un literal


"\$HOME"

Casa con el literal "$HOME".

"\\"

Casa con la barra invertida "\"

Rangos

[<alternativas>] 

Casa con cualquiera de las alternativas

[^<carácter>] 

Negación de un carácter


"[abc]"

Casa con "a", "b" o "c"

"<[^>]>"

Casa con el contenido de un tag "<...>"

incluyendo espacios, comillas...

y... Más repetición


{<n>}

Repetido exactamente n veces

"pa(ta){2}"

Casa con: patata


{n,}

Repetido n veces o más

"muchi(si){1,}mo"
Casa con: muchisimo, muchisisimo, muchisisisisimo...

Capturas


(<grupo>) 

Captura un grupo

\<n> 

Repite el grupo número n


"(\w\w)li\1"
Captura dos caracteres, "li" y luego repite la captura
Casa con "talita", "colico", "01li01"

Más egrep


egrep -o <patrón> <fichero>

Muestra sólo las coincidencias con la expresión regular


$ egrep -o "<\w+>" página.html
<html>
<head>
<title>
[...]

Muestra los tags HTML abiertos

Ejercicio 1: tags HTML


Encuentra todos los tags cerrados
en el fichero página.html de los materiales

Ejemplo de tag cerrado:
<a>...</a>


Ejercicio 2: números


Busca una expresión regular que case con

números en coma flotante:

4, 5.3, 89987898.5887999


Pista: puedes usar esta línea para verificar la expresión

echo "5.4" | egrep -o "..." 

Verifica todos los casos de arriba

Ejercicio 3: regex golf


Jugar al regular expression golf

http://regex.alf.nu/

y conseguir al menos 600 puntos

Seguridad

Defensa en profundidad

Acceso


Cada usuario Unix tiene un nombre y una contraseña


servidor login: usuario
password:
Last login: Fri Mar 21 from ...
$ 

Hace login con el usuario en el servidor

Password oculta, sin asteriscos

passwd


passwd [<usuario>]

Cambia la contraseña del usuario

Si no se especifica, del usuario actual


$ passwd
Cambiando la contraseña de usuario.
(actual) contraseña de UNIX:
Introduzca la nueva contraseña de UNIX:
Vuelva a escribir la nueva contraseña de UNIX:
passwd: contraseña actualizada correctamente 

Cambia la contraseña del usuario actual

Usuario root


Superusuario

Tiene acceso absoluto sobre la máquina

y permisos para acceder a todos los ficheros


Excepciones:

  • NFS: unidad montada por red
  • SELinux: extensión de seguridad para Linux

su


su 

Cambia el usuario activo a root (SuperUser)


su -u <usuario>

Cambia al usuario dado


$ su
# su otrousuario
$ 

Cambia a root y luego a otro usuario

sudo


sudo <comando>

Permite ejecutar un comando como el usuario root

Funciona en: Mac OS X, Ubuntu


$ rm /root/file
rm: no se puede borrar «/root/file»: Permiso denegado
$ sudo rm /etc/nginx/sites-enabled/frontend 

Borra un fichero como root

El poder de sudo

Fuente: xkcd

whoami


whoami 

Imprime el usuario logado

Who am I? ¿Quién soy?


$ whoami
usuario

En caso de que se te olvide quién eres

users


users 

Muestra los usuarios logados


$ users
usuario usuario usuario usuario usuario 

Todos los usuarios logados en mi máquina

(Yo unas cuantas veces)

adduser


adduser <usuario>

Crea un nuevo usuario


# adduser pepito
Añadiendo el usuario `pepito' ...
Añadiendo el nuevo grupo `pepito' (1001) ...
Añadiendo el nuevo usuario `pepito' (1001) con grupo `pepito' ...
Creando el directorio personal `/home/pepito' ...
Copiando los ficheros desde `/etc/skel' ...
Introduzca la nueva contraseña de UNIX:
[...] 

Crea el usuario pepito

w


w 

Muestra los usuarios logados y qué están haciendo


$ w
 22:30:12 up 15 days, 55 min, 14 users,  load average: 0,70, 0,89, 0,73
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
usuario  tty7     :0               25abr14 15days  3:27m 53.04s x-sess...
usuario  pts/0    :0               25abr14 19:59m  0.14s  0.14s bash
usuario  pts/2    :0               25abr14  4.00s  0.44s  0.01s w
usuario  pts/6    :0               25abr14 11:37m  1.73s  0.02s ssh ...
usuario  pts/9    :0               25abr14 12:01m  1.41s  0.09s vim ...
usuario  pts/11   :0               25abr14 34:22m  1:16  13:10  xfce4...
usuario  tty1                      04may14  6days  0.13s  0.12s -bash
usuario  pts/4    :0               00:34   11:01m  0.18s  0.18s bash
Usuarios logados en mi máquina y qué hacen

chmod


chmod <modo> <fichero>...

Cambia los permisos de acceso de uno o más ficheros


$ ls -l README.md
-rw-r--r-- 1 chenno chenno 48 may  5 00:41 README.md
$ chmod g+w README.md
$ ls -l README.md
-rw-rw-r-- 1 chenno chenno 48 may  5 00:41 README.md 
Cambia README.md para que el grupo puede modificarlo

Permisos


d rwx rwx rwx 

Permisos para directorio, usuario, grupo y todos

$ ls -l ~/.ssh/*
-rw-r--r-- 1 usuario usuario 1238 jul 17  2013 ~/.ssh/authorized_keys
-rw------- 1 usuario usuario  668 abr 16  2013 ~/.ssh/id_dsa
-rw-r--r-- 1 usuario usuario  601 abr 16  2013 ~/.ssh/id_dsa.pub
-rw------- 1 usuario usuario 8404 may  9 15:27 ~/.ssh/known_hosts 

Permisos en el directorio .ssh


Permisos en octal: lectura (4) + escritura (2) + ejecución (1)

Todo el mundo accede: 777

groups


groups 

Muestra a qué grupos pertenece el usuario


$ groups
usuario cdrom floppy audio dip video plugdev fuse 

Siempre primero el grupo propio del usuario

Cada grupo da unos accesos al usuario

adduser (otra vez)


adduser <usuario> <grupo>

Añade un usuario a un grupo


# addgroup grupeto
Añadiendo el grupo `grupeto' (GID 1002) ...
Hecho.
# adduser usuario grupeto
Añadiendo al usuario `usuario' al grupo `grupeto' ...
Añadiendo al usuario usuario al grupo grupeto
Hecho.
Añade pepito al grupo grupeto

Resuelve algunos problemas de permisos

chown


chown <usuario>:<grupo> <fichero>...

Cambia el propietario (OWNer) de uno o más ficheros

chown -R <usuario>:<grupo> <directorio>

Cambia Recursivamente el propietario de un directorio


# chown -R root:root pic 

Cambia de usuario el contenido del directorio

Ejercicio 1: sé root


Conviértete en el usuario root

en un sistema operativo que use sudo:

Mac OS X, Ubuntu


Pista: hay una solución muy elegante

Ejercicio 2: nuevo dueño


Crea un directorio en /var/log llamado "pepito"


Añade un fichero pepito.log al directorio


Cambia de dueño todo el directorio con un comando

Ejercicio 3: nuevo amigo


Crea un nuevo usuario "pepito"


Conviértete en el usuario "pepito"


Vuelve a ser root


Busca el comando para borrar el usuario

y borra a pepito


Comandos Avanzados


Para epatar a tus colegas

rename


rename <regexp> <files> 

Renombra los ficheros según la expresión regular


$ rename "s/md/text/" *.md 

Renombra los ficheros .md a .text

ssh


ssh <usuario>@<servidor>

Acceso remoto seguro (Secure SHell)


ssh -i <certificado> <usuario>@<servidor>

Usa el certificado del fichero como credenciales

para acceder a la máquina remota


$ ssh root@localhost 

Accede a la máquina local como root

scp, sftp


scp <origen> <destino>

Copia segura usando SSH (Secure CoPy)

sftp <usuario>@<servidor>[:<directorio>]

FTP seguro (Secure FTP): copia interactiva


$ scp usuario@servidor:dir/fichero.dat local.dat 

Copia un fichero remoto a local

$ scp ~/dir/fichero.dat usuario@servidor: 

Copia un fichero local al $HOME de un servidor remoto

nohup


nohup <comando>

Ejecuta un comando inmune a cuelgues

Seguirá corriendo aunque se cierre la consola


$ nohup scp usuario@servidor:fichero-grande.dat .

Corre la copia de un fichero grande

Saca la salida a nohup.out

Mount, umount


mount [-t <tipo>] <dispositivo> <directorio>

Monta una unidad

$ mount -t ext4 /dev/sdb /media/usb 

Monta un disco USB en el directorio /media/usb


umount <directorio> / <dispositivo>

Desmonta una unidad

umount /media/usb 

Desmonta el disco USB

rsync


rsync <opciones> <origen> <destino>

Sincroniza dos directorios (Remote SYNC)


$ rsync -av proyectos /media/usuario/backup/proyectos

Sincroniza los proyectos locales con un disco extraíble

$ rsync -av proyectos usuario@servidor:proyectos

Sincroniza con un servidor remoto

git

Control de versiones

Subcomandos:

git clone <repo>

Baja un repo

git commit <ficheros> -m <mensaje>

Compromete un cambio

git push 

Sube cambios

git pull 

Baja cambios

wget


wget <url> 

Accede a una página web y la baja en local


$ wget http://google.com/
--2014-05-10 22:17:47--  http://google.com/
[...]
Petición HTTP enviada, esperando respuesta... 200 OK
Longitud: no especificado [text/html]
Grabando a: “index.html”
...
    [ <=> ] 12.708      --.-K/s   en 0,008s 

2014-05-10 22:17:47 (1,60 MB/s) - “index.html” guardado [12708] 

Baja la página principal de Google a index.html

links2

links2 <url>

Browser estándar y completo (sin JavaScript)


$ links2 http://google.com/
                                                                  Google
   Busqueda Imagenes Maps Play YouTube Noticias Gmail Drive Mas >>
   Historial web | Configuracion | Iniciar sesion
Espana
_______________________________ Busqueda avanzadaHerramientas del idioma
[ Buscar con Google ] [ Voy a tener suerte ]

Google.es tambien en: catal`a galego euskara English

Programas de publicidadSoluciones Empresariales+GoogleTodo acerca de GoogleGoogle.com

(c) 2013 - Privacidad y condiciones

Navega por la página principal de Google

Ejercicio 1: copia de seguridad


Haz una copia de seguridad de tu disco duro

en un dispositivo externo

(disco externo, llave USB)

usando rsync


Ejercicio 2: navega en texto


Navega con links2
(o algún otro navegador de texto)

Haz una búsqueda en Google

Atrás: tecla Retroceso

Navega hasta github.com/alexfernandez

Ejercicio 3: En las nubes


Ir a Amazon Web Services (AWS)

http://aws.amazon.com/

(o a cualquier otro proveedor en la nube)


Abrir cuenta

Crear servidor micro (gratis)


Acceder por SSH usando el certificado

Algunos trucos


Para ser el rey de la fiesta

Configuración de Bash


~/.bashrc

Fichero de configuración en el directorio $HOME


Se ejecuta cada vez que se abre una consola


$ nano ~/.bashrc
$ vim ~/.bashrc

Edita el fichero directamente desde cualquier directorio

Colores del pie


Añade esta línea al final de tu .bashrc:

PS1='\[\033[00;34m\]\u@\h: \[\033[00;32m\]\w \$ \[\033[00m\]'


Puedes elegir otros colores de esta lista


Negro       0;30     Gris Obscuro  1;30
Azul        0;34     Azul Claro    1;34
Verde       0;32     Verde Claro   1;32
Cyan        0;36     Cyan Claro    1;36
Rojo        0;31     Rojo Claro    1;31
Purpura     0;35     Fiuscha       1;35
Café        0;33     Amarillo      1;33
Gris Claro  0;37     Blanco        1;37

Autocompletado


Ubuntu:

$ sudo apt-get install bash-completion 

Debian (.bashrc):

# enable bash completion in interactive shells
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi 

Mac OS X: integrado por defecto


Pulsa la tecla Tab para autocompletar

Usa tu consola como calculadora


$(( <operación> )) 

Calcula la operación aritmética

Los espacios son importantes


$ echo $(( (5 + 4) * 4 ))
36

Calcula (5 + 4) * 4

$ echo $(( (5 + 4) ** 4 ))
6561
Calcula (5 + 4) a la cuarta potencia

Envía una tarea a background

nohup

screen

busca en el histórico


Control-r: inicia la búsqueda interactiva


Teclea "ls":

(reverse-i-search)`ls': ls 

Va buscando los comandos que casan

Comando-n: siguiente

Comando-p: anterior

Genera contraseña aleatoria


/dev/random

Genera bytes aleatorios


$ head -c 12 /dev/random | base64
e/a5Yd5/q1tPFsEi 

Genera una contraseña que puede contener caracteres "/", "+"


genera contraseña en minúsculas


tr <conjunto1> <conjunto2>

Transforma los caracteres del conjunto1 al conjunto2

tr -d <conjunto>

Elimina los caracteres del conjunto

Categorías POSIX


$ head -c 12 /dev/random | base64 | tr [:upper:] [:lower:] | tr -d +/0-9
imjbhbjtiamaiu
Genera una contraseña de sólo letras minúsculas

bb


bb 

Demo de aalib


$ bb 

Corre la demo

Compila tu propio software


make <objetivo>

Compila el software del directorio atual


$ wget http://prdownloads.sourceforge.net/aa-project/bb-1.2.tar.gz
$ tar -xzf bb-1.2.tar.gz
$ cd bb-1.2
$ ./configure
$ make
# make install 

Compila el paquete bb

Ejercicio 1: Entorno de compilación

Compilador + make


Mac OS X: Xcode

Ubuntu:

sudo apt-get install make gcc 

Debian:

# apt-get install make gcc  

Fedora:

su -c 'yum groupinstall “Development Tools”' 

Ejercicio 2: Instala aalib


Mac OS X:

$ brew install aalib 


Ubuntu:

$ sudo apt-get install libaa1 


Debian:

# su apt-get install libaa1 

Ejercicio 3: compila bb


Sigue estos pasos:

$ wget http://prdownloads.sourceforge.net/aa-project/bb-1.2.tar.gz
$ tar -xzf bb-1.2.tar.gz
$ cd bb-1.2
$ ./configure
$ make
$ ./bb

Para compilar el paquete bb y correrlo


Para Mac OS X existe una versión especial:

git clone https://github.com/artyfarty/bb-osx.git 

Scripts de Bash


Desencadena a la bestia

shebang!


#!/bin/bash 

Al inicio del fichero, indica que es un script de bash


#!/bin/bash
# Alex 2014-05-11: hello Bash
echo "hello, world" 

Script hello-world.sh

$ ls -l hello-world.sh
-rwxr-xr-x 1 chenno chenno 64 may 11 21:26 hello-world.sh 

Requiere permisos de ejecución

Variables de sistema

<CLAVE>=<valor>

Define una variable CLAVE con un valor

$<CLAVE>

Accede a la variable CLAVE


$ echo $HOME
/home/usuario

Muestra el directorio home del usuario

$ echo $EDITOR 

Muestra el contenido de la variable $EDITOR

(El editor por defecto)

Condicionales

if [ <condición> ] 
then
    <código si la condición se cumple>
else
    <código si no se cumple>
fi

Comprueba una condición

if [ -e "$fichero" ]
then
    echo "found $fichero"
fi 

Comprueba si existe un fichero (fíjate en las comillas)

if [ -d "$directorio" ] ...

Comprueba si el fichero es un directorio

... y muchas más

Líneas multi-comando


<comando 1>; <comando 2>

Separa dos comandos en la misma línea

y los corre en secuencia


$ cd $HOME; ls
bin
...

Cambia al directorio home del usuario

y muestra los ficheros encontrados


for

for <variable> in <rango>
do
    <código>
done 

Recorre un rango con una variable

y corre el código con ella


$ for fichero in *; do echo "Encontrado $fichero"; doneEncontrado ejemplo.txt
Encontrado LICENSE
Encontrado página.html
Encontrado pic
Encontrado README.md
Encontrado scripts
Encontrado soluciones.md 

Muestra todos los ficheros locales

Rangos

{<inicio>..<fin>}

Crea un rango entre dos números

{<inicio>..<fin>..<paso>}

Crea un rango saltando el paso


for contador in {1..5..2}
do
    echo "Contando $contador"
done

Contando 1
Contando 3
Contando 5

Cuenta de 1 a 5 de 2 en dos

funciones


function <name> {
    ...
} 

Define una función

Los parámetros aparecen como $1, $2, $3...

<name> par1 par2... 

Invoca la función

function imprime {
  echo $1
}
imprime hola

Ejecuta una función que muestra "hola"

ejercicio 1: Crea un montón

Escribe un script que cree 10 ficheros holaXX.txt,

sustituyendo XX por un número.

Ejemplo:

hola1.txt
hola2.txt
...
hola10.txt

Después debe borrarlos.


Cámbialo para que escriba y borre 20 ficheros.

Ejercicio 2: lista ficheros

Crea un script que liste todos los ficheros de un directorio


Sólo los ficheros y directorios a primer nivel


Para cada uno debe imprimir "Encontrado <fichero>"

Ejemplo:

Encontrado ejemplo.txt
Encontrado LICENSE
Encontrado página.html
Encontrado pic
Encontrado README.md
Encontrado scripts
Encontrado soluciones.md 

Ejercicio 3: cuenta ficheros


Crea un script que cuente todos los ficheros de tu $HOME

incluyendo ficheros contenidos en directorios


Haz que cuente también los directorios aparte


Truco: usa recursividad

(una función que se llama a sí misma)

¡Gracias!


Código: https://github.com/alexfernandez/floqq-unix
Presentación: https://slid.es/alexfernandez/unix-floqq