<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Calcifer &#187; gnu/linux</title>
	<atom:link href="http://blog.calcifer.com.ar/tag/gnulinux/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.calcifer.com.ar</link>
	<description></description>
	<lastBuildDate>Sat, 02 Oct 2010 05:32:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Debian squeeze en Samsung N210</title>
		<link>http://blog.calcifer.com.ar/2010/07/debian-squeeze-en-samsung-n210/</link>
		<comments>http://blog.calcifer.com.ar/2010/07/debian-squeeze-en-samsung-n210/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 18:07:03 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[gnu/linux]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=731</guid>
		<description><![CDATA[La semana pasada me compré una netbook Samsung N210 con la cual estoy muy contento. Le instalé Debian squeeze (testing) y logré configurarle todas las teclas especiales, incluyendo las usadas para regular el brillo de la pantalla. Me basé en varias guías como esta y esta otra, aunque no las seguí exactamente y es por [...]]]></description>
			<content:encoded><![CDATA[<p>La semana pasada me compré una netbook <a href="http://www.samsung.com/sg/consumer/pc-peripherals-printer/notebook-pc/n-series/NP-N210-JA01SG/index.idx?pagetype=prd_detail" class="external">Samsung N210</a> con la cual estoy muy contento. Le instalé Debian squeeze (testing) y logré configurarle todas las teclas especiales, incluyendo las usadas para regular el brillo de la pantalla. Me basé en varias guías como <a href="http://artipc10.vub.ac.be/wordpress/uncategorized/samsung-n210-netbook-on-debian-gnulinux.html" title="Samsung N210 netbook on Debian GNU/Linux" class="external">esta</a> y <a href="http://josthalen.wordpress.com/2010/07/03/linux-on-samsung-n210/" title="Linux on Samsung N210" class="external">esta otra</a>, aunque no las seguí exactamente y es por eso el motivo del post.</p>
<p>Antes de comenzar la guía (y suponiendo que como yo, estás leyendo esto antes de comprar la máquina) te cuento mi experiencia con este aparatito. Algo que me hacía dudar en comprarme o no una netbook era el teclado que traían: demasiado chicos o sin espacio entre teclas. La N210 tiene casi la misma distancia entre la A y la Ñ que los teclados de escritorio y además tiene las teclas separadas como para que los dedos reconozcan mejor dónde están ubicados. Lo encuentro bastante cómodo y agradable de usar y salvo por un par de teclas que complican un poco (la &lt; se encuentra sobre la derecha y el shift derecho es chico) me siento a gusto con él. Por otro lado la batería dura aprox. 7 hs (con el brillo casi a tope) contra las 11 que declara Samsung. Dudo que llegue a eso incluso desconectando la wifi, bluetooth y poniendo el brillo al mínimo, pero aun así destaca su autonomía. Otra característica que me gusta es que es silenciosa y calienta muy poco.</p>
<p>Una última cosa antes de comenzar: El microprocesador <a href="http://ark.intel.com/Product.aspx?id=42503" class="external">Atom N450</a> tiene tecnología <a href="http://en.wikipedia.org/wiki/Hyper-threading" class="wikipedia">Hyperthreading</a> que paraleliza el procesador físico en dos procesadores virtuales. Es por eso que la salida de<code>/proc/cpuinfo</code>muestra dos cpus.</p>
<p>Ahora sí, vamos a la guía.</p>
<p><span id="more-731"></span></p>
<h3>Preparando el instalador</h3>
<p>El boot del instalador lo hice a través de la red, mediante un servidor <a href="http://en.wikipedia.org/wiki/Preboot_Execution_Environment" title="Preboot eXecution Environment" class="wikipedia">PXE</a> que armé en otra máquina. En realidad PXE no es un único servicio sino varios que en conjunto crean el entorno para que el boot remoto sea posible. Los servicios que lo componen son <a href="http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol" title="Dynamic Host Configuration Protocol" class="wikipedia">DHCP</a>, <a href="http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol" title="Trivial File Transfer Protocol" class="wikipedia">TFTP</a> e <a href="http://en.wikipedia.org/wiki/Inetd" title="InterNET Daemon" class="wikipedia">inetd</a> (o xinetd). Hay muchas guías por ahí para hacer esto: <a href="http://www.debian.org/releases/etch/i386/ch04s06.html.en" title="Preparing Files for TFTP Net Booting" class="external">1</a>, <a href="http://www.debian-administration.org/articles/478" title="Setting up a server for PXE network booting" class="external">2</a>, <a href="http://andys.org.uk/wiki/Guide:PXE_network_booting_Debian_install" title="PXE network booting Debian install" class="external">3</a>. Aquí va la receta que yo usé:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace"># apt-get install tftpd tftp dhcp3-server</div></div>
<p>En el archivo<code>/etc/dhcp3/dhcpd.conf</code>agregar lo siguiente:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">group {<br />
&nbsp; allow bootp;<br />
&nbsp; next-server 192.168.1.2;<br />
&nbsp; &nbsp; filename &quot;pxelinux.0&quot;;<br />
&nbsp; &nbsp; host samsung-n210 {<br />
&nbsp; &nbsp; &nbsp; &nbsp; hardware ethernet 00:24:54:76:EC:08;<br />
&nbsp; &nbsp; &nbsp; &nbsp; fixed-address 192.168.1.10;<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>Donde<code>192.168.1.2</code>es la IP del servidor que tiene el servidor TFTP.<code>00:24:54:76:EC:08</code>es la MAC address de la netbook y<code>192.168.1.10</code>es la IP fija que se le asignará a la netbook.</p>
<p>El instalador de Debian agrega la siguiente línea a<code>/etc/inetd.conf</code>al momento de la instalación de tftpd así que ni hay que tocarlo:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /srv/tftp/</div></div>
<p>Notar que el directorio<code>/srv/tftp/</code>es el raíz del servidor TFTP y es el lugar donde se debe descomprimir el <a href="http://d-i.debian.org/daily-images/amd64/daily/netboot/" title="" class="external">instalador de Debian</a>.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace"># tar xvf netboot.tar.gz -C /srv/tftp<br />
# chown -R nobody:nogroup /srv/tftp<br />
# chmod -R 777 /srv/tftp</div></div>
<p>El funcionamiento del servidor TFTP se puede comprobar ingresando y pidiendo un archivo:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ tftp localhost<br />
tftp&gt; get version.info<br />
Received 65 bytes in 0.1 seconds</div></div>
<p>Finalmente hay que reinciar inetd, dhcp y setear la bios de la netbook para que haga el boot por la placa de red. Para no perder tiempo y poder ver cualquier error que se produzca es conveniente dejar sólo la placa de red en la secuencia de booteo.</p>
<h3>Instalación</h3>
<p>Bueno, no tengo mucho que decir acá. Yo preferí (por ansiedad) instalar el sistema base (pelado, sin X), instalar grub y finalizar; Reiniciar, cambiar la secuencia de boot y comprobar que Linux levantara correctamente.</p>
<p>Lo segundo entonces fue instalar<code>gnome-desktop-environment</code>y<code>firmware-linux-nonfree</code>y<code>network-manager-gnome</code>para la wifi.</p>
<p>El entorno gráfico levantó sin problemas y sin que tuviera que tocar nada. Out-of-the-box como le dicen.</p>
<h3>Ajuste de brillo y otras teclas rebeldes</h3>
<p>Antes de comprarme la máquina sabía que las teclas de ajuste de brillo no funcionaban pero ni bien instalé Gnome descubrí con sorpresa que sí andaban. Fue luego de un tiempo y de varios apt-get install que dejaron de funcionar. Además tampoco andaban las teclas activar/desactivar wifi, bluetooth y pantalla.</p>
<p>En la segunda guía que mencioné al principio del post cuentan que existe un proyecto llamado <a href="http://www.voria.org/forum/" title="" class="external">Linux on my Samsung</a> que lidera un tano copado llamado Fortunato Ventre y que escribió<code>samsung-tools</code>(en Python) y que sirve para darle vida a esas teclas que tanto nos angustian cuano no hacen lo que dicen hacer. El programa usa un módulo, escrito por otra gente, llamado<code>samsung_backlight</code>que se distribuye bajo el paquete <a href="http://code.google.com/p/easy-slow-down-manager/" title="" class="external">easy-slow-down-manager</a> y que según palabras de sus creadores hace lo siguiente:</p>
<blockquote><p>Easy slow down manager provides Linux users with functionality similar to &#8220;Samsung Easy Speed Up Manager&#8221;. It also allows to turn WiFi on and off.
</p></blockquote>
<p>Entonces hay que instalar primero este módulo, para lo cual necesitamos descargar el <a href="http://code.google.com/p/easy-slow-down-manager/downloads/list" title="" class="external">.deb</a> y compilarlo con los headers correspondientes al kernel que estemos usando.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace"># apt-get install linux-headers-`uname -r`<br />
# dpkg -i easy-slow-down-manager-dkms_0.13.1_all.deb</div></div>
<p>Luego de instalar el módulo, bajamos el paquete <a href="https://launchpad.net/samsung-tools" title="" class="external">samsung-tools</a> y lo compilamos también, no sin antes instalar sus dependencias.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace"># apt-get install xbindkeys dbus-python rfkill gettext<br />
# tar xzf samsung-tools-1.1.1.tar.gz<br />
# cd &nbsp;samsung-tools-1.1.1<br />
# make<br />
# make install</div></div>
<p>Las teclas de brillo deberían funcionar tras reiniciar el sistema. Si no, puede que no esté cargado el módulo. Acá dejo la salida de algunos comandos de mi sistema funcionando:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace"># modprobe -l | grep -i samsung-backlight<br />
updates/samsung-backlight/samsung-backlight.ko<br />
# lsmod | grep samsung<br />
samsung_backlight &nbsp; &nbsp; &nbsp; 2740 &nbsp;0<br />
# dmesg | grep Samsung<br />
[ &nbsp; &nbsp;4.009833] Samsung-backlight: checking for SABI support.<br />
[ &nbsp; &nbsp;4.010082] Samsung-backlight: SABI is supported (f5191)</div></div>
<h3>El TouchPad</h3>
<p>Sólo nos resta ocuparnos de este, que de movida funciona pero tiene algunas opciones ocultas que pueden ser interesantes, como el scolling circular. El TouchPad puede setearse directamente desde la consola mediante el comando<code>synclient</code>pasándole como parámetro la propiedad a modificar y su nuevo valor. Las siguientes dos líneas habilitan el scrolling horizontal:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ synclient HorizEdgeScroll=1<br />
$ synclient TouchpadOff=0</div></div>
<p>Se puede obtener un listado completo de todas las propiedades con sus valores actuales ejecutando</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ synclient -l</div></div>
<p>Lindo, pero es un poco engorroso manejarlo así (y yo quiero habilitar y setear el scrolling circular). Por suerte existe <a href="http://live.gnome.org/GPointingDeviceSettings" title="" class="external">gpointing-device-settings</a> que permite configurar el TouchPad en forma gráfica.</p>
<p><img src="http://blog.calcifer.com.ar/uploads/2010/07/GPointingDeviceSettings.png" alt="" title="GPointingDeviceSettings" width="420" height="345" class="noborder" /></p>
<p>Lamentablemente la versión actual (1.5.1-2) tiene un <a href="https://bugs.launchpad.net/ubuntu/+source/gpointing-device-settings/+bug/489830" title="Settings of gpointing-device-settings are non-persistent" class="external">bug conocido</a> que no persiste los cambios al salir de la sesión. Seguramente lo arreglarán pronto. Mientras tanto se me ocurrió lo siguiente: setear todas las propiedades con gpointing-device-settings, recolectar el estado completo con synclient -l y generar un .sh que se ejecute al inicio de la sesión:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ synclient -l | awk '{if(NR==1)print &quot;#!/bin/bash&quot;;else print &quot;synclient &quot; $1 $2 $3}' &gt; touchpad-settings.sh &amp;&amp; chmod u+x touchpad-settings.sh</div></div>
<p>Sólo queda añadir<code>touchpad-settings.sh</code>al listado de aplicaciones que se ejecutan al iniciar la sesión de Gnome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2010/07/debian-squeeze-en-samsung-n210/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Reemplazo de discos en RAID con mdadm</title>
		<link>http://blog.calcifer.com.ar/2010/06/reemplazo-de-discos-en-raid-con-mdadm/</link>
		<comments>http://blog.calcifer.com.ar/2010/06/reemplazo-de-discos-en-raid-con-mdadm/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 03:05:28 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[gnu/linux]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=692</guid>
		<description><![CDATA[Hace unos días hice mi segundo reemplazo completo de discos de un array MD y quería compartir aquí los pasos que he utilizado (con éxito :D) en ambos casos.
Los dos escenarios fueron similares: dos discos iguales, con iguales particiones y RAID-1 que deben ser reemplazados por otros dos discos iguales pero de mayor tamaño, por [...]]]></description>
			<content:encoded><![CDATA[<p>Hace unos días hice mi segundo reemplazo completo de discos de un array <a href="http://linux.die.net/man/4/md" class="external">MD</a> y quería compartir aquí los pasos que he utilizado (con éxito :D) en ambos casos.</p>
<p>Los dos escenarios fueron similares: dos discos iguales, con iguales particiones y <a href="http://es.wikipedia.org/wiki/RAID#RAID_1_.28Data_Mirroring.29" class="wikipedia">RAID-1</a> que deben ser reemplazados por otros dos discos iguales pero de mayor tamaño, por lo que el procedimiento fue el mismo en ambos casos.</p>
<p>Para simplificar la guía decidí usar discos con sólo tres particiones: una para<code>/</code>, una para<code>/var</code>y otra para<code>swap</code>(que no está en RAID). El esquema entonces queda definido de la siguiente manera:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">sda (grub) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RAID's 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sdb (grub)<br />
+------------------+ &nbsp; &nbsp; +-----------------+ &nbsp; &nbsp; +------------------+<br />
| /dev/sda1 &nbsp; &nbsp; &nbsp; &nbsp;|-----| /dev/md0 (/) &nbsp; &nbsp;|-----| /dev/sdb1 &nbsp; &nbsp; &nbsp; &nbsp;|<br />
+------------------+ &nbsp; &nbsp; +-----------------+ &nbsp; &nbsp; +------------------+<br />
| /dev/sda2 &nbsp; &nbsp; &nbsp; &nbsp;|-----| /dev/md1 (/var) |-----| /dev/sdb2 &nbsp; &nbsp; &nbsp; &nbsp;|<br />
+------------------+ &nbsp; &nbsp; +-----------------+ &nbsp; &nbsp; +------------------+<br />
| /dev/sda3 (swap) | &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | /dev/sdb3 (swap) |<br />
+------------------+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +------------------+</div></div>
<p>Los discos que se usarán para reemplazo son<code>sdc</code>y<code>sdd</code>.</p>
<p><strong>NOTA:</strong> En la guía sólo se muestra el reemplazo completo de sda por sdc ya que el procedimiento para reemplazar sdb por sdd es el mismo.</p>
<h3>1. Particionado de disco</h3>
<p>La manera sencilla de copiar la tabla de particiones de una unidad a otra es:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">papua:~<span class="co0"># sfdisk -d /dev/sda | sfdisk /dev/sdc</span></div></div>
<p>Esto copia completamente el esquema del disco origen (sda) al disco destino (sdc). Si el destino es mayor simplemente quedará espacio libre (sin asignar) al final del disco.</p>
<h3>2. Reemplazo de particiones en arrays</h3>
<p><strong>TIP:</strong> Es útil tener visible, en otra terminal y durante todo el proceso, la salida de<code>/proc/mdstat</code>para visualizar en todo momento el estado del array y poder ver el sincronizado de los discos:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">papua:~<span class="co0"># watch -t cat /proc/mdstat</span></div></div>
<p><span id="more-692"></span><br />
Ahora sí, empecemos por el RAID sobre el que está montado<code>/var</code>y quitemos<code>sda2</code>:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">papua:~<span class="co0"># mdadm /dev/md1 --fail /dev/sda2</span><br />
mdadm: <span class="kw1">set</span> <span class="sy0">/</span>dev<span class="sy0">/</span>sda2 faulty <span class="kw1">in</span> <span class="sy0">/</span>dev<span class="sy0">/</span>md1<br />
<br />
papua:~<span class="co0"># mdadm /dev/md1 --remove /dev/sda2</span><br />
mdadm: hot removed <span class="sy0">/</span>dev<span class="sy0">/</span>sda2</div></div>
<p>La salida de<code>/proc/mdstat</code>debería mostrar con<code>U_</code>el array degradado:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">papua:~<span class="co0"># cat /proc/mdstat </span><br />
Personalities : <span class="br0">&#91;</span>raid1<span class="br0">&#93;</span> <br />
md1 : active raid1 sdb2<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; <span class="nu0">14651200</span> blocks <span class="br0">&#91;</span><span class="nu0">2</span><span class="sy0">/</span><span class="nu0">1</span><span class="br0">&#93;</span> <span class="br0">&#91;</span>U_<span class="br0">&#93;</span><br />
<br />
md0 : active raid1 sdb1<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> sda1<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; <span class="nu0">29294400</span> blocks <span class="br0">&#91;</span><span class="nu0">2</span><span class="sy0">/</span><span class="nu0">2</span><span class="br0">&#93;</span> <span class="br0">&#91;</span>UU<span class="br0">&#93;</span></div></div>
<p>Ahora agreguemos<code>sdc2</code>:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">papua:~<span class="co0"># mdadm /dev/md1 --add /dev/sdc2</span><br />
mdadm: added <span class="sy0">/</span>dev<span class="sy0">/</span>sdc2</div></div>
<p>Esperamos a que la sincronización termine (nuevamente ver la salida de /proc/mdstat) y hacemos lo mismo para<code>/</code>: repetimos completo el punto 2 cambiando sda2 por sda1 y sdc2 por sdc1.</p>
<h3>4. Instalación de GRUB</h3>
<p>Instalaremos grub en el MBR de<code>sdc</code>para que el sistema pueda bootear con cualquiera de los discos del array. Agregamos una entrada para el nuevo disco en el archivo<code>/boot/grub/device.map</code>:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw3">echo</span> <span class="st_h">'(hd2) &nbsp; &nbsp; /dev/sdc'</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>boot<span class="sy0">/</span>grub<span class="sy0">/</span>device.map</div></div>
<p>Luego procedemos a la instalación:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">papua:~<span class="co0"># grub --device-map=/boot/grub/device.map</span><br />
grub<span class="sy0">&gt;</span> root <span class="br0">&#40;</span>hd2,<span class="nu0">0</span><span class="br0">&#41;</span><br />
root <span class="br0">&#40;</span>hd2,<span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp;Filesystem <span class="kw3">type</span> is reiserfs, partition <span class="kw3">type</span> 0xfd<br />
grub<span class="sy0">&gt;</span> setup <span class="br0">&#40;</span>hd2<span class="br0">&#41;</span><br />
setup <span class="br0">&#40;</span>hd2<span class="br0">&#41;</span><br />
...<br />
grub<span class="sy0">&gt;</span> quit</div></div>
<h3>5. Reemplazo de swap</h3>
<p>Seteamos la partición:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">papua:~<span class="co0"># mkswap /dev/sdc3</span><br />
Setting up swapspace version <span class="nu0">1</span>, <span class="kw2">size</span> = <span class="nu0">10001936</span> kB<br />
no label, <span class="re2">UUID</span>=b00c3665-151b-4a16-ba57-e0c032f14520</div></div>
<p>Desmontamos la swap de<code>sda3</code>y la montamos en<code>sdc3</code>:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">papua:~<span class="co0"># swapoff /dev/sda3</span><br />
papua:~<span class="co0"># swapon /dev/sdc3</span></div></div>
<p>También es necesario modificar<code>/etc/fstab</code>para que la swap sea correctamente montada al reiniciar el equipo:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">UUID=b00c3665-151b-4a16-ba57-e0c032f14520 &nbsp;none &nbsp;swap &nbsp;sw &nbsp; 0 &nbsp; &nbsp;0</div></div>
<p>Recordar que el<code>UUID</code>debe ser el que nos devuelva la salida de<code>mkswap</code>, aunque también puede averiguarse mediante</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">ls</span> <span class="re5">-l</span> <span class="sy0">/</span>dev<span class="sy0">/</span>disk<span class="sy0">/</span>by-uuid<span class="sy0">/</span> <span class="sy0">|</span> <span class="kw2">grep</span> sdc3</div></div>
<h3>6. Fin</h3>
<p>Eso es todo. Para remover el otro disco repetimos los pasos del 1 al 5 reemplazando sda por sdb, sdc por sdd y hd2 por hd3.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2010/06/reemplazo-de-discos-en-raid-con-mdadm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sincronizar Motorola Q y Evolution con SynCE y MultiSync en Ubuntu Jaunty</title>
		<link>http://blog.calcifer.com.ar/2009/09/sincronizar-motorola-q-y-evolution/</link>
		<comments>http://blog.calcifer.com.ar/2009/09/sincronizar-motorola-q-y-evolution/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 13:27:38 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[gnu/linux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=465</guid>
		<description><![CDATA[Para sincronizar contactos, calendario y tareas entre un Motorola Q y Evolution se necesitan dos programas: SynCE y MultiSync.
Como dice el sitio web de SynCE, el objetivo del proyecto es proporcionar un medio de comunicación entre un dispositivo con Windows Mobile y un equipo con Linux, *BSD u otro UNIX, mediante una conexión USB o [...]]]></description>
			<content:encoded><![CDATA[<p>Para sincronizar contactos, calendario y tareas entre un <a href="http://www.motorola-rm.com/motoq/es/q-home.asp" class="external">Motorola Q</a> y <a href="http://projects.gnome.org/evolution/" class="external">Evolution</a> se necesitan dos programas: SynCE y MultiSync.</p>
<p>Como dice el <a href="http://www.synce.org/moin/" class="external">sitio web de SynCE</a>, el objetivo del proyecto es proporcionar un medio de comunicación entre un dispositivo con Windows Mobile y un equipo con Linux, *BSD u otro UNIX, mediante una conexión USB o Bluetooth. Esto permite utilizar la PC para navegar el sistema de archivos del teléfono e instalar aplicaciones y proporciona el medio de comunicación para que mediante otro programa (MultiSync) sea posible sincronizar contactos, calendario y tareas entre el teléfono y una aplicación <a href="http://en.wikipedia.org/wiki/Personal_information_management" class="wikipedia">PIM</a> de escritorio como Evolution.</p>
<p><a href="http://multisync.sourceforge.net/news.php" class="external">MultiSync</a> es una herramienta de software libre que sincroniza calendarios, libretas de direcciones y otra información PIM, entre programas de una PC o de otras PC, dispositivos móviles o teléfonos móviles. Depende del framework de desarrollo <a href="http://opensync.org/" class="external">OpenSync</a>.</p>
<p><span id="more-465"></span><br />
El primer paso entonces será instalar SynCE y comprobar que la conexión sea exitosa.</p>
<h3>1. Instalación de SynCE</h3>
<p>Agregar los siguientes repositorios a<code>/etc/apt/sources.list</code></p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">deb http://ppa.launchpad.net/synce/ubuntu jaunty main<br />
deb-src http://ppa.launchpad.net/synce/ubuntu jaunty main</div></div>
<p>Importar la clave pública</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">sudo apt-key adv --recv-keys --keyserver subkeys.pgp.net 7D2C7A23BF810CD5</div></div>
<p>Actualizar la lista de paquetes e instalar los necesarios para SynCE</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">sudo apt-get udpate<br />
sudo apt-get install synce-hal librra-tools librapi2-tools</div></div>
<p><strong>TIP:</strong> Desinstalar<code>odccm</code>en caso de estar instalado. Dejar solo<code>synce-hal</code>.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">sudo apt-get remove odccm</div></div>
<p>Antes de conectar el teléfono hay que deshabilitarle la opción <strong>&#8220;Enable advanced network funcionality&#8221;</strong> que se encuentra en Start / Settings / Connections / USB to PC.</p>
<p>Al conectar el teléfono es conveniente mirar la entrada de<code>/var/log/messages</code>ya que brinda información que puede ser útil para resolver problemas:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ tail -f /var/log/messages<br />
...<br />
[ 5082.864026] usb 2-2: new full speed USB device using uhci_hcd and address 3<br />
[ 5083.068779] usb 2-2: configuration #1 chosen from 1 choice <br />
[ 5083.071136] ipaq 2-2:1.0: PocketPC PDA converter detected <br />
[ 5083.106975] usb 2-2: PocketPC PDA converter now attached to ttyUSB0</div></div>
<p>La última línea indica que el teléfono ha sido conectado al dispositivo<code>/dev/ttyUSB0</code>. Este dispositivo se crea cuando se detecta la conexión. Si no se crea es probable que no esten cargados los módulos<code>usbserial</code>e<code>ipaq</code>. Chequear esto mediante<code>lsmod | grep ipaq</code>. (más info <a href="http://www.kernel.org/doc/Documentation/usb/usb-serial.txt" class="external">aquí</a>).</p>
<p>La conexión se prueba con siguiente comando</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">synce-pls</div></div>
<p>Si la conexión se ha establecido correctamente el comando devolverá el listado de archivos del directorio raíz del teléfono. En caso contrario hay que revisar los pasos anteriores, reiniciar el servicio hal (<code>sudo /etc/init.d/hal restart</code>) y reconectar el teléfono. Una herramienta que brinda información sobre las conexiones USB es<code>lsusb</code>(con la opción -v muestra información aun más detallada).</p>
<h4>Integración con Gnome</h4>
<p>Hay dos herramientas que son útiles para ver el estado del teléfono (conexión, carga de la batería, memoria utilizada, programas instalados, etc.) y navegar por su estructura de directorios utilizando <a href="http://live.gnome.org/Nautilus">Nautilus</a>.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">sudo apt-get install synce-trayicon synce-gvfs</div></div>
<p><strong>TIP:</strong> Luego de instalar<code>synce-gvfs</code>es necesario reiniciar el equipo.</p>
<h3>2. Instalación de MultiSync</h3>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">apt-get install multisync-tools opensync-plugin-synce synce-sync-engine opensync-plugin-evolution</div></div>
<p>Para que la sincronización pueda llevarse a cabo es necesario crear una asociación (partnership) entre el teléfono y Evolution. Hay al menos dos formas de hacer esto. Una es en forma gráfica utilizando<code>SynCE-Trayicon</code>y la otra es desde línea de comandos:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">synce-create-partnership &quot;Linux desktop&quot; &quot;Contacts,Calendar,Tasks&quot;</div></div>
<p>Ahora es necesario crear un grupo y asociar a él los dos plugins previamente instalados:<code>synce-opensync-plugin</code>y<code>evo2-sync</code>. Se puede comprobar que efectivamente se encuentren instalados utilizando<code>msynctool --listplugins</code>.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">msynctool --addgroup synce-sync<br />
msynctool --addmember synce-sync synce-opensync-plugin<br />
msynctool --addmember synce-sync evo2-sync</div></div>
<h4>Sincronizando datos</h4>
<p>En este punto ya es posible sincronizar datos ejecutando</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">msynctool --sync synce-sync</div></div>
<h3>Referencias</h3>
<ul>
<li><a href="http://www.synce.org/moin/SynceInstallation/Ubuntu/ModernDevice" class="external">SynCE with Windows Mobile 5/6/6.1 on Ubuntu</a></li>
<li><a href="http://www.kernel.org/doc/Documentation/usb/usb-serial.txt" class="external">Kernel.org: USB-Serial</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/09/sincronizar-motorola-q-y-evolution/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>umask</title>
		<link>http://blog.calcifer.com.ar/2009/08/umask/</link>
		<comments>http://blog.calcifer.com.ar/2009/08/umask/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 04:38:27 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[*N?X]]></category>
		<category><![CDATA[gnu/linux]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=451</guid>
		<description><![CDATA[Umask (user mask) es un número octal que UNIX utiliza para determinar qué permisos NO asignar automáticamente a los nuevos archivos y directorios creados. Umask sólo restringe permisos; no concede permisos adicionales más allá de lo especificado por defecto.
La mayoría de los sistemas UNIX especifican el valor octal 666 (rw-rw-rw-) para la creación de archivos [...]]]></description>
			<content:encoded><![CDATA[<p>Umask (user mask) es un número octal que UNIX utiliza para determinar qué permisos NO asignar automáticamente a los nuevos archivos y directorios creados. Umask sólo restringe permisos; no concede permisos adicionales más allá de lo especificado por defecto.</p>
<p>La mayoría de los sistemas UNIX especifican el valor octal 666 (rw-rw-rw-) para la creación de archivos y el valor octal 777 (rwxrwxrwx) para la creación de directorios. Luego, el kernel utiliza el valor de umask asignado al usuario como máscara para quitar permisos a los definidos por defecto. Todo proceso tiene su umask, heredado del proceso padre del cual desciende.</p>
<p>Los valores más comunes para umask son 022, 027 y 077.<br />
Normalmente el valor de umask se define en /etc/profile</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co0"># Set the user's umask</span><br />
<span class="kw3">umask</span> 022</div></div>
<p>aunque es posible setearlo en algún archivo de sesión como ~/.bash_profile, e incluso manualmente para la sessión actual. En todos los casos se utiliza el comando umask que es una función interna de Bash, y de otros shells como ksh y csh. (Si umask fuera un programa separado del shell no podríamos cambiar el valor de umask del proceso shell actual).</p>
<h3>Cálculo de permisos</h3>
<p>Los permisos de creación se obtienen realizando un AND binario entre el permiso por defecto y el complemento unario (NOT binario) de umask:</p>
<p>Suponiendo que quisiéramos averiguar los permisos de creación de archivos y directorios para umask 027:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">permisos archivos: &nbsp; &nbsp;666 &amp; ~027<br />
permisos directorios: 777 &amp; ~027</div></div>
<p>Recordemos que el complemento unario puede obtenerse fácilmente reemplazando ceros por unos y unos por ceros:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">Complemento unario:<br />
&nbsp;027 = 000 010 111<br />
~027 = 111 101 000</div></div>
<p>Luego de obtener el complemento unario se procede a realizar el AND binario:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">Archivos:<br />
&nbsp;666 = 110 110 110<br />
~027 = 111 101 000<br />
------------------<br />
&nbsp;640 = 110 100 000 &nbsp;&lt;-- (rw-r-----)</div></div>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">Directorios:<br />
&nbsp;777 = 111 111 111<br />
~027 = 111 101 000<br />
------------------<br />
&nbsp;750 = 111 101 000 &nbsp;&lt;-- (rwxr-x---)</div></div>
<h3>En bash</h3>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ <span class="kw3">umask</span> 027<br />
$ <span class="kw2">mkdir</span> foo<br />
$ <span class="kw2">touch</span> bar<br />
$ <span class="kw2">ls</span> <span class="re5">-l</span><br />
drwxr-x--- &nbsp;<span class="nu0">2</span> xleo xleo &nbsp; &nbsp;<span class="nu0">48</span> <span class="nu0">2009</span>-08-<span class="nu0">19</span> 01:09 foo<br />
<span class="re5">-rw-r-----</span> &nbsp;<span class="nu0">1</span> xleo xleo &nbsp; &nbsp; <span class="nu0">0</span> <span class="nu0">2009</span>-08-<span class="nu0">19</span> 01:<span class="nu0">10</span> bar</div></div>
<h3>Referencias</h3>
<ul>
<li><a href="http://www.gnu.org/software/libc/manual/html_node/Setting-Permissions.html" class="external">gnu.org &#8211; Assigning File Permissions</a></li>
<li><a href="http://docstore.mik.ua/orelly/networking/puis/ch05_03.htm" class="external">Practical UNIX &#038; Internet Security &#8211; umask</a></li>
<li><a href="http://en.wikipedia.org/wiki/Umask" class="external">Wikipedia &#8211; umask</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/08/umask/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tiempos de ejecución de un proceso</title>
		<link>http://blog.calcifer.com.ar/2009/04/tiempos-de-ejecucion-de-un-proceso/</link>
		<comments>http://blog.calcifer.com.ar/2009/04/tiempos-de-ejecucion-de-un-proceso/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 15:32:10 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[gnu/linux]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=404</guid>
		<description><![CDATA[Traducción de What do ‘real’, ‘user’ and ‘sys’ mean in the output of time?
$ time foo
real &#160;0m13.520s 
user &#160;0m1.628s
sys &#160; 0m1.420s

Real
Tiempo real transcurrido desde que el proceso comienza hasta que finaliza. Esto implica el tiempo utilizado por otros procesos ejecutándose al mismo tiempo y el tiempo en que el proceso se encuentra bloquedo (por ejemplo, [...]]]></description>
			<content:encoded><![CDATA[<p class="from">Traducción de <a href="http://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1/556411" class="external">What do ‘real’, ‘user’ and ‘sys’ mean in the output of time?</a></p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">$ <span class="kw1">time</span> foo<br />
real &nbsp;0m13.520s <br />
user &nbsp;0m1.628s<br />
sys &nbsp; 0m1.420s</div></div>
<dl>
<dt>Real</dt>
<dd>Tiempo real transcurrido desde que el proceso comienza hasta que finaliza. Esto implica el tiempo utilizado por otros procesos ejecutándose al mismo tiempo y el tiempo en que el proceso se encuentra bloquedo (por ejemplo, esperando que una llamada al sistema como I/O se complete).</dd>
<dt>User</dt>
<dd>Tiempo de CPU empleado por el proceso en modo usuario (fuera del núcleo). El tiempo de CPU de otros procesos y el tiempo de espera de una llamada al sistema no cuentan en este valor.</dd>
<dt>Sys</dt>
<dd>Tiempo empleado por el núcleo para atender peticiones del proceso. Esto significa tiempo de uso de CPU en llamadas al sistema dentro del núcleo, como por ejemplo I/O.</dd>
</dl>
<p><strong>User+Sys</strong> equivale al total de tiempo de CPU usado por el proceso.</p>
<p><span id="more-404"></span></p>
<h4>Diferencia entre &#8216;Kernel mode&#8217; y &#8216;User mode&#8217;</h4>
<p>En Unix, o cualquier otro sistema operativo de memoria protegida, &#8216;Kernel&#8217; o &#8216;Supervisor&#8217; es el modo privilegiado en que la CPU puede operar. Ciertas acciones que pueden afectar la seguridad o estabilidad del sistema solo pueden ser realizadas cuando la CPU funciona en este modo. Estas acciones no están disponibles para aplicaciones de usuario. Un ejemplo de este tipo de acciones podría ser la de manipular la <a href="http://en.wikipedia.org/wiki/Memory_management_unit" class="wikipedia">MMU</a> para tener acceso al espacio de direcciones de otro proceso. Normalmente, el código en modo usuario no puede hacer esto, aunque puede solicitar memoria compartida desde el Kernel, la que podría ser leída y escrita por más de un proceso. En este caso la memoria compartida es solicitada explícitamente por el Kernel a través de un mecanismo seguro y los diferentes procesos pueden utilizarla mediante llamadas también explícitas.</p>
<p>El modo privilegiado es generalmente denominado &#8216;Kernel mode&#8217; debido a que es el núcleo el ejecutado por la CPU cuando se ejecuta en este modo.</p>
<p>Las llamadas al sistema en la librería C (particularmente aquellas que se describen en la sección 2 de las páginas man) tienen un componente en modo usuario, que es el que realmente hace la llamada desde el programa. Una página que describe el sistema de llamadas proporcionadas por el núcleo Linux puede encontrarse <a href="http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html" class="external">aquí</a>.</p>
<h4>Aclaración acerca de Sys time</h4>
<p>Hay ciertas cosas que el código de usuario no puede hacer. Asignar memoria o acceder a un hardware (HDD, red, etc) solo pueden hacerse bajo supervisión del núcleo, y sólo él puede hacerlo. Algunas operaciones como<code>malloc</code>o<code>fread/fwrite</code>, invocarán esta supervisión del núcleo y entonces contarán como &#8216;Sys time&#8217;. Desafortunadamente no es tan sencillo como &#8220;cada llamada a malloc será contada como Sys time&#8221;. Una llamada a malloc pasa cierto tiempo procesando su componente de modo usuario (entonces contará como &#8216;User time&#8217;), luego invocará la función del núcleo (lo que contará como &#8216;Sys time&#8217;) y finalmente, cuando retome el control luego de la llamada al sistema, usará probablemente algo más de tiempo de usuario (que contará como &#8216;User time&#8217;).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/04/tiempos-de-ejecucion-de-un-proceso/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GNU gettext con php5</title>
		<link>http://blog.calcifer.com.ar/2009/03/gnu-gettext-con-php5/</link>
		<comments>http://blog.calcifer.com.ar/2009/03/gnu-gettext-con-php5/#comments</comments>
		<pubDate>Sat, 21 Mar 2009 17:55:06 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[gnu/linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=226</guid>
		<description><![CDATA[
GNU gettext es la biblioteca GNU de internacionalización (i18n) y es usada para escribir programas con interfaz en múltiples idiomas.
wikipedia
La internacionalización es el proceso de diseñar software de manera tal que pueda adaptarse a diferentes idiomas y regiones sin necesidad de cambios de ingeniería ni de código. La localización es el proceso de adaptar el [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.calcifer.com.ar/uploads/2009/03/gnu-head-sm.jpg" alt="gnu-head-sm" title="gnu-head-sm" width="129" height="122" class="alignright size-full wp-image-231" /></p>
<p><a href="http://www.gnu.org/software/gettext/gettext.html" class="wikipedia">GNU gettext</a> es la biblioteca <a href="http://es.wikipedia.org/wiki/GNU" class="wikipedia">GNU</a> de <a href="http://es.wikipedia.org/wiki/Internacionalizaci%C3%B3n_(computaci%C3%B3n)" class="wikipedia">internacionalización</a> (i18n) y es usada para escribir programas con interfaz en múltiples idiomas.</p>
<p><a href="http://es.wikipedia.org/wiki/Internacionalizaci%C3%B3n_(computaci%C3%B3n)" class="wikipedia">wikipedia</a></p>
<blockquote title="wikipedia.org"><p>La internacionalización es el proceso de diseñar software de manera tal que pueda adaptarse a diferentes idiomas y regiones sin necesidad de cambios de ingeniería ni de código. La localización es el proceso de adaptar el software para una región específica mediante la adición de componentes específicos de un locale y la traducción de los textos, por lo que también se le puede denominar regionalización.<br />
&#8230;<br />
Es una práctica común en el idioma inglés (sobre todo en el ámbito de la computación), abreviar internationalization como &#8220;i18n&#8221;. Ello se debe a que entre la primera i y la última n de dicha palabra hay 18 letras. Lo mismo sucede con localization, que se abrevia &#8220;L10n&#8221;.
</p></blockquote>
<h3>gettext en PHP</h3>
<p>Existen dos formas de usar gettext en PHP: mediante la <a href="http://ar2.php.net/manual/en/book.gettext.php" class="external">extensión gettext nativa de PHP</a> o utilizando la librería <a href="http://savannah.nongnu.org/projects/php-gettext/" class="external">PHP-gettext</a>, escrita en PHP, que no necesita ninguna extensión.</p>
<p>La forma de usar gettext es</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"># @file: index.php<br />
<span class="kw2">&lt;?php</span><br />
<a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/_"><span class="kw3">_</span></a><span class="br0">&#40;</span><span class="st0">&quot;hello world&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div></td></tr></tbody></table></div>
<p>La función<code>_()</code>, alias de<code>gettext()</code>, devolverá la cadena &#8220;hello world&#8221; en el lenguaje correspondiente, de acuerdo al <a href="http://en.wikipedia.org/wiki/Locale" class="wikipedia">locale</a> que hayamos seleccionado.</p>
<p>Si ejecutamos el script obtendremos &#8220;hello world&#8221; como salida, puesto que no hemos indicado ningún locale, ni creado ningún catálogo de traducción. Necesitamos crear el archivo<code>comments.po</code>con la traducción de la cadena &#8220;hello world&#8221;. Esto puede hacerse mediante el comando<code>xgettext</code>, o mediante un editor gráfico como <a href="http://www.poedit.net/" class="external">poEdit</a>.</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">apt-get</span> <span class="kw2">install</span> poedit</div></div>
<h3>Creación del catálogo con poEdit</h3>
<p>Ante todo debemos saber que la estructura de directorios para guardar los distintos catálogos tiene forma determinada. Por cada traducción se utiliza un directorio. Este generalmente se nombra usando dos letras minúsculas para el idioma, un guión bajo y dos mayúsculas para el país (es_AR, para español de Argentina). Dentro de este directorio debe existir otro con el nombre LC_MESSAGES, el cual será finalmente el directorio que contendrá el catálogo.</p>
<p>La estructura de nuestro ejemplo será</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">.<br />
<span class="sy0">|</span>-- locale<br />
<span class="sy0">|</span> &nbsp; <span class="sy0">`</span>-- es_AR<br />
<span class="sy0">|</span> &nbsp; &nbsp; &nbsp; <span class="sy0">`</span>-- LC_MESSAGES<br />
<span class="sy0">|</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">|</span>-- messages.mo<br />
<span class="sy0">|</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">`</span>-- messages.po<br />
<span class="sy0">`</span>-- index.php</div></div>
<p>El archivo<code>messages.mo</code>es la versión compilada de<code>messages.po</code>y el que usará PHP para obtener la traducción.</p>
<p>Iniciemos poEdit. La primera vez nos preguntará por nuestro nombre y correo electrónico. Estos datos servirán para saber quién fue el último traductor que modificó el catálogo. Una vez en la ventana principal vamos a File -> New catalog. Seleccionamos el idioma (Español en este caso), el país y el código de caracteres tanto para el catálogo como para la fuente de datos desde la que obtendremos el listado de cadenas que requieren traducción. En la solapa Paths debemos colocar en &#8216;Base path&#8217; la ruta completa al directorio base de archivos php (conteniendo las cadenas mencionadas anteriormente) y, debajo, en el cuadro &#8216;Paths&#8217; agregar una entrada con &#8216;.&#8217; indicando que se debe utilizar el directorio ingresado anteriormente. Al hacer click en OK aparecerá un cuadro de diálogo para guardar el nuevo catálogo. Navegamos hasta el directorio LC_MESSAGES y guardamos el archivo como messages.po. poEdit escaneará el directorio ingresado en Paths y extraerá todos las cadenas gettext. Ahora queda simplemente realizar la traducción y guardar el archivo. Al guardarlo, poEdit lo compilará y generará el .mo que finalmente usará PHP.</p>
<p>Ahora, modificaremos index.php para setear el locale</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"># @file: index.php<br />
<span class="kw2">&lt;?php</span><br />
<span class="re0">$language</span> <span class="sy0">=</span> <span class="st_h">'es_AR.UTF-8'</span><span class="sy0">;</span><br />
<a href="http://www.php.net/putenv"><span class="kw3">putenv</span></a><span class="br0">&#40;</span><span class="st0">&quot;LANG=<span class="es4">$language</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
<a href="http://www.php.net/setlocale"><span class="kw3">setlocale</span></a><span class="br0">&#40;</span>LC_ALL<span class="sy0">,</span> <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="re0">$domain</span> <span class="sy0">=</span> <span class="st0">&quot;messages&quot;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/bindtextdomain"><span class="kw3">bindtextdomain</span></a><span class="br0">&#40;</span><span class="re0">$domain</span><span class="sy0">,</span> <span class="st0">&quot;./locale&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/bind_textdomain_codeset"><span class="kw3">bind_textdomain_codeset</span></a><span class="br0">&#40;</span><span class="re0">$domain</span><span class="sy0">,</span> <span class="st_h">'UTF-8'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/textdomain"><span class="kw3">textdomain</span></a><span class="br0">&#40;</span><span class="re0">$domain</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/_"><span class="kw3">_</span></a><span class="br0">&#40;</span><span class="st0">&quot;hello world&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div></td></tr></tbody></table></div>
<p>Aun nos queda un paso y es comprobar que tengamos dicho locale habilitado en nuestro sistema. Esto lo hacemos mirando la salida de</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">locale <span class="re5">-a</span></div></div>
<p>Si no tenemos habilitado el charset es_AR.UTF8, ejecutamos</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">locale-gen es_AR.UTF-<span class="nu0">8</span></div></div>
<p>En este punto la salida del script debería ser la traducción que hicimos al español.</p>
<h3>Tip</h3>
<p>Para casos en que la cadena a traducir contenga variables, podemos utilizar esta función:</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> __<span class="br0">&#40;</span><span class="re0">$string</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$arg</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">1</span> <span class="sy0">;</span> <span class="re0">$i</span> <span class="sy0">&lt;</span> <a href="http://www.php.net/func_num_args"><span class="kw3">func_num_args</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$arg</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <a href="http://www.php.net/func_get_arg"><span class="kw3">func_get_arg</span></a><span class="br0">&#40;</span><span class="re0">$i</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/vsprintf"><span class="kw3">vsprintf</span></a><span class="br0">&#40;</span><a href="http://www.php.net/gettext"><span class="kw3">gettext</span></a><span class="br0">&#40;</span><span class="re0">$string</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$arg</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="re0">$total</span> <span class="sy0">=</span> <span class="nu0">400</span><span class="sy0">;</span><br />
<a href="http://www.php.net/print"><span class="kw3">print</span></a> __<span class="br0">&#40;</span><span class="st0">&quot;results <span class="es6">%d</span> - <span class="es6">%d</span> of about <span class="es6">%d</span>&quot;</span><span class="sy0">,</span> <span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">20</span><span class="sy0">,</span> <span class="re0">$total</span><span class="br0">&#41;</span><span class="sy0">;</span></div></td></tr></tbody></table></div>
<p>La traducción podría quedar</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">resultados %d - %d de aproximadamente %d</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/03/gnu-gettext-con-php5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compilar Kernel generando paquete .deb</title>
		<link>http://blog.calcifer.com.ar/2008/06/compilar-kernel-generando-paquete-deb/</link>
		<comments>http://blog.calcifer.com.ar/2008/06/compilar-kernel-generando-paquete-deb/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 13:23:54 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[gnu/linux]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2008/06/16/compilar-kernel-generando-paquete-deb/</guid>
		<description><![CDATA[Aquí se describe cómo compilar un Kernel en Debian Etch, generando un.debque luego podrá ser instalado usandodpkg -i.
Paquetes requeridos para la compilación
apt-get update &#38;&#38; \
apt-get install kernel-package libncurses5-dev fakeroot \
wget bzip2 build-essential
Descarga de código fuente desde kernel.org
cd /usr/src
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.25.6.tar.bz2
Desempaquetado
tar xjf linux-2.6.25.6.tar.bz2
Copia del archivo de configuración del kernel actual como base para el nuevo kernel
cp /boot/config-`uname [...]]]></description>
			<content:encoded><![CDATA[<p>Aquí se describe cómo compilar un Kernel en Debian Etch, generando un<code>.deb</code>que luego podrá ser instalado usando<code>dpkg -i</code>.</p>
<p>Paquetes requeridos para la compilación</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">apt-get</span> update <span class="sy0">&amp;&amp;</span> \<br />
<span class="kw2">apt-get</span> <span class="kw2">install</span> kernel-package libncurses5-dev fakeroot \<br />
<span class="kw2">wget</span> <span class="kw2">bzip2</span> build-essential</div></div>
<p>Descarga de código fuente desde <a href="http://www.kernel.org" class="linkexternal">kernel.org</a></p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw3">cd</span> <span class="sy0">/</span>usr<span class="sy0">/</span>src<br />
<span class="kw2">wget</span> http:<span class="sy0">//</span>www.kernel.org<span class="sy0">/</span>pub<span class="sy0">/</span>linux<span class="sy0">/</span>kernel<span class="sy0">/</span>v2.6<span class="sy0">/</span>linux-2.6.25.6.tar.bz2</div></div>
<p>Desempaquetado</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">tar</span> xjf linux-2.6.25.6.tar.bz2</div></div>
<p>Copia del archivo de configuración del kernel actual como base para el nuevo kernel</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">cp</span> <span class="sy0">/</span>boot<span class="sy0">/</span>config-<span class="sy0">`</span><span class="kw2">uname</span> -r<span class="sy0">`</span> <span class="sy0">/</span>usr<span class="sy0">/</span>src<span class="sy0">/</span>.config</div></div>
<p>Eliminación de cualquier rastro de compilación anterior</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw3">cd</span> linux-2.6.25.6<br />
<span class="kw2">make</span> clean <span class="sy0">&amp;&amp;</span> <span class="kw2">make</span> mrproper</div></div>
<p>Creación link simbólico a .config (por si repetimos la compilación)</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">ln</span> <span class="re5">-s</span> <span class="sy0">/</span>usr<span class="sy0">/</span>src<span class="sy0">/</span>.config <span class="sy0">/</span>usr<span class="sy0">/</span>src<span class="sy0">/</span>linux-2.6.25.6<span class="sy0">/</span>.config</div></div>
<p>Selección de opciones, cargando .config desde la opción &#8216;Alternate Configuration File&#8217;.</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">make</span> menuconfig</div></div>
<p>Compilación</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">make-kpkg clean<br />
fakeroot make-kpkg <span class="re5">--initrd</span> <span class="re5">--append-to-version</span>=-custom kernel_image kernel_headers</div></div>
<p>Instalación</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">dpkg</span> <span class="re5">-i</span> linux-image-2.6.25.6-custom_2.6.25.6-custom-10.00.Custom_i386.deb<br />
<span class="kw2">dpkg</span> <span class="re5">-i</span> linux-headers-2.6.25.6-custom_2.6.25.6-custom-10.00.Custom_i386.deb</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2008/06/compilar-kernel-generando-paquete-deb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Renombrar recursivamente archivos y directorios</title>
		<link>http://blog.calcifer.com.ar/2008/06/renombrar-recursivamente-archivos-y-directorios/</link>
		<comments>http://blog.calcifer.com.ar/2008/06/renombrar-recursivamente-archivos-y-directorios/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 03:50:58 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[gnu/linux]]></category>
		<category><![CDATA[recursivity]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2008/06/10/renombrar-recursivamente-archivos-y-directorios/</guid>
		<description><![CDATA[El siguiente script de bash renombra archivos y directorios convirtiendo sus nombres a minúsculas, reemplazando espacios, acentos, eñes y eliminando paréntesis.
Por defecto renombra únicamente aquellos archivos y directorios ubicados en el directorio pasado como parámetro. Es posible usar la opción-r&#124;--recursivepara que trabaje recursivamente en todos los directorios hijos:
./rename.sh -r dir
Usando la opción-v&#124;--verbosees posible ver en [...]]]></description>
			<content:encoded><![CDATA[<p>El siguiente script de bash renombra archivos y directorios convirtiendo sus nombres a minúsculas, reemplazando espacios, acentos, eñes y eliminando paréntesis.</p>
<p>Por defecto renombra únicamente aquellos archivos y directorios ubicados en el directorio pasado como parámetro. Es posible usar la opción<code>-r|--recursive</code>para que trabaje recursivamente en todos los directorios hijos:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">./rename.sh -r dir</div></div>
<p>Usando la opción<code>-v|--verbose</code>es posible ver en pantalla el listado de archivos modificados</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">./rename.sh -v -r dir</div></div>
<p>La opción<code>-t|--test</code>muestra un listado de cambios a realizar sin realizar ninguno</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">./rename.sh -t -r dir</div></div>
<h3>Ejemplo</h3>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px;height:300px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">xleo@calcifer:/tmp/music$ rename -t -r .<br />
/tmp/music/Jaime Roos/1998 - Concierto Aniversario<br />
./17 - Amándote.mp3 ./17_-_amandote.mp3<br />
./02 - Victoria Abaracón.mp3 ./02_-_victoria_abaracon.mp3<br />
./12 - Nadie Me Dijo Nada.mp3 ./12_-_nadie_me_dijo_nada.mp3<br />
./16 - Durazno Y Convención.mp3 ./16_-_durazno_y_convencion.mp3<br />
./01 - Si Me Voy Antes Que Vos-1.mp3 ./01_-_si_me_voy_antes_que_vos-1.mp3<br />
./03 - El Hombre De La Calle.mp3 ./03_-_el_hombre_de_la_calle.mp3<br />
./05 - Las Luces Del Estadio.mp3 ./05_-_las_luces_del_estadio.mp3<br />
./07 - Piropo.mp3 ./07_-_piropo.mp3<br />
./10 - Esta Noche.mp3 ./10_-_esta_noche.mp3<br />
./06 - Se Va La Murga.mp3 ./06_-_se_va_la_murga.mp3<br />
./08 - Los Futuros Murguistas.mp3 ./08_-_los_futuros_murguistas.mp3<br />
./15 - Tal Vez Cheché.mp3 ./15_-_tal_vez_cheche.mp3<br />
./13 - Bienvenido.mp3 ./13_-_bienvenido.mp3<br />
./1998 - Concierto Aniversario.m3u ./1998_-_concierto_aniversario.m3u<br />
./09 - Los Olímpicos.mp3 ./09_-_los_olimpicos.mp3<br />
./11 - Cometa De La Farola.mp3 ./11_-_cometa_de_la_farola.mp3<br />
./04 - Cuando Juega Uruguay.mp3 ./04_-_cuando_juega_uruguay.mp3<br />
./14 - El Tambor.mp3 ./14_-_el_tambor.mp3<br />
/tmp/music/Jaime Roos<br />
./1998 - Concierto Aniversario ./1998_-_concierto_aniversario<br />
/tmp/music<br />
./Jaime Roos ./jaime_roos</div></div>
<h3>rename.sh</h3>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px;height:500px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br /></div></td><td><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co0">#!/bin/bash</span><br />
<span class="co0">#</span><br />
<span class="co0"># @autor &nbsp; Leonardo Vidarte</span><br />
<span class="co0"># @version $Id rename.sh 5 2008-06-05 15:44:45Z xleo $</span><br />
<span class="co0">#</span><br />
<br />
<br />
<span class="co0"># ********</span><br />
<span class="co0"># INIT SET</span><br />
<span class="co0"># ********</span><br />
<span class="re2">verbose</span>=<span class="nu0">0</span><br />
<span class="re2">recursive</span>=<span class="nu0">0</span><br />
<span class="re2">MOVE</span>=<span class="sy0">/</span>bin<span class="sy0">/</span><span class="kw2">mv</span><br />
<span class="re2">ECHO</span>=<br />
<br />
<br />
<span class="co0"># ****</span><br />
<span class="co0"># HELP</span><br />
<span class="co0"># ****</span><br />
<span class="kw3">help</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
<span class="kw2">cat</span> <span class="co2">&lt;&lt; END<br />
Usage : rename [-t] [-v] [-r] directory<br />
<br />
Options:<br />
&nbsp; -v, --verbose &nbsp; &nbsp;verbose move<br />
&nbsp; -r, --recursive &nbsp;recursive rename<br />
&nbsp; -t, --test &nbsp; &nbsp; &nbsp; don't move, only show change list. Implies -v.<br />
&nbsp; -?, --help &nbsp; &nbsp; &nbsp; show this help<br />
<br />
END</span><br />
<span class="br0">&#125;</span><br />
<br />
<br />
<span class="co0"># ***************</span><br />
<span class="co0"># RENAME FUNCTION</span><br />
<span class="co0"># ***************</span><br />
rename <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">find</span> <span class="re5">-maxdepth</span> <span class="nu0">1</span> <span class="sy0">|</span> \<br />
&nbsp; &nbsp; <span class="kw2">awk</span> <span class="st_h">'{out=tolower($0); \<br />
&nbsp; &nbsp; gsub(&quot; ?\&amp; ?&quot;,&quot;_y_&quot;,out); \<br />
&nbsp; &nbsp; gsub(&quot;\(|\)&quot;,&quot;-&quot;,out); \<br />
&nbsp; &nbsp; gsub(&quot;[\340-\345]&quot;,&quot;a&quot;,out); \<br />
&nbsp; &nbsp; gsub(&quot;\347&quot;,&quot;c&quot;,out); \<br />
&nbsp; &nbsp; gsub(&quot;[\350-\353]&quot;,&quot;e&quot;,out); \<br />
&nbsp; &nbsp; gsub(&quot;[\354-\357]&quot;,&quot;i&quot;,out); \<br />
&nbsp; &nbsp; gsub(&quot;\361&quot;,&quot;n&quot;,out); \<br />
&nbsp; &nbsp; gsub(&quot;[\362-\366]&quot;,&quot;o&quot;,out); \<br />
&nbsp; &nbsp; gsub(&quot;[\371-\374]&quot;,&quot;u&quot;,out); \<br />
&nbsp; &nbsp; gsub(&quot;[^0-9a-z\./_-]&quot;,&quot;_&quot;,out); \<br />
&nbsp; &nbsp; if ($0!=out) {print &quot;\&quot;&quot;$0&quot;\&quot; &quot;out;}}'</span> <span class="sy0">|</span> \<br />
&nbsp; &nbsp; <span class="kw2">xargs</span> <span class="re5">-r</span> <span class="re5">-n</span> <span class="nu0">2</span> <span class="re1">$ECHO</span> <span class="re1">$MOVE</span><br />
<br />
<span class="br0">&#125;</span><br />
<br />
<br />
<span class="co0"># *************</span><br />
<span class="co0"># MAIN FUNCTION</span><br />
<span class="co0"># *************</span><br />
main <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
<br />
<br />
&nbsp; &nbsp; <span class="co0"># ----------------</span><br />
&nbsp; &nbsp; <span class="co0"># Recursive rename</span><br />
&nbsp; &nbsp; <span class="co0"># ----------------</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$recursive</span> <span class="re5">-eq</span> <span class="nu0">1</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="kw2">dir</span> <span class="kw1">in</span> <span class="st0">&quot;$1&quot;</span><span class="sy0">/*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-d</span> <span class="st0">&quot;<span class="es2">$dir</span>&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">cd</span> <span class="st0">&quot;<span class="es2">$dir</span>&quot;</span> <span class="sy0">&amp;&amp;</span> search <span class="st0">&quot;<span class="es2">$dir</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fi</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">done</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
<br />
<br />
&nbsp; &nbsp; <span class="co0"># ----------------------------</span><br />
&nbsp; &nbsp; <span class="co0"># Rename files and directories</span><br />
&nbsp; &nbsp; <span class="co0"># ----------------------------</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$verbose</span> <span class="re5">-eq</span> <span class="nu0">1</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;$1&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
<br />
&nbsp; &nbsp; <span class="kw3">cd</span> <span class="st0">&quot;$1&quot;</span> <span class="sy0">&amp;&amp;</span> rename<br />
<br />
<br />
<span class="br0">&#125;</span><br />
<br />
<br />
<span class="co0"># ***************************</span><br />
<span class="co0"># SHOW HELP WITHOUT ARGUMENTS</span><br />
<span class="co0"># ***************************</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re4">$#</span> <span class="re5">-eq</span> <span class="nu0">0</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp;<span class="kw3">help</span><br />
&nbsp; &nbsp;<span class="kw3">exit</span> <span class="nu0">1</span><br />
<span class="kw1">fi</span><br />
<br />
<br />
<span class="co0"># *********</span><br />
<span class="co0"># SHOW HELP</span><br />
<span class="co0"># *********</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span><span class="br0">&#91;</span> <span class="st0">&quot;$1&quot;</span> =~ <span class="st_h">'(-h|--help)'</span> <span class="br0">&#93;</span><span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp;<span class="kw3">help</span><br />
&nbsp; &nbsp;<span class="kw3">exit</span> <span class="nu0">0</span><br />
<span class="kw1">fi</span><br />
<br />
<br />
<span class="co0"># ***************</span><br />
<span class="co0"># CHECK ARGUMENTS</span><br />
<span class="co0"># ***************</span><br />
<span class="kw1">while</span> <span class="br0">&#91;</span> <span class="re4">$#</span> <span class="re5">-gt</span> <span class="nu0">1</span> <span class="br0">&#93;</span>; <span class="kw1">do</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&quot;$1&quot;</span> <span class="kw1">in</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; -v<span class="sy0">|</span>--verbose<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">verbose</span>=<span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">MOVE</span>=<span class="st0">&quot;<span class="es2">$MOVE</span> --verbose&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; -r<span class="sy0">|</span>--recursive<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">recursive</span>=<span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; -t<span class="sy0">|</span>--test<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">verbose</span>=<span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">MOVE</span>=<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">ECHO</span>=<span class="sy0">/</span>bin<span class="sy0">/</span><span class="kw3">echo</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">*</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> invalid argument $<span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">help</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">esac</span><br />
<br />
&nbsp; &nbsp; <span class="kw3">shift</span><br />
<br />
<span class="kw1">done</span><br />
<br />
<br />
<span class="co0"># ****************************************</span><br />
<span class="co0"># CHECK DIRECTORY AND INVOKE MAIN FUNCTION</span><br />
<span class="co0"># ****************************************</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="st0">&quot;$1&quot;</span> == <span class="st_h">'.'</span> <span class="re5">-o</span> <span class="st0">&quot;$1&quot;</span> == <span class="st_h">'*'</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="re2"><span class="kw2">dir</span></span>=<span class="re1">$PWD</span><br />
<span class="kw1">else</span><br />
&nbsp; &nbsp; <span class="re2"><span class="kw2">dir</span></span>=$<span class="nu0">1</span><br />
<span class="kw1">fi</span><br />
<br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-d</span> <span class="st0">&quot;<span class="es2">$dir</span>&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">cd</span> <span class="st0">&quot;<span class="es2">$dir</span>&quot;</span><br />
&nbsp; &nbsp; <span class="re2"><span class="kw2">dir</span></span>=<span class="re1">$PWD</span><br />
&nbsp; &nbsp; <span class="kw3">cd</span> - <span class="nu0">1</span><span class="sy0">&gt;</span> <span class="sy0">/</span>dev<span class="sy0">/</span>null<br />
&nbsp; &nbsp; main <span class="st0">&quot;<span class="es2">$dir</span>&quot;</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">0</span><br />
<span class="kw1">else</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> rename: directory not found<br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">3</span><br />
<span class="kw1">fi</span></div></td></tr></tbody></table></div>
<h3>Otro ejemplo</h3>
<p>Salida de<code>./rename -r -v /shared/music > <a href='http://blog.calcifer.com.ar/uploads/2008/06/result.txt' title='result.txt'>result.txt</a></code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2008/06/renombrar-recursivamente-archivos-y-directorios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mpd &#8211; Music Player Daemon</title>
		<link>http://blog.calcifer.com.ar/2008/05/mpd-music-player-daemon/</link>
		<comments>http://blog.calcifer.com.ar/2008/05/mpd-music-player-daemon/#comments</comments>
		<pubDate>Wed, 28 May 2008 17:08:04 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[gnu/linux]]></category>
		<category><![CDATA[music]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2008/05/24/mpd-music-player-daemon/</guid>
		<description><![CDATA[Music Player Daemon (MPD) is a music player which allows for remote access from another computer. An example is a headless computer running MPD and using one of the available front ends to control it remotely. It also makes for a good media player for desktop computers, particularly if the user either does not use [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Music Player Daemon (MPD)</strong> is a music player which allows for remote access from another computer. An example is a headless computer running MPD and using one of the available front ends to control it remotely. It also makes for a good media player for desktop computers, particularly if the user either does not use or frequently restarts X.</p>
<p>MPD does not stream audio; all playback occurs on the server where the music files are located. The remote client controls playback from a nearby location.</p>
<p>MPD uses a text file as a database in which to maintain the basic music file information when it is not running. Once the daemon is started, the database is kept completely in-memory and no hard disk access is necessary to look up or search for a song. This database does not allow arbitrary files to be added; music files must be above the music root directory and are only added to the database when the update command is sent to the server.</p>
<p>Install:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">apt-get install mpd mpc</div></div>
<p>Edit config file<code>/etc/mpd.conf</code>:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">port&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;6600&quot;<br />
music_directory &nbsp; &nbsp; &nbsp; &nbsp; &quot;~/music&quot;<br />
playlist_directory &nbsp; &nbsp; &nbsp;&quot;~/.mpd/playlists&quot;<br />
db_file &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;~/.mpd/mpd.db&quot;<br />
log_file &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;/var/log/mpd/mpd.log&quot;<br />
error_file &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;/var/log/mpd/mpd.error&quot;<br />
user &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;mpd&quot;<br />
bind_to_address &nbsp; &nbsp; &nbsp; &nbsp; &quot;192.168.0.254&quot; #only private interface</div></div>
<p>Create dir and set own:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">mkdir -p ~/music/.mpd/playlists<br />
chown -R mpd ~/music</div></div>
<p>Create DB:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">/etc/init.d/mpd restart<br />
mpd --create-db</div></div>
<p>Add all music to playlist and&#8230; play:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">mpc update<br />
mpc add /<br />
mpc play</div></div>
<h3>References</h3>
<dl>
<dt>mpd –create-db</dt>
<dd>This will start the daemon. The ‘–create-db’ argument will read the contents of the root music directory and add the Music files to a text database. You should see the list of files being added into the DB. This may take some time to complete &#8211; based on size of your music collection.</dd>
<dt>mpc update</dt>
<dd>The command used here is ‘mpc’ &#8211; not ‘mpd’. We are using a command line client now. This command scans the root music directory for updates.</dd>
<dt>mpc add /</dt>
<dd>This command will add all the files in the music directory to the current playlist. Please note that the ‘/’ here means root music directory &#8211; and not the global linux root.</dd>
<dt>mpc play</dt>
<dd>This will start playing the files in the current playlist.</dd>
</dl>
<h3>Links</h3>
<ul>
<li><a href="http://www.musicpd.org/" class="linkexternal">Music Player Daemon</a></li>
<li><a href="http://mpd.wikia.com/wiki/Main_Page" class="linkexternal">MPD Wiki</a></li>
<li><a href="http://mpd.wikia.com/wiki/Clients" class="linkexternal">MPD Wiki::Clients</a></li>
<li><a href="http://mpd.wikia.com/wiki/Music_Player_Daemon_Security">MPD Wiki::Security</a></li>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/6324" class="linkexternal">Minion &#8211; Plugin Firefox</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2008/05/mpd-music-player-daemon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bash Regular Expressions</title>
		<link>http://blog.calcifer.com.ar/2008/05/bash-regular-expressions/</link>
		<comments>http://blog.calcifer.com.ar/2008/05/bash-regular-expressions/#comments</comments>
		<pubDate>Tue, 27 May 2008 18:41:13 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[gnu/linux]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2008/05/28/bash-regular-expressions/</guid>
		<description><![CDATA[Vía www.linuxjournal.com
When working with regular expressions in a shell script the norm is to use grep or sed or some other external command/program. Since version 3 of bash (released in 2004) there is another option: bash&#8217;s built-in regular expression comparison operator &#8220;=~&#8221;.
Bash&#8217;s regular expression comparison operator takes a string on the left and an extended [...]]]></description>
			<content:encoded><![CDATA[<div class="from">Vía <a href="http://www.linuxjournal.com/content/bash-regular-expressions" class="linkexternal">www.linuxjournal.com</a></div>
<p>When working with regular expressions in a shell script the norm is to use grep or sed or some other external command/program. Since version 3 of bash (released in 2004) there is another option: bash&#8217;s built-in regular expression comparison operator &#8220;=~&#8221;.</p>
<p>Bash&#8217;s regular expression comparison operator takes a string on the left and an extended regular expression on the right. It returns 0 (success) if the regular expression matches the string, otherwise it returns 1 (failure).</p>
<p>In addition to doing simple matching, bash regular expressions support sub-patterns surrounded by parenthesis for capturing parts of the match. The matches are assigned to an array variable BASH_REMATCH. The entire match is assigned to BASH_REMATCH[0], the first sub-pattern is assigned to BASH_REMATCH[1], etc..</p>
<p>The following example script takes a regular expression as its first argument and one or more strings to match against. It then cycles through the strings and outputs the results of the match process:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px;height:300px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co0">#!/bin.bash</span><br />
<br />
<span class="kw1">if</span> <span class="br0">&#91;</span><span class="br0">&#91;</span> <span class="re4">$#</span> <span class="re5">-lt</span> <span class="nu0">2</span> <span class="br0">&#93;</span><span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Usage: $0 PATTERN STRINGS...&quot;</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">1</span><br />
<span class="kw1">fi</span><br />
<span class="re2">regex</span>=$<span class="nu0">1</span><br />
<span class="kw3">shift</span><br />
<span class="kw3">echo</span> <span class="st0">&quot;regex: <span class="es2">$regex</span>&quot;</span><br />
<span class="kw3">echo</span><br />
<br />
<span class="kw1">while</span> <span class="br0">&#91;</span><span class="br0">&#91;</span> $<span class="nu0">1</span> <span class="br0">&#93;</span><span class="br0">&#93;</span><br />
<span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span><span class="br0">&#91;</span> $<span class="nu0">1</span> =~ <span class="re1">$regex</span> <span class="br0">&#93;</span><span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;$1 matches&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">i</span>=<span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">n</span>=<span class="co1">${#BASH_REMATCH[*]}</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#91;</span><span class="br0">&#91;</span> <span class="re1">$i</span> <span class="re5">-lt</span> <span class="re1">$n</span> <span class="br0">&#93;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot; &nbsp;capture[<span class="es2">$i</span>]: <span class="es3">${BASH_REMATCH[$i]}</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">let</span> i++<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">done</span><br />
&nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;$1 does not match&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
&nbsp; &nbsp; <span class="kw3">shift</span><br />
<span class="kw1">done</span></div></div>
<p>Assuming the script is saved in &#8220;bashre.sh&#8221;, the following sample shows its output:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co0"># sh bashre.sh 'aa(b{2,3}[xyz])cc' aabbxcc aabbcc</span><br />
regex: aa<span class="br0">&#40;</span>b<span class="br0">&#123;</span><span class="nu0">2</span>,<span class="nu0">3</span><span class="br0">&#125;</span><span class="br0">&#91;</span>xyz<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="kw2">cc</span><br />
<br />
aabbxcc matches<br />
&nbsp; capture<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>: bbx<br />
aabbcc does not match</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2008/05/bash-regular-expressions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

