Hiparco

Recetas y trucos de GNU/Linux e informática en general

Alojado en http://guimi.net

Generar (diff) y aplicar (patch) parches

Hay manuales muy buenos sobre cómo generar parches… este no es uno de ellos, pero es una guía rápida para el 90% de casos.

Para los ejemplos suponemos que tenemos ficheros originales en una carpeta “original” y ficheros modificados en una carpeta “new”.

Trabajando con ficheros
Primero veremos como parchear un único fichero. Usamos el formato unificado (-u). Es el mejor pero “solo” sirve para entornos GNU, es decir todos los Linux y muchos UNIX.
diff -u original/foo.txt new/foo.txt > foo.patch

Podemos ver el parche generado con:
less foo.patch
La sintaxis es (línea o rango de líneas)(orden)(línea o rango de líneas)
Orden puede ser:
c – change – sustituir unas líneas por otras
a – add – añadir líneas
d -delete – borrar líneas

Para aplicar el parche podemos hacer (nombre de fichero implícito en el parche):
patch < foo.patch
O más seguro
patch bar.txt < foo.patch

Si queremos revertir un parche, porque detectamos que introduce un bug pero que el que corrige, por ejemplo, podemos hacer:
patch -R < foo.patch

Trabajando con directorios
Si modificamos varios ficheros, trabajamos con los directorios.
Generamos el parche con:
diff -rupN original/ new/ > codigo.patch

Lo aplicamos con:
patch -p1 < codigo.patch

Para más información, como siempre:
$ man diff
$ man patch

Trabajando con github.com
Los commits de Github pueden bajarse como parches añadiendo “.patch” al URL.
Así bastaría con:
$ wget github.com/URL_COMMIT.patch
$ patch -p1 < URL_COMMIT.patch

diff, patch, parche

Introducción a bash

El texto original es de IvanYuja. Posteriormente ha sido modificado y ampliado.

Linux presenta una interfaz de línea de comandos, llamado consola o shell, la cual permite al usuario interactuar con el sistema operativo de una forma amigable.

Algunos ejemplos de estas consolas son: bash, csh, ksh, sh, entre otros. En este texto se utilizará BASH.

BASH (acrónimo de Bourne-Again Shell) es un intérprete de comandos compatible con sh, puede leer comandos desde la entrada estándar (standar input) o de un archivo.

Una salida típica de un shell de usuario puede verse así:

~ $ _

si la salida contiene un signo de almoadilla (#), en lugar del signo de dólar, quiere decir que esta loggeado como root.

~ # _

Cuadro I: Keystrokes para editar en la línea de comandos

Teclas Descripción
Ctrl-a Mueve el cursor al inicio de la línea de entrada
Ctrl-b Mueve el cursor un espacio hacia adelante
Ctrl-f Mueve el cursor un espacio hacia atrás
Ctrl-d Borra la letra que esta inmediatamente despúes del cursor
Ctrl-e Mueve el cursor al final de la línea de entrada
Ctrl-k Corta caracteres desde la posición del cursor hasta el final de la línea
Ctrl-n Se desplaza en el histórico de comandos hacia adelante
Ctrl-p Se desplaza en el histórico de comandos hacia atrás
Ctrl-q Des-bloquea la terminal
Ctrl-r Búsqueda de comandos en el histórico
Ctrl-s Bloquea la terminal
Ctrl-t Swap entre letras. Eje: ‘jeo’ lo convierte en ‘joe’ si el cursor esta encima de la ‘o’ al momento de corregir
Ctrl-l Limpia la terminal (equivalente a clear)
Ctrl-u Corta toda la línea de entrada
Ctrl-w Borra la palabra que está antes del cursor
Ctrl-y Pega el texto que fue cortado, a partir de la posición del cursor
Tab Completa comandos o rutas, según existan
Tab-Tab Muestra opciones que cumplen con el inicio de un patrón

a. Completando comandos:

$ ls /bin/m[tab][tab] 
mkdir mkfifo mknod more mount mv 

$ ls /bin/mor[tab] 
$ ls /bin/more

b. Repitiendo el último comando que se digitó:

$ [UP]

c. Utilizando el historial:
El comando history mostará un historial ennumerado de los últimos comandos digitados.

$ history 
 1 cd /home/ 
 2 cd /mnt/cdrom/ 
 3 ls 
 4 history

para hacer uso de alguno de los comandos digitados, es posible llamarlos utilizando el signo de admiración (!) seguido del número del comando digitado en el historial, por ejemplo:

$ !3 
ls 
arch* domainname@  ln* sed* awk@ du* loadkeys* setterm* bash* echo* login* sh@ bunzip2@ ed* ls* shred*

d. Ejecutando una lista de comandos:

Para ejectuar más de un comando en la línea de entrada, solamente digite cada comando en orden separando cada comandos con un punto y coma (;). Por ejemplo para limpiar la consola y luego desloggearse del systema puede hacer:

$ clear; logout

e. Redireccionado la entrada y salida:
Utilice el operador ‘>’ para redireccionar la salida estándar de un comando a un archivo al cual se va a escribir la salida, y el operador ‘>>’ para anexar la salida a un archivo (el archivo puede existir, o no).
Por ejemplo:

$ ls > /tmp/contenido.de.bin

f. Mostrando el contenido de un archivo:
hay herramientas para ver el contenido de un archivo de texto entre ellas las más comunes son: less, more, most y cat, aunque el comando cat tiene más funcionalidad que solamente mostrar el contenido de un archivo.

Del ejemplo anterior:

$ cat /tmp/contenido.de.bin 
arch* 
awk@ 
bash* 
bunzip2@ 
bzcat@ 
bzip2* 
... 

o bien se puede direccionar la entrada de cat del archivo contenido.de.bin, de la siguiente forma:

$ cat < /tmp/contenido.de.bin 
arch* 
awk@ 
bash* 
bunzip2@ 
bzcat@ 
bzip2* 
...

g. Redireccionando mensajes de error a un archivo: para redireccionar la salida error estándar utilice el operador ‘>’ precedido de ’2′ (2 representa al archivo de error estándar) luego el archivo al cual se va a escribir el error:

$ ls archivo-que-no-existe 2 > command.error 

para redireccionar la salida estándar y el error estándar a un mismo archivo haga:

$ ls archivo-que-no-existe &> command.error

por ejemplo, si se quisiera redireccionar la salída estándar a la salida de error estándar se puede hacer lo siguiente:

$ (ls /bin/ 1>&2)>a.txt 
arch* 
awk@ 
bash* 
bunzip2@ 
bzcat@ 
bzip2* 
... 

$ cat a.txt

observará que a.txt no contiene ningún dato, ya que la redirección ‘> a.txt’ recibe la salida estándar, la cual está siendo redireccionada al error estándar, por tanto a.txt se encuentra vacío.

h. El background y foreground: usted puede ejecutar comandos sin que estos bloqueen la línea de comandos en su ejeccución, a esto se le llama background y regresarlos a la salida en la línea de comandos (foreground). Para ejecutar un comando en background solamente tiene que añadir el operador ‘&’ al final del comando:

$ ls /bin/ > contenido.de.bin & 
[1] 683 
[1] Done     ls /bin/ >contenido.de.bin 

donde 1 es el número de proceso siendo ejecutado en la shell que se utiliza y 683 es el identificador del proceso, asignado por el kernel. La última línea le informa cuando el comando finalizó su ejeccución.

Ahora bien, si yo estoy utilizando alguna aplicacion y la quiero detener para poder ejectuar otro comando, utilizo el keystroke

Ctrl-z

y para ver la lista de procesos que están siendo ejecutados bajo esa shell:

$ jobs 
[1]+ Stopped vi

de nuevo el 1 me va a mostrar el número de proceso para dicha shell y ‘Stopped’ me dice, que el comando esta detenido de ejecución en ese momento, si quiero seguir ejecutando ese proceso en el background, se utiliza el comando bg, seguido por el numero de proceso del shell. En nuestro caso (aunque no tenga mucho sentido ejecutar un editor en background) se utiliza:

$ bg %1 
[1]- vi &

para regresar un comando proceso al foreground se utiliza el comando fg, seguido por el número de proceso para la terminal. Por ejemplo:

$ fg %1

para ‘matar’ algún proceso que esté en bg puedo utilizar el comando kill seguido por el número del proceso para la shell. Ejemplo:

$ kill %1 
[1]+ Stopped vi

i. Tubería entre aplicaciones: la carácterística principal de la shell de Linux (y sistemas parecido- UNIX) es que no existen programas monolíticos para algo complejo, sin embargo la shell ofrece comandos de fin sencillo pero que uniéndolos hacen un proceso bastante complejo. Para comunicar programas entre sí, se utiliza el operador ‘|’ (pipe), esto lo que hace es comunicar la salida estándar de un comando con la entrada estándar de otro comando, por ejemplo, si quisiéramos contar la cantidad de archivos en el directorio /dev, podemos utilizar:

$ ls /dev/ | wc -l 
2561 

donde el comando `wc -l’ lo que hace es contar la cantidad de líneas que recibe de una entrada estándar, en este caso el resultado de ls dev.

j. Prioridad de los procesos:
Lo más común es tener muchos procesos a la vez ejecutándose en nuestra máquina.
Pero no todos son igual de importantes.
La forma de establecer prioridades es ejecutando desde el principio el comando interesado
mediante nice, o bien, conseguir su PID si ya se está ejecutando
y usar renice para cambiar su prioridad.

Algunos ejemplos:

$ nice -n PRIORIDAD COMANDO
$ renice PRIORIDAD PID_PROCESO

PRIORIDAD es un valor que va desde -20 a +20 (con el signo incluido). -20 es la prioridad más alta (al contrario de lo que cabría pensar), y +20 la más baja. Sólo root puede establecer un proceso a una prioridad negativa, los usuarios como máximo pueden poner un proceso en prioridad 0.

Introducción a bash, shell, línea de comandos, prompt