<?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>El blog de Deigote &#187; linux</title>
	<atom:link href="http://blog.deigote.com/tag/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.deigote.com</link>
	<description>El mundo de Deigote. Un diario de cualquier cosa que me resulte interesante (si a alguien más se lo resulta, es otro cantar). Espero que os guste o disguste. Incluso que os deje indiferentes sería una opción tan buena como cualquier otra.</description>
	<lastBuildDate>Thu, 07 Apr 2011 15:29:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SyntaxError: invalid syntax usando equery en Gentoo</title>
		<link>http://blog.deigote.com/2010/07/14/syntaxerror-invalid-syntax-usando-equery-en-gentoo/</link>
		<comments>http://blog.deigote.com/2010/07/14/syntaxerror-invalid-syntax-usando-equery-en-gentoo/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 10:33:23 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[equery]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[eselect]]></category>
		<category><![CDATA[gentoo]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=490</guid>
		<description><![CDATA[En Gentoo, cómo solucionar el error que da equery: print pp.path(" /" + c[0]) SyntaxError: invalid syntax ]]></description>
			<content:encoded><![CDATA[<p>Usando Gentoo, me encontré con el siguiente error al lanzar el mandato equery:</p>
<pre><code>$ sudo equery belongs somefile
  File "/usr/bin/equery", line 271
    print pp.path(" /" + c[0])
           ^
SyntaxError: invalid syntax
</code></pre>
<p>Tras darle unas vueltas y no encontrar gran cosa en <del datetime="2010-07-14T10:14:26+00:00">Internet</del> Google <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> , acabé pensando que podía tener que ver con el intérprete de python instalado. No estoy seguro de cómo llegué a esa conclusión, pero supongo que ayudaron el hecho de ver que equery está escrito en python, que mi sistema tenía instalados varios intérpretes (concretamente los más actuales de la versión 2 y 3 del mismo), y que otra máquina con Gentoo usaba otro intérprete y no sufría el problema.</p>
<p>Para resolverlo, lo primero es buscar pistas. Al trabajar con varias versiones, lo normal es que el ejecutable sea un enlace a la versión elegida. Así que fue cuestión de ver a dónde apuntaba dicho enlace y buscar el paquete involucrado.</p>
<pre><code>$ ls -l /usr/bin/python
lrwxrwxrwx 1 root root 14 jul 14 12:21 /usr/bin/python -> python-wrapper
$ equery belongs /usr/bin/python-wrapper
[ Searching for file(s) /usr/bin/python-wrapper in *... ]
app-admin/eselect-python-20100321 (/usr/bin/python-wrapper)
$ equery files app-admin/eselect-python
[ Searching for packages matching app-admin/eselect-python... ]
* Contents of app-admin/eselect-python-20100321:
/etc/env.d/python/.keep_app-admin_eselect-python-0
/usr/bin/python-wrapper
/usr/share/eselect/modules/python.eselect
</code></pre>
<p>Parece que eselect es la herramienta que usa portage para decidir qué versión se usa cuando un paquete tiene varias instaladas. Por lo que se ve arriba, cada paquete instala sus propios módulos para informar a eselect de qué versiones hay disponibles, etc. A partir de aquí, jugando un poco con el mandato eselect, encontrar la forma de cambiar la versión no es difícil:</p>
<pre><code>$ eselect
Usage: eselect <global options> <module name> <module options>
...
$ eselect python
Usage: eselect python <action> <options>
...
$ eselect python list
Available Python interpreters:
  [1]   python2.6
  [2]   python3.1 *
$ sudo eselect python set python2.6
</code></pre>
<p>Y, efectivamente, eso resuelve el problema y equery vuelve a funcionar <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':)' title=':)' class='wp-smiley smiley-19' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2010/07/14/syntaxerror-invalid-syntax-usando-equery-en-gentoo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mandato PS con salida &#8220;personalizada&#8221;</title>
		<link>http://blog.deigote.com/2010/03/08/custom-output-ps-command/</link>
		<comments>http://blog.deigote.com/2010/03/08/custom-output-ps-command/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 11:56:14 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[command]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[output]]></category>
		<category><![CDATA[ps]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=476</guid>
		<description><![CDATA[Cómo definir salida personalizada o custom output para la orden ps en sistemas operativos tipo unix]]></description>
			<content:encoded><![CDATA[<p>Una opción del mandato <a href="http://www.google.es/search?q=ps+linux+command">ps</a> de los sistemas operativos tipo Unix que no suele estar muy bien documentada y que en mi opinión es tremendamente útil es la que permite personalizar la salida del mandato para que muestre la información que te interesa de cada proceso.
</p>
<p>La opción es <em>-o</em>, y acepta como argumentos una gran cantidad de posibilidades, que normalmente se encuentran descritas en la página del manual como <a href="http://ccrma.stanford.edu/planetccrma/man/man1/ps.1.html">standard format specifiers</a> (o directamente no se encuentran <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> ).
</p>
<p>Un ejemplo de cómo lucen normalmente las órdenes de tipo <em>ps</em> que suelo lanzar en mis terminales:</p>
<pre><code>$ ps fax -o user,uid,pid,ppid,pgrp,%cpu,%mem,rss,vsize,size,tname,etime,start_time,args
USER       UID   PID  PPID  PGRP %CPU %MEM   RSS    VSZ    SZ TTY          ELAPSED START COMMAND
root         0  3434     1  3434  0.0  0.1   552   5404   464 ?        12-22:14:08 Feb23 /usr/sbin/sshd
root         0 14466  3434 14466  0.0  0.5  2572   8124   512 ?              36:04 12:13  \_ sshd: deigote [priv]
deigote   1000 14469 14466 14466  0.0  0.2  1440   8280   668 ?              36:01 12:13      \_ sshd: deigote@pts/2
deigote   1000 14470 14469 14470  0.0  0.6  3344   6548  2172 pts/2          36:01 12:13          \_ -bash
root         0 16310 14470 16310  0.1  0.2  1196   4292   472 pts/2          00:06 12:49              \_ su -
root         0 16311 16310 16311  0.0  0.3  1688   4740   364 pts/2          00:03 12:49                  \_ -su
root         0 16315 16311 16315  0.0  0.2   992   4148   580 pts/2          00:00 12:50                      \_ ps fax -o user,uid,pid,ppid,pgrp,%cpu,%mem,rss,vsize,size,tname,etime,start_time,args
</code></pre>
<p>Y, de hecho, un par de alias que suelo tener siempre definidos, entre otros, son:</p>
<pre><code>alias ps='ps fax -o user,uid,pid,ppid,pgrp,%cpu,%mem,rss,vsize,size,tname,etime,start_time,args'
alias psg='ps | head -n 1 &#038;&#038; ps | grep'
</code></pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2010/03/08/custom-output-ps-command/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Obtener las extensiones de fichero existentes en un directorio</title>
		<link>http://blog.deigote.com/2010/01/12/obtener-las-extensiones-fichero-existentes-en-un-directorio/</link>
		<comments>http://blog.deigote.com/2010/01/12/obtener-las-extensiones-fichero-existentes-en-un-directorio/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 17:56:40 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=440</guid>
		<description><![CDATA[Cómo obtener la extensión de un fichero, o todas las extensiones que existan a partir de un directorio en bash o sh.]]></description>
			<content:encoded><![CDATA[<p>Una mini-receta rápida para obtener, de forma recursiva, todas las extensiones de fichero que existan a partir de un directorio dado:</p>
<p><code>find directorio_raiz -type f -exec sh -c 'basename $0 | sed "s/.*\.//"' {} \;  | sort | uniq</code></p>
<p>El truco viene del archipoderoso sed, que permite obtener las extensión de un fichero mediante la orden <em>sed &#8220;s/.*\.//&#8221;</em>, y funciona que yo sepa, para cualquier <em>Unix</em> con una shell compatible con <em>sh</em> y <em>find</em>, <em>basename</em> y <em>sed</em> instalados.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2010/01/12/obtener-las-extensiones-fichero-existentes-en-un-directorio/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Empezando con Liferay: una guía rápida de instalación</title>
		<link>http://blog.deigote.com/2010/01/08/empezando-con-liferay-una-guia-rapida-de-instalacion/</link>
		<comments>http://blog.deigote.com/2010/01/08/empezando-con-liferay-una-guia-rapida-de-instalacion/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 12:37:09 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[como]]></category>
		<category><![CDATA[instalación]]></category>
		<category><![CDATA[liferay]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[portlets]]></category>
		<category><![CDATA[tomcat]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[usar]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=423</guid>
		<description><![CDATA[Guía rápida de instalación de Liferay usando Apache y MySQL]]></description>
			<content:encoded><![CDATA[<p>Dado que reciéntemente he tenido que instalar un Liferay limpito en un servidor con Apache, dejo aquí una guía con los pasos que seguí:</p>
<ol>
<li><a href="#que-es-liferay">¿Qué es Liferay?</a></li>
<li><a href="#instalacion-basica">Instalación básica</a></li>
<li><a href="#liferay-con-mysql">Usando Liferay con MySQL</a></li>
<li><a href="#liferay-con-apache">Usando Liferay con Apache</a></li>
<li><a href="#usuario-por-defecto">Usuario por defecto y un par de ajustes más</a></li>
</ol>
<h4 id="que-es-liferay">¿Qué es Liferay?</h4>
<p><a href="http://www.liferay.com/">Liferay</a> es un gestor de portales web con una gran funcionalidad integrada (gestión de comunidades y usuarios, CMS, wiki, blogs, y mucho más), y a su vez es un contenedor de portlets, lo que le permite ser extendido de manera bastante rápida y flexible (siguiendo la especificación <a href="http://www.jcp.org/en/jsr/detail?id=286">JSR 286: Portlet Specification 2.0</a>). Además, cuenta con una versión <a href="http://www.liferay.com/web/guest/downloads/portal">Community</a> cuyo uso es gratuito y cuyo código es libre.</p>
<h4 id="instalacion-basica">Instalación básica</h4>
<p>Descargamos la última versión <em>Community</em> con el usuario que arrancará Liferay (en mi caso <em>www-data</em>) en el sitio que queramos (yo he escogido <em>/opt/websites/liferay.deigote.com</em> como directorio base de la instalación):</p>
<pre><code>$ su - www-data
$ cd /opt/websites/
$ wget 'http://sourceforge.net/projects/lportal/files/Liferay%20Portal/liferay-portal-tomcat-6.0-5.2.3.zip'
$ unzip liferay-portal-tomcat-6.0-5.2.3.zip
$ mv liferay-portal-5.2.3/ liferay.deigote.com
</code></pre>
<p>Si ahora arrancamos Liferay, podremos ver cómo nos informa en los log de que se usará una base de datos para testing (<em><a href="http://hsqldb.org/">Hipersonic</a></em>), y si navegamos por la web, podremos ver una serie de portlets a modo de demo:</p>
<pre><code>$ /opt/websites/liferay.deigote.com/tomcat-6.0.18/bin/startup.sh
$ tail -f logs/catalina.out &#038;
$ firefox http://localhost:8080
</code></pre>
<p>Este entorno de demo está bien para cacharrear un poco y ver cómo la gente de Liferay quiere vendernos sus capacidades para hacer un clon de Facebook <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> (vienen instanciados portlets de chat, de muro, de añadir usuarios como amigo, de actividad reciente&#8230;), pero los datos no persisten, por lo que no podréis pasar de ahí. Además, Liferay viene por defecto con usa serie de portlets (en forma de plugins) preparados para hacer la demostración antes mencionada. Yo normalmente borro dichos portlets antes de continuar (de hecho, en mi caso borro todos los plugins excepto el de web-form-portlet, que es el único que encuentro útil):</p>
<pre><code>$ rm -rf `ls /opt/websites/liferay.deigote.com/tomcat-6.0.18/webapps | grep -v ROOT | grep -v web-form-portlet`</code></pre>
<p>Para la persistencia de los datos, tenemos que conectar Liferay con un viejo conocido <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> .</p>
<h4 id="liferay-con-mysql">Usando Liferay con MySQL</h4>
<p>Para conectar Liferay con MySQL existen varias formas. De momento anotaré aquí la más sencilla (aunque para mi gusto un poco &#8220;fea&#8221;), puesto que no recuerdo exactamente cómo es la otra <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> . Liferay incluye en su <em>core</em> un fichero de propiedades (<em><a href="http://svn.liferay.com/browse/portal/trunk/portal-impl/src/portal.properties">portal.properties</a></em>) que configuran prácticamente todos los componentes del portal, base de datos incluida. Ese fichero puede ser extendido mediante el fichero <em>portal-ext.properties</em>, que por defecto no existe. Así que escribimos en él la configuración de la base de datos:</p>
<pre><code>$ echo "# Database connection
jdbc.default.driverClassName=com.mysql.jdbc.Driver
jdbc.default.url=jdbc:mysql://localhost/liferay_database?useUnicode=true&#038;characterEncoding=UTF-8&#038;useFastDateParsing=false
jdbc.default.username=mysql-user
jdbc.default.password=mysql-password" > /opt/websites/liferay.deigote.com/tomcat-6.0.18/webapps/ROOT/WEB-INF/classes/portal-ext.properties
</code></pre>
<p>A continuación nos conectamos al servidor de mysql (en mi caso, localhost) y creamos la base de datos y un usuario con permisos para la misma:</p>
<pre><code>$ mysql -h localhost -u root -p
$ create database liferay_database
$ grant all privileges on liferay_database.* to "mysql-user"@"localhost" identified by "mysql-password";
</code></pre>
<p>Si en este momento arrancamos Liferay de nuevo, deberíamos ver algunos mensajes haciendo mención a la base de datos utilizada (MySQL), y otros que indican que se están creando las tablas.</em>.</p>
<h4 id="liferay-con-apache">Usando Liferay con Apache</h4>
<p>Para usar Apache como servidor web, creamos un <em>host</em> virtual y lo conectamos al servidor de aplicaciones de Liferay (en mi caso Tomcat) usando un módulo de proxy. Podemos usar el módulo proxy_http, que funcionaría con cualquier servidor de aplicaciones, o el módulo proxy_ajp, específico de Apache, y que presenta algunas ventajas sobre http, aunque yo no las recuerde <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> . Dado que Tomcat soporta AJP, será el que usemos. Dado que yo uso Debian, necesito activar el módulo de proxy_ajp y crear un host virtual que use dicho módulo:</p>
<pre><code>$ su -
# a2enmod proxy_ajp
# nano /etc/apache2/sites-available/liferay.deigote.com
# a2ensite liferay.deigote.com
# /etc/init.d/apache2 restart
# exit
</code></pre>
<p>El contenido del fichero /etc/apache2/sites-available/liferay.deigote.com será el siguiente:</p>
<pre><code>&lt;VirtualHost *:80&gt;
        ServerName liferay.deigote.com
        ServerAdmin webmaster@localhost
        ErrorLog /var/log/apache2/liferay.deigote.com_error.log
        LogLevel warn
        CustomLog /var/log/apache2/liferay.deigote.com_access.log combined
        # Proxy to Tomcat
        &lt;Proxy *&gt;
                Order deny,allow
                Allow from all
        &lt;/Proxy&gt;
        ProxyPass / ajp://liferay.deigote.com:8009/
        ProxyPassReverse / ajp://liferay.deigote.com:8009/
&lt;/VirtualHost&gt;
</code></pre>
<p>Antes de echar a andar con esta configuración, debemos añadir un par de líneas al fichero de propiedades de Liferay, ya que si no éste dará por hecho que estamos atacando al puerto 8080 (el puerto por defecto de Tomcat) y escribirá las URL&#8217;s con dicho puerto. Una vez realizado este paso, deberíamos poder acceder a Liferay a través del host virtual que hemos usado (siempre y cuando nuestro servidor DNS sepa resolver dicho host, claro):</p>
<pre><code>$ /opt/websites/liferay.deigote.com/tomcat-6.0.18/bin/shutdown.sh
$ echo "
# Webserver configuration
web.server.http.port=80
web.server.https.port=443" >> /opt/websites/liferay.deigote.com/tomcat-6.0.18/webapps/ROOT/WEB-INF/classes/portal-ext.properties
$ /opt/websites/liferay.deigote.com/tomcat-6.0.18/bin/startup.sh
$ firefox http://liferay.deigote.com
</code></pre>
<h4 id="usuario-por-defecto">Usuario por defecto y un par de ajustes más</h4>
<p>Una vez estemos navegando por Liferay, podremos acceder usando el usuario <em>test@liferay.com</em> con la contraseña <em>test</em>, que es administrador de la comunidad por defecto (<em>guest</em>) Yo recomiendo un par de ajustes más:</p>
<ul>
<li>Cambiar la dirección de correo (y por tanto el login) y la contraseña del usuario administrador. Esto lo podéis hacer en el Panel de control, en el apartado de Usuarios.</li>
<li>Modificar el host virtual de la comunidad por defecto (o la que vayáis a usar) para que coincida con el que estéis usando para acceder a través de Apache. Esto se puede hacer en el panel de control, en el apartado <em>Communities &#8211; Guest &#8211; Manage pages &#8211; Settings &#8211; Virtual host</em>, usando el campo <em>Public virtual host</em>. Esto permitirá que las URL&#8217;s del tipo <em>http://virtual_host/web/nombre_de_la_comunidad/pagina</em> pasen a ser <em>http://virtual_host/pagina</em>, lo cual es más cómodo. Por ejemplo, la URL de la página por defecto (<em>home</em>) en la comunidad por defecto (guest) en mi caso pasaría de <em>http://liferay.deigote.com/web/guest/home</em> a <em>http://liferay.deigote.com/home</em></li>
</ul>
<p>Una vez finalizados estos pasos, ya podemos empezar a trabajar con Liferay en un entorno de producción (a falta, por supuesto, de configuraciones y optimizaciones de Tomcat, Apache y MySQL que no vienen al caso <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> ).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2010/01/08/empezando-con-liferay-una-guia-rapida-de-instalacion/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Programmed shutdown: pequeño script para apagar la máquina</title>
		<link>http://blog.deigote.com/2009/04/17/programmed-shutdown-pequeno-script-para-apagar-la-maquina/</link>
		<comments>http://blog.deigote.com/2009/04/17/programmed-shutdown-pequeno-script-para-apagar-la-maquina/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 09:09:30 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[poweroff]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[shutdown]]></category>
		<category><![CDATA[sleep]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[zenity]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=330</guid>
		<description><![CDATA[Después de buscar (no, mucho, eso si  ) por Google y no encontrar algo que se adaptase a mis mínimas necesidades, me he hecho un pequeño script de apagado de la máquina para mi maravilloso PC en el salón (que no de salón  ) equipado con un GNU/Linux (en concreto una Debian, pero [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignright" style="width: 260px"><a href="http://deigote.com/img/programmed-shutdown-cropped1.png"><img alt="Programmed shutdown: step 1" src="http://deigote.com/img/programmed-shutdown-cropped1.png" title="Paso 1: ¿cuánto tiempo?" width="250" /></a><p class="wp-caption-text">Paso 1: ¿cuánto tiempo?</p></div>
<p>Después de buscar (no, mucho, eso si <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> ) por Google y no encontrar algo que se adaptase a mis mínimas necesidades, me he hecho un pequeño <em>script</em> de apagado de la máquina para mi maravilloso PC en el salón (que no de salón <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':)' title=':)' class='wp-smiley smiley-19' /> ) equipado con un GNU/Linux (en concreto una Debian, pero el script es multiversal dentro del mundo Linux <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-P' title=':-P' class='wp-smiley smiley-15' /> y quizá Unix, depende de si el software zenity está en otras plataformas o no). </p>
<div class="wp-caption alignleft" style="width: 260px"><a href="http://deigote.com/img/programmed-shutdown-cropped2.png"><img alt="Programmed shutdown: step 2" src="http://deigote.com/img/programmed-shutdown-cropped2.png" title="Paso 2: tú tranqui, que ya te aviso yo..." width="250" /></a><p class="wp-caption-text">Paso 2: tú tranqui, que ya te aviso yo...</p></div>
<p>La idea es poder pedirle a la máquina que se apague dentro de equis minutos, con posilibidad de cancelarlo y cierto feedback visual de cuánto tiempo te queda. Posibles usos son por ejemplo imitar la función Sleep de algunas televisiones, o, cuando te vas de vacaciones y tienes algunas descargas tirando, o algún programa de TV que quieres que se grabe, pedirle que se apague en unos días para no consumir energía tontamente.</p>
<div style="clear:both; height:1em"></div>
<p>El script sólo requiere que esté instalado <a href="http://library.gnome.org/users/zenity/">Zenity</a>. El código fuente del mismo lo podéis ver a continuación:</p>
<pre><code>#!/bin/bash
# Ask for time in minutes to sleep and ater that poweroff the computer
# needs - zenity
# Diego Toharia - deigote@deigote.com

# Messages
TITLE="Apagar el ordenador"
MINUTES_QUESTION="¿Dentro de cuántos minutos?"
WAIT_PRE="Esperando"
WAIT_POST="minutos"

minutes=`zenity --entry --title "$TITLE" --text "$MINUTES_QUESTION" 2>&#038;1` || exit
seconds=`expr $minutes "*" 60`

if [ $seconds != "" ] ; then
	for i in `seq 1 $seconds` ; do
		percentage=`expr $i "*" 100`
		percentage=`expr $percentage "/" $seconds`
		echo $percentage
		sleep 1
	done | zenity --title="$TITLE" --text="$WAIT_PRE $minutes $WAIT_POST" --progress --auto-close --auto-kill
	poweroff
fi</code></pre>
<p>También quiero pensar que, si alguna vez cambio algo, podréis encontrar una versión actualizada en el enlace <a href="http://deigote.com/scripts/x-programmed-shutdown" title="Programmed shutdown">Programmed shutdown script</a> pero no garantizo que  cumpla mis propósitos  <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-D' title=':-D' class='wp-smiley smiley-2' /> .</p>
<div class="wp-caption aligncenter" style="width: 500px"><a href="http://deigote.com/img/programmed-shutdown-cropped3.png"><img alt="Programmed shutdown: laucher" src="http://deigote.com/img/programmed-shutdown-cropped3.png" title="Lanzador del script" width="490" /></a><p class="wp-caption-text">Programmed shutdown: laucher</p></div>
<p>Para invocarlo, basta guardarlo en un directorio que esté en el <em>path</em> (yo suelo usar para estos scripts $HOME/bin) y darle permisos de ejecución. Recordar que debéis tener permisos para ejecutar el mandato poweoff. En mi caso, tengo en la barra inferior un lanzador precedido del mandato gksudo, de tal manera que el script se lanza con los permisos necesarios, pidiéndome la contraseña en caso necesario.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2009/04/17/programmed-shutdown-pequeno-script-para-apagar-la-maquina/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Mini tutorial de awk</title>
		<link>http://blog.deigote.com/2006/08/30/mini-tutorial-de-awk/</link>
		<comments>http://blog.deigote.com/2006/08/30/mini-tutorial-de-awk/#comments</comments>
		<pubDate>Wed, 30 Aug 2006 10:02:02 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.deigote.com/blog/2006/08/30/mini-tutorial-de-awk/</guid>
		<description><![CDATA[Por petición popular, voy a escribir un poco sobre un mandato típico de los sistemas operativos UNIX (apareció por primera vez en 1977 nada menos), awk.
awk es un mandato que sirve para procesar líneas de texto (separadas, naturalmente, por un salto de línea). awk cuenta con un pequeño y sencillo lenguaje de programación que es [...]]]></description>
			<content:encoded><![CDATA[<p>Por <a href="http://www.deigote.com/blog/2006/08/17/dando-capacidades-multimedia-a-ubuntu-dapper-con-easyubuntu/#comment-51">petición popular</a>, voy a escribir un poco sobre un mandato típico de los sistemas operativos UNIX (apareció por primera vez en 1977 nada menos), <a title="AWK programming language" href="http://en.wikipedia.org/wiki/AWK_programming_language">awk</a>.</p>
<p>awk es un mandato que sirve para procesar líneas de texto (separadas, naturalmente, por un salto de línea). awk cuenta con un pequeño y sencillo lenguaje de programación que es interpretado (no necesita ser compilado), y resulta tremendamente útil cuando queremos extraer información de extensos campos de texto (y, posiblemente, manipularla).</p>
<p>El funcionamiento del madato awk es muy sencillo: basicamente tenemos dos posiblidades:</p>
<p><code> $ awk -f <em>fuente.awk</em> <em>fichero_entrada.txt</em></code><br />
<code> $ awk '<em>fragmento de código fuente</em>' <em>fichero_entrada.txt</em></code></p>
<p>En la primera de ellas, el código fuente está en un fichero (recomendado para usos que vayan a repetirse con el tiempo y con códigos fuentes largos) mientras que el segundo ofrece la ventaja de poder poner el código fuente como un argumento más. Esto es muy útil para el uso de awk en <em>scripts</em> o similares, en los que el uso de ficheros puede ser un engorro. También cabe la posibilidad de omitir el fichero de entrada, en cuyo caso awk leerá de la entrada estándar.</p>
<p>Respecto al lenguaje awk, tiene una estructura similar a lo siguiente:</p>
<p><code>BEGIN { <em>acción</em> }<br />
/<em>patrón</em>/ { <em>acción</em> }<br />
END { <em>acción</em> }</code></p>
<p>La forma de funcionamiento la siguiente:</p>
<ol>
<li>Nada más comenzar la ejecución, se evaluará la acción marcada entre llaves precedida por la palabra reservada <em>BEGIN</em>.</li>
<li>Por cada campo de texto (recordemos, por defecto líneas) awk evaluará si se ajusta al patrón (una <a href="http://es.wikipedia.org/wiki/Expresi%C3%B3n_regular">expresión regular</a>), y de ser así, ejecutará la acción marcada entre llaves que sigue a dicho patrón. Por cada líneas se evaluarán todos los patrones a menos que en una de las acciones ejecutadas se encuentre la orden <em>next</em>, en cuyo caso se comenzará desde el principio con la siguiente línea.</li>
<li>Finalmente, se procesará la acción marcada entre llaves precedida por la palabra reservada <em>END</em>.</li>
</ol>
<p>Respecto a los <strong>patrones</strong> de awk, son, como ya he dicho, expresiones regulares. No voy a explicar aquí todas las posiblidades porque no acabaría nunca (y con la <a title="Las expresiones regulares en programación" href="http://es.wikipedia.org/wiki/Expresi%C3%B3n_regular#Las_expresiones_regulares_en_programaci.C3.B3n">ayuda de la Wikipedia</a> os debería bastar), basten un par de ejemplos:</p>
<ul>
<li>/[afP]MEMOLO[1-3]z/ casará con cualquier línea que contenga las letras a, f o P seguidas de la cadena MEMOLO seguidas de un dígito comprendido del 1 al 3 y seguida por la letra z.</li>
<li>/[afP](MEMOLO)+([1-3])*z/ casará con cualquier línea que contenga las letras a, f o P seguidas de la cadena MEMOLO una o varias veces seguidas de un dígito comprendido del 1 al 3 que puede aparecer ninguna, una, o varias veces y seguida por la letra z.</li>
</ul>
<p>Esta es la parte más complicada de awk (ya sabeis lo que <a title="Jamie Zawinski dijo" href="http://www.deigote.com/blog/2006/08/21/jamie-zawinski-dijo/">se dice de las expresiones regulares</a>).</p>
<p>En cuanto a las <strong>acciones</strong>, cualquiera que haya programado en C no tendrá mucho problema, ya que es similar. Como características cabría destacar:</p>
<ul>
<li>El acceso a las línea actual se hace mediante unas variables especiales. En concreto $0 referencia a toda la línea mientras que $1, $2, etcétera, referencian a los campos de dicha línea. El separador de campos por defecto es un espacio o un tabulador, pudiéndose modificar en la acción de <em>BEGIN</em> con la variable FS (otra expresión regular, por cierto).</li>
<li>No es necesario declarar ni tipar las variables, cuyo formato es el mismo que en C (su expresión regular, para que vayais practicando, es algo parecido a <em>[a-Z]([a-Z] | [1-9] | _ )*</em>).</li>
<li>Están permitidas todas las estructuras clásicas de programación en un formato estilo C (bucles, expresiones condicionales, operadores, etcétera).</li>
<li>Para imprimir resultados, existen dos posiblidades. La primera, <em>print</em>, es la más cómoda, puesto que no es necesario usar paréntesis para sus argumentos y cuenta con concatenación automática de los mismos (algo parecido al mandato <em>echo</em> de la terminal. Por ejemplo, <em>print &#8220;la línea &#8221; $0 &#8220;tiene &#8221; NF &#8221; palabras&#8221;</em> imprimirá la frase que precede a <em>print</em> sustituyedo $0 por la línea actual y NF (otra variable especial) por el número de campos de la misma. Como segunda posibilidad, tenemos <em>printf</em>, que ofrece mayor control (es idéntico al del lenguaje C).</li>
</ul>
<p>¿Y qué pasa con los los jugosos <strong>ejemplos</strong>? Pues he recopilado alguno que otro según me ha ido surgiendo la necesidad de usarlo estos días.</p>
<ul>
<li>Por ejemplo, el otro día necesitaba obtener del fichero de <em>log</em> de Tomcat las líneas que contuviesen o bien &#8220;SOAP21&#8243; o bien &#8221; &#8211; 2 &#8220;. Esto sería sencillo de hacer con dos grep, pero yo necesitaba que esas líneas mantuviesen el orden en el que habían aparecido en el fichero, y hacer eso con un grep requiere de una expresión regular bastante más compleja de lo que en realidad es necesario. Además, quería saber en qué número de línea del fichero estaba cada línea buscada. Con awk, fue tan sencillo como esto:<br />
<code> cat tomcat.log | awk '/SOAP21/{print NR " - " $0} / - 2/{print NR " - "$0}'</code></li>
<li>También necesité, en el mismo fichero, verificar que se cumpliese una secuencia, y concretamente, me valía saber que, dentro del conjunto de líneas que contenían &#8220;SOAP21&#8243;, las múltiplo de 5 eran idénticas, ya que de esta manera sabía que se habían cumplido todos los pasos. Por lo tanto, necesitaba sacar las líneas que tuviesen &#8220;SOAP21&#8243;, y dentro de éstas, sólo las que su número de línea fuese múltiplo de 5. Nuevamente, awk te lo pone fácil:<br />
<code> cat tomcat.log | awk 'BEGIN { nl = 1 } /SOAP21/ { if (nl % 5 == 0) print ; nl++}'</code></li>
<li>En plan más &#8220;complicado&#8221; (teniendo en cuenta que lo de antes era trivial), hice una pequeña línea para sacar la nota media a partir del archivo html que te devuelve <a title="Universidad Politécnica de Madrid. Consulta de expedientes" href="https://www.upm.es/expedientes/">la UPM</a> cuando consultas tu expendiente usando la modalidad &#8220;Último estado de cada asignatura&#8221; (aunque falla cuando tienes alguna matrícula, pero bueno, eso no es lo importante ahora). El código es el siguiente:<br />
<code>cat consulta.upm.html | grep "<br />
/&lt;\/table&gt;/ { d = 0 } { if (d &gt; 0) { if (c == 10) { print ; c = 0 } else c++ } }' | grep<br />
'&gt;\([1-9][0-9]\|[1-9]\|[1-9]\,[0-9]\{1\}\|[1-9]\,[0-9]\{2\}\)&lt;' | cut -d 1 -f2 -d'&gt;' | cut<br />
-f1 -d'&lt;' | awk 'BEGIN { t=0.0;n=0; } {print ; t=t+$1 ; n++} END { print "Total " t "<br />
Asignaturas " n " Media " t/n}'</code><br />
Como veis, el primer fragmento de awk hace una selección de líneas, imprimiendo sólo las filas de las tablas que sean múltiplo de 10 (son en las que se encuentran las notas) y que estén contenidas entre una línea que tenga la palabra Obs y el primer final de tabla en html. Una vez obtenidas estas líneas, uso grep para quedarme solo con las que tienen nota y cut para dejar sólo la nota, quitando el resto de elementos html. El segundo fragmento de awk se encarga de ir sumando las notas y el número de asignaturas para imprimir la media.</li>
<p><strong>EDITO:</strong> iré añadiendo más fantabulosos ejemplos <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=';-)' title=';-)' class='wp-smiley smiley-22' /> según me los vaya encontrado.</p>
<li><a title="Pablo Toharia @ dac" href="http://www.gmrv.es/~ptoharia/">Mi hermano</a> el otro día me preguntó como resolvería un problema y le sugerí que usara awk. El problema consistía en que tenía ficheros (por cierto, de más de 80.000 líneas) con una estructura tal que<br />
<code>frase1 1<br />
frase2 5<br />
...<br />
fraseN M</code><br />
y quería sumar los números de cada frase. En el caso original tenía la ventaja de que las frases siempre iban en el mismo orden en todos los ficheros, pero la sencillez de awk hace que la solución (que corre a cargo de mi hermano, por cierto) valga para casos que no estén en orden (e incluso que aparezcan frases en algunos ficheros y en otros no). Además, se requería que fuese relativamente rápido, y awk cumplió con las expectativas (la solución previa eran pruebas con <em>scripts</em> más o menos a mano y los resultados se iban por encima de los 10 minutos, frente a los 2 minutos de la solución con awk). El único problema era juntar la salida de los ficheros, pero awk permite trabajar con varios ficheros de entrada de datos (si no, un poquito de <em>bash scripting</em>, for i in *.out ; do cat $i ; done, lo hubiese solucionado). Los ficheros tenían extensión .out, por lo que la solución final es:<br />
<code>awk 'BEGIN { FS = " ";} { resultados[$1] += $2 } END { for(category in resultados) print category, resultados[category]; } *.out'</code><br />
Como veis es sencillo, limpio y eficaz <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-D' title=':-D' class='wp-smiley smiley-2' /> ¡con awk, la suciedad se va en un bang! Aquí además podeis ver algunas cosas más de awk, como los bucles, los <em>array</em> (estilo PHP, sin declaración ni reserva de memoria ni inicialización de datos) y la variable especial <acronym title="Field separator">FS</acronym>, que sirve para especificar cómo separar los campos de una línea (aunque en este caso no haga falta porque por defecto es espacio o tabulador).</li>
</ul>
<p>Y esto es todo por hoy. Huelga decir que en Internet encontrareis cientos de ejemplos y tutoriales, pero yo quería hacer una pequeña introducción con un par de ejemplos más prácticos que los que suelo encontrar (al menos, serían prácticos para mí ;-)). Espero que os sea de utilidad.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2006/08/30/mini-tutorial-de-awk/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Webcam Quickcam Messenger en Ubuntu Linux</title>
		<link>http://blog.deigote.com/2006/01/13/webcam-quickcam-messenger-en-ubuntu-linux/</link>
		<comments>http://blog.deigote.com/2006/01/13/webcam-quickcam-messenger-en-ubuntu-linux/#comments</comments>
		<pubDate>Fri, 13 Jan 2006 17:37:00 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[driver]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[logitech]]></category>
		<category><![CDATA[messenger]]></category>
		<category><![CDATA[quickcam]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[webcam]]></category>

		<guid isPermaLink="false">http://www.deigote.com/blog/?p=38</guid>
		<description><![CDATA[Cómo hacer funcionar en Linux la webcam Logitech Quickcam Messenger]]></description>
			<content:encoded><![CDATA[<p>Pues sí, como he comentado en el <a href="http://deigote.blogspot.com/2006/01/regalos-tecnolgicos.html">post</a> anterior, uno de los reyes (no recuerdo si Melchor o Baltasar&#8230; Gaspar no, que ese me ha traido la <a href="http://mundominimotos.com/data/productos/Multitubular-zoom1.gif">minimoto</a>) me ha traido una  <a href="http://www.logitech.com/index.cfm/products/details/ES/ES,CRID=2204,CONTENTID=10860">webcam</a>, que he hecho funcionar bajo Linux (concretamente, yo uso <a href="http://www.ubuntulinux.org">Ubuntu</a>). La cuestión es que oficialmente la cámara no está soportada. Sin embargo encontré un driver, enlazado ya en <a href="http://del.icio.us/deigote"> Del.ici.us</a>, que es el siguiente:<br />
<a href="http://home.mag.cx/messenger/">Quickcam Messenger Driver</a><br />
Tras compilarlo y tal, la cosa funcionó, ya he hecho mis primeros videochateos con el <a href="http://amsn.sourceforge.net">Amsn</a> (¡como mola! :D). El único problema que tengo es que la resolución es pobre (lei por ahí que de momento no soporta los 640&#215;480 de la cámara) y que cada vez que reconecto la cámara, tengo que borrar y cargar los drivers de nuevo (puede ser problema de que antes instalé otros drivers y que estén todos, los de Ubuntu incluidos, pegándose por la cámara :P), pero bueno, al final se resume en:<br />
<code># sudo rmmod quickcam ; sudo rmmod videodev ; sudo modprobe quickcam ; sudo modprobe videodev </code><br />
cada vez que conecto la cámara. El micro parece que es detectado por la Ubuntu (de hecho, me monta la cámara como una tarjeta de sonido extra), pero todavía no he conseguido grabar nada con él (tampoco he dedicado mucho tiempo).</p>
<p> Technorati Tags: <a href="http://technorati.com/tag/webcam" rel="tag">webcam</a> <a href="http://technorati.com/tag/quickcam" rel="tag">quickcam</a> <a href="http://technorati.com/tag/messenger" rel="tag">messenger</a> <a href="http://technorati.com/tag/quickcam+linux" rel="tag">quickcam linux</a> <a href="http://technorati.com/tag/quickcam+messenger+linux" rel="tag">quickcam messenger linux</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2006/01/13/webcam-quickcam-messenger-en-ubuntu-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firewalling/accounting con iptables, averiguar la IP y algunas cosas más</title>
		<link>http://blog.deigote.com/2005/09/09/firewallingaccounting-con-iptables-averiguar-la-ip-y-algunas-cosas-mas/</link>
		<comments>http://blog.deigote.com/2005/09/09/firewallingaccounting-con-iptables-averiguar-la-ip-y-algunas-cosas-mas/#comments</comments>
		<pubDate>Sat, 10 Sep 2005 00:19:00 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[accounting]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[traffic]]></category>

		<guid isPermaLink="false">http://www.deigote.com/blog/?p=8</guid>
		<description><![CDATA[Bueno. Creo que ya va tocando un poco de iptables, mi tema linuxero favorito :P. Pues nada, simplemente después de cierta pereza me he decidido a hacer un &#8220;firewall&#8221; con iptables para mi máquina. Pongo &#8220;firewall&#8221; entre comillas porque no hago filtrado en absoluto: estoy detrás del router, así que pocos ataques recibo. Encima los [...]]]></description>
			<content:encoded><![CDATA[<p>Bueno. Creo que ya va tocando un poco de <a href="http://www.netfilter.org">iptables</a>, mi tema linuxero favorito :P. Pues nada, simplemente después de cierta pereza me he decidido a hacer un &#8220;firewall&#8221; con iptables para mi máquina. Pongo &#8220;firewall&#8221; entre comillas porque no hago filtrado en absoluto: estoy detrás del router, así que pocos ataques recibo. Encima los switches que comunican mis <abbr title="Personal Computers"> PC&#8217;s </abbr>, al ser precisamente switches y no hub&#8217;s, separan los dominios de colisión y no recibo trafico ethernet de ninguna otra máquina. En fin, que no hay lugar para mucha experimentación. Sin embargo, un amante de las estadísticas de red como yo no puede dejar pasar la ocasión que brinda <a href="http://www.netfilter.org">iptables</a> de contar todo el tráfico que pasa por mi <abbr title="Personal Computer"> PC </abbr>, por lo que he hecho el siguiente firewall, que pongo a continuación a trozos para comentar el propósito de cada cosa.</p>
<ul>
<li>Para empezar, algunas variables. El nombre del script, la localización del mandato iptables, el puerto que uso para el emule y los puertos que uso para el bittorrent. Poca cosa :):
<pre><code>
#!/bin/sh
# An extended firewall script.
# Diego Toharia

# Some vars
N=/etc/init.d/firewall
IPTABLES=/sbin/iptables
EMULE_PORT=6889
BT_PORT=6881:6888
</code></pre>
</li>
<li>Aquí esta la chicha de <a href="http://www.netfilter.org">iptables</a>. Las reglas, metidas dentro de una función. Como se puede ver hay poca cosa, y ni una sola acción de salto (-j, <i> jump </i>). Así, por cada regla sólo se cuentan los paquetes que enlazan con la misma. Si quisíeramos filtrar alguna de ellas, añadimos <i> -j DROP </i> y listo :). Principalmente lo que hago es, primeramente, crear contadores de conexiones entrantes (es decir, el número de paquetes/bytes que generan las nuevas conexiones de clientes a programas con socket en estado <i>LISTEN</i> o en escucha), y luego añado varios contadores del tráfico generado tanto entrante como saliente por el emule, bittorrent, web, y globales (dentro y fuera de la <abbr title="Local Area Network"> LAN </abbr> y en total). Como ya he comentado, no hay mucho más, ya que es una máquina detrás de un router y que no es router a su vez:
<pre><code>
# Rules definitions
rules_def() {
    ############ CONNECTIONS COUNTERS ##################################
    # Count Emule connections
    $IPTABLES -A INPUT -m state --state NEW -p tcp --dport $EMULE_PORT
    # Count Bittorrent connections
    $IPTABLES -A INPUT -m state --state NEW -p tcp --dport $BT_PORT
    # Count Ssh connections
    $IPTABLES -A INPUT -m state --state NEW -p tcp --dport ssh
    # Count Http connections
    $IPTABLES -A INPUT -m state --state NEW -p tcp --dport http
    ############ TRAFIC COUNTERS #######################################
    # Count Emule input traffic
    $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED         -p tcp --dport $EMULE_PORT
    # Count Bittorrent input traffic
    $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED         -p tcp --dport $BT_PORT
    # Count Http traffic
    $IPTABLES -A INPUT  -p tcp --sport http
    $IPTABLES -A OUTPUT -p tcp --dport http
    # Count LAN traffic
    $IPTABLES -A INPUT -s 192.168.0.0/24
    $IPTABLES -A OUTPUT -d 192.168.0.0/24
    # Count inet traffic
    $IPTABLES -A INPUT -s ! 192.168.0.0/24
    $IPTABLES -A OUTPUT -d ! 192.168.0.0/24
    # Count all traffic
    $IPTABLES -A INPUT
    $IPTABLES -A OUTPUT
    ####################################################################
}
</code></pre>
</li>
<li>Aquí pongo una función que averigua cuál es la dirección <abbr title="Internet Protocol"> IP </abbr> con la que navegamos por Internet, y cuales son las direcciones <abbr title="Internet Protocol"> IP </abbr> configuradas en nuestra máquina. Para hacerla, he usado la información del siguiente enlace: <a href="http://blog.enrique.barbeito.org/archivos/2004/02/10/una-funcin-para-extraccin-de-tu-ip-en-internet/"> http://blog.enrique.barbeito.org/</a>. Lo he encontrado usando <a href="http://www.google.es">Google</a>, como no. Muchas gracias a Enrique Barbeito y su blog.
<pre><code>
# IP finder
ipfinder() {
        IP_PUB=`lynx -dump www.cualesmiip.net | grep Tu | awk '{print $5}'`
        IP_PRIVS=`ifconfig | grep "inet addr" | cut -f2 -d: | cut -f1 -d' '`
        export IP_PUB=$IP_PUB
        export IP_PRIV=$IP_PRIVS
        echo "Public IP"
        echo $IP_PUB
        echo "Private IPs"
        echo $IP_PRIVS
}
</code></pre>
</li>
<li>A continuación hago una función que, a partir de información guardada por el resto del script, calcula unas tasas de transferencia desde que se puso en marcha el script hasta que se paró (siempre que estas operaciones se hagan de forma correcta, es decir, arrancando y parando el script con las propias opciones del script). Esta funcionalidad, es, sin duda, la que más me gusta :P, todos los días consulto el trafico del dia anterior y me congratulo, jejeje:
<pre><code>
# Traffic rates
traffic_rates() {
    START_TIME=`cat /var/run/firewall.start`
    FINISH_TIME=`cat /proc/uptime | awk '{print $1}' | cut -d'.' -f 1`
    UPTIME=`expr $FINISH_TIME - $START_TIME`
    INPUT_TRAFFIC=`sudo iptables -L INPUT -v -x | grep \!localnet | awk '{print $2}'`
    INPUT_RATE=`expr $INPUT_TRAFFIC / 1024 / $UPTIME`
    OUTPUT_TRAFFIC=`sudo iptables -L OUTPUT -v -x | grep \!localnet | awk '{print $2}'`
    OUTPUT_RATE=`expr $OUTPUT_TRAFFIC / 1024 / $UPTIME`
    echo "Input rate: $INPUT_RATE KB/s (`expr $INPUT_TRAFFIC / 1048576` MB)"
    echo "Output rate: $OUTPUT_RATE KB/s (`expr $OUTPUT_TRAFFIC / 1048576` MB)"
}
</code></pre>
</li>
<li>Por último, el &#8220;programa principal&#8221; del script. Está hecho a modo de script de los del init.d, para ser arrancado por el mismo (luego explicaré cómo hacerlo). Se encarga de coordinar lo anterior para, por cada <i>start</i> y <i>stop</i>, guardar en un log el accounting, la direccion <abbr title="Internet Protocol"> IP </abbr>, y las tasas de tráfico del intervalo de tiempo entre los mismos:
<pre><code>
case "$1" in
  start)
        cat /proc/uptime | awk '{print $1}' | cut -d'.' -f 1             &gt; /var/run/firewall.start
        echo "Firewall: setting up iptables rules.."
        echo "###############################################"             &gt; /var/run/firewall
        echo -n "Traffic from " &gt;&gt; /var/run/firewall
        date +%k:%M" of "%A' '%D &gt;&gt; /var/run/firewall
        rules_def
        ipfinder &gt;&gt; /var/run/ipfinder
        ;;
    stop)
        echo "Firewall: saving counters.."
        echo -n "To " &gt;&gt; /var/run/firewall
        date +%k:%M" of "%A' '%D &gt;&gt; /var/run/firewall
        echo "###############################################"             &gt;&gt; /var/run/firewall
        iptables -L -v &gt;&gt; /var/run/firewall
        echo "###############################################"             &gt;&gt; /var/run/firewall
        ipfinder &gt;&gt; /var/run/firewall
        echo "###############################################"             &gt;&gt; /var/run/firewall
        traffic_rates &gt;&gt; /var/run/firewall
        echo "###############################################"             &gt;&gt; /var/run/firewall
        mv /var/run/firewall /var/log/firewall/log.`date +%d_%m_%y_%H_%M`
        echo "Firewall: flushing iptables rules.."
        iptables -F
        iptables -X
        rm /var/run/ipfinder
        rm /var/run/firewall.start
        ;;
    reload|restart|force-reload)
        $N stop
        $N start
        ;;
  *)
        echo "Usage: $N {start|stop|restart|force-reload}" &gt;&amp;2
        exit 1
        ;;
esac

exit 0
</code></pre>
</li>
</ul>
<p>Si poneis cada parte del código seguida, tendreis el script completo. Durante la ejecución del mismo podeis encontrar vuestra ip en el fichero <i>/var/run/ipfinder</i>, quedando los logs almacenados en el directorio <i>/var/log/firewall</i> que previamente debeis crear. Poniendo este fichero en <i>/etc/init.d/</i> con el nombre <i>firewall</i> y ejecutando <i>rcconf</i>, o el mandato <i>update_rec.d firewall defaults</i>, lo tendreis todo funcionando, y podreis disponer de unas sencillas estadísticas para los que no queremos complicarnos la vida (para los que si quieran, a conjugar <a href="http://www.netfilter.org">iptables</a> con <a href="http://www.ntop.org">ntop</a>, que me ha parecido potentisimo, y <a href="http://www.snort.org">snort</a>, que no lo he usado más que como sniffer pero es un potente detector de intrusos). Sigo buscando cómo hacer accounting del resto de máquinas, ya que aunque ponga la interfaz en modo promiscuo, iptables no procesa el tráfico que llega de otros <abbr title="Personal Computers"> PC&#8217;s </abbr>. Mis posteriores descubrimientos, aquí, en próximas ediciones ;). No puedo terminar el artículo sin agradecer a <a href="http://people.unix-fu.org/andreasson">Oskar Andreasson</a> su magnifico trabajo con el <a href="http://www.linuxsecurity.com/resource_files/firewalls/IPTables-Tutorial/iptables-tutorial.html">tutorial de iptables</a>, con el que yo me inicie y que es mi referencia para este tema.</p>
<p>Por supuesto, sólo para <a href="http://www.linux.org">Linux</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2005/09/09/firewallingaccounting-con-iptables-averiguar-la-ip-y-algunas-cosas-mas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Any to mp3</title>
		<link>http://blog.deigote.com/2005/09/06/any-to-mp3/</link>
		<comments>http://blog.deigote.com/2005/09/06/any-to-mp3/#comments</comments>
		<pubDate>Wed, 07 Sep 2005 00:37:00 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[any2mp3]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[for]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[wma]]></category>

		<guid isPermaLink="false">http://www.deigote.com/blog/?p=4</guid>
		<description><![CDATA[Un script que convierte cualquier archivo (wav, wma, avi, etc) a mp3]]></description>
			<content:encoded><![CDATA[<p>¡Bueno, pues aquí va la primera entrada :D! ¿Nunca os las habeis visto con los malditos archivos wma? Yo si, y debo decir que son odiosos, nada menos que de <a href="http://www.microsoft.com">Mocosoft</a>. Más que nada, no me gustan porque mi fabulosa radio no lee más que MP3. Asín que, con las mismas, he hecho un cutre script que convierte cualquier archivo de cualquier tipo que pueda leer mplayer (es decir, cualquiera :)) a formato mp3. Incluso se puede usar para extraer el sonido de un archivo de video cualquiera (un concierto, por ejemplo :)). Aquí os dejo el estupendo y citado script:</p>
<pre><code>
#!/bin/bash
# any2mp3 - Recives an extension and convert any file with this extension
#           to mp3 using mplayer and lame.
# Requirements - mplayer, lame.
# Diego Toharia - deigote@gmail.com

# Verify parameter
if [[ $# -ne 1 ]]
then
  echo "Error: first parameter (file extension to convert) missing"
  echo "Usage: `basename $0` "
  exit 1
fi
ext=$1

# Remove spaces
for i in *.$ext; do
  mv "$i" `echo $i | tr ' ' '_'` ;
done

# To wav with mplayer, to mp3 with lame.
for i in *.$ext ; do
  name="`basename "$i" ."$ext" | tr '_' ' '`.mp3"
  echo $name
  mplayer $i -ao pcm:file=scratch.$$.wav &amp;&amp; \  lame -h -V 7 scratch.$$.wav "$name" ;
done

# Remove scratch file
rm scratch.$$.wav
</code></pre>
<p>Por supuesto, sólo para <a href="http://www.linux.org">Linux</a>. ¿O que pensabais?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2005/09/06/any-to-mp3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
