Haciendo respaldos con el protocolo SMB desde Linux

matrox usb hardrive
Nuestra nueva unidad de disco duro externa. Comparen el tamaño con la nueva Coca Cola “Blak”

Vero y yo nos compramos hace días un disco duro externo el cual se conecta por el puerto USB con la computadora; La razón: Nunca hacemos respaldos y cada vez que pasa algo nos quedamos como pajarito en grama, llorando por los datos perdidos. Nos metimos con un “Maxtor OneTouch II USB” el cual si bien no es muy rápido tiene bastante espacio (300GB) y sobre todo tiene un software de backup el cual es muy fácil de usar.

Por supuesto no todo es color de rosas:

  • El software de respaldo funciona sólo bajo Windows
  • El sistema de archivos de el disco es NTFS (viene con FAT32 pero nadie en su sano juicio usa eso). El soporte de NTFS bajo Linux no es muy bueno.
  • No se puede compartir el disco con dos computadoras, para eso tienes que comprar un adaptador de red, el “Linksys Network Storage Link”.
  • Es algo lenta, me tomó casi 4 horas respaldar 10GB por la red (la laptop que la tiene conectada utiliza una conexión inalambrica de 50MB/sec y el cable USB puede transmitir entre 100 y 400 Mb/seg. Me da ladilla echar números).

Pero la fe hay que pagarla, y ya no queriamos gastar menos dinero. Al menos la laptop de Vero (y donde yo ocasionalmente hago una que otra cosa) estaba protegida. Pero y ¿que hacía con mi Laptop bajo Linux?

Nada, bien sencillo: Compartir el disco usando SMB en Windows y luego montar el disco compartido bajo Linux. De allí usar Tar o CPIO.

Revizando si el disco ya está compartido:

[josevnz@localhost ~]$ smbclient --workgroup XXXXX -L 192.168.0.2
Password:
Domain=[RORAIMA] OS=[Windows 5.1] Server=[Windows 2000 LAN Manager]

Sharename Type Comment
--------- ---- -------
IPC$ IPC Remote IPC
Documents Disk
josevnz Disk
session request to 192.168.0.2 failed (Called name not present)
session request to 192 failed (Called name not present)
Domain=[RORAIMA] OS=[Windows 5.1] Server=[Windows 2000 LAN Manager]

Server Comment
--------- -------

Workgroup Master
--------- -------

OK, Montando la partición con SMB (como root, no quiero poner una entrada permanente en el /etc/fstab):
[root@localhost ~]# mount -t smbfs -o username=josevnz,password=ZZZZ,workgroup=XXXXX,rw,lfs,sockopt=TCP_NODELAY //192.168.0.2/josevnz /mnt/smb/

Una vez hecho esto, el venerable tar hace el trabajo:
[root@localhost ~]# tar -czvf /mnt/smb/josevnz-backup-`date +%Y%m%d`.tar.gz /home/josevnz

Listo, ya puedo montar Fedora Core 5 este fin de semana y al menos estaré seguro que mis datos van a estar de vuelta 😉

Buscar en Technorati: , , , ,

El futuro de Perl es questionable: ¿Puede desaparecer?

Leyendo este articulo, me encuentro que dicen que Perl está perdiendo relevancia, y que es dificil conseguir desarrolladores con experiencia en el lenguaje, además de que lenguajes como Java lo están reemplazando en las escuelas o compañias como Google no lo utilizan en lo absoluto (ellos se mojan por gente con experiencia en Phython).

Les recomiendo primero que se lean el articulo, es muy provocador y detallado. Curiosamente las pantallas usadas en el articulo copian la funcionalidad de Eclipse y Java, el cual en mi opinión es el mejor editor libre de Java.

Yo en particular no creo que la situación sea tan grave aún; Y digo aún porque:

  • La inversión de Perl (en entrenamiento y tecnología) es muy grande como para hacerla irrelevante. Perl 6 ya viene, con un montón de mejoras muy importantes.
  • Google no es el espejo en el que todas las compañias deben reflejarse. Después de todo Google es una compañia joven.

Por otro lado, es dificil conseguir gente que sepa bien Perl (aunque eso se aplica a cualquier lenguaje); En Venezuela recuerdo que a nosotros nos resultó casi imposible conseguir a gente que supiera usar el lenguaje y en los Estados Unidos no es nada fácil (aunque no es fácil conseguir buenos desarrolladores en ninguno de los dos paises, al menos es lo que he visto en mi experiencia profesional).

Yo no recuerdo que enseñaran Perl en las Universidades (por ejemplo, yo lo aprendí por mi cuenta); Por otro lado se que ya se enseña Python en algunas Universidades Venezolanas (Java por supuesto) pero eso es otro punto más en contra de Perl.

Como desarrollador sería agradable ver que las herramientas de Perl se vuelven más maduras, de lo contrario otros lenguajes más jovenes tomarán su lugar (alguien recuerda a COBOL o BASIC).

Y usted, que herramientas usa para programar en su “Scripting Lannguaje” preferido?

Buscar en Technorati:

Huracán Katrina: Categoría 5, lo peor comienza en la mañana

Huracan Katrina en Google Maps

Si, la tormenta pasó de categoría 1 a categoría 5. En Stamford el clima va a estar un poco lluvioso pero nada más, pero allá abajo la cosa se va a poner bien fea. CNN y otros canales de noticias llevan todo el día reportando y es que es la primera tormenta que esa parte de la geografía de manera tan directa en 40 años.

Katrina
Esa persona tiene fotos de el Huracan, mientras se aproxima a New Orleands. la foto es espeluznante

Por supuesto ya en Technorati se pueden conseguir los Blogs hablando de el fenomeno, entre ellos me conseguí una imagenes interesantes en Flickr de Goggle Earth mostrando el fenomeno. Hay otro grupo con muchas más fotos. Otro sitio con imagenes impresionantes es la página de la NASA.

De verdad les deseo suerte a todos los que viven allá y ojalá que las 12 mil personas que están el el “SuperDome” en New Orleands no pasen tanto trabajo mientras pasa el temporal.

Ya mañana veremos como esto afecta a el mercado. Ya el precio de el combustible subió aún más, además de que New Orleands produce una buena parte de el combustible de Los Estados Unidos.

Buscar en Technorati: ,,

Echando código: ¿Ejecución de programas de linea de comandos más inteligente?

Vamos a ver el siguiente problema: Usted rutinariamente ejecuta cierto programa en su sistema, el cual corre por una cantidad ilimitada de tiempo (como un demonio en UNIX); Rato más tarde se decide a matar el proceso y debe entonces empezar a buscar en que máquina lo corrio y cual es el PID (program ID) de el proceso, para luego matarlo con kill. ¿Suena ladilla verdad? (sobre todo si lo hace todos los dias).

Seria genial tener un programa que nos permita ejecutar un comando (sin importar en donde estemos parados en el sistema de archivos) y si necesitamos matarlo entonces sólo llamamos a otro script con el nombre de el programa anterior. La idea es mantener el rastro de el primer programa (donde se ejecutó y el PID) y para matarlo poder utilizar esa información. En el caso de demonios normalmente ejecutamos una instancia (y es esa la que tiene hijos), así que nuestra solución se va a valer de eso.

La solución a el problema se reduce a dos scripts:

  • Uno para correr los programas, este mantendrá la máquina en donde lo ejecutamos y el PID de el programa que queremos correr.
  • Un script que sabe que hizo el script que lanzó el programa anterior, y con esa información lo mata

Esto se puede hacer en cualquier script languaje, pero veamos que tan lejos podemos llegar con Perl 🙂

Supongamos que nuestro “demonio” es solamente un programita que no hace nada, excepto contar:

   1:#!/bin/bash
2:declare -ri MAX=999999
3:for ((i=0; i <= MAX; i++))
4:do
5: printf "Counter: %i\n" $i
6: sleep 10
7:done

El programa que lo arranca:

   1:#!/usr/bin/perl -w
2:
3:use strict;
4:use File::Basename;
5:use Sys::Hostname;
6:
7:if (scalar(@ARGV) <= 0) {
8: die "Provide the full path of the program to be executed!";
9:}
10:
11:use constant LOCKDIR => "/tmp";
12:
13:my $currentHost = hostname;
14:
15:my $progName = basename($ARGV[0]);
16:printf "Executing '%s'\n", $progName;
17:my $lockfile = LOCKDIR . "/" . $progName . ".lock";
18:# There is a lockfile, but is the process really running?
19:if ( -f $lockfile ) {
20: my ($pid, $hostname, $prog);
21: open(LOCK, "$lockfile") || die "$@, $!";
22: while(<LOCK>) {
23: ($pid, $hostname, $prog) = split(";", $_);
24: }
25: close(LOCK);
26: my $cnt = kill 0, $pid;
27: if ($cnt != 0) {
28: die "Sorry, but the programm $progName is already running as the PID: $pid"
29: }
30:}
31:open(LOCK, "> $lockfile") || die "$@, $!";
32:print LOCK ("$$" . ";" . $currentHost . ";" . $progName);
33:close(LOCK);
34:my $prog = shift(@ARGV);
35:exec("$prog", @ARGV);
36:__END__
37:=head1 NAME
38:
39:Run a single instance of a UNIX process, leaving information behind
40:to ease its termination.
41:
42:=head1 DESCRIPTION
43:
44:Will run the desired command and will create a lock file. To kill the program,
45:either use the information on the lock file or call the smart_kill script
46:
47:To run a program:
48:
49:./smart_run.pl script.sh
50:
51:To run on the background:
52:
53:./smart_run.pl script.sh &
54:
55:=head1 AuTHOR
56:
57:Jose Vicente Nunez Zuleta
58:
59:=head1 BLOG
60:
61:KodeGeeK - http://kodegeek.com
62:
63:=head1 LICENSE
64:
65:LGPL
66:
67:=cut

Y el programa que lo mata:

   1:#!/usr/bin/perl
2:
3:use strict;
4:use File::Basename;
5:use Sys::Hostname;
6:
7:if (scalar(@ARGV) != 1) {
8: die "Provide the name of the program to be killed!";
9:}
10:
11:use constant LOCKDIR => "/tmp";
12:
13:my $currentHost = hostname;
14:
15:my $progName = $ARGV[0];
16:my $lockfile = LOCKDIR . "/" . $progName . ".lock";
17:# There is a lockfile, but is the process really running?
18:if ( -f $lockfile ) {
19: printf "Trying to kill '%s'\n", $progName;
20: my ($pid, $hostname, $prog);
21: open(LOCK, "$lockfile") || die "$@, $!";
22: while(<LOCK>) {
23: ($pid, $hostname, $prog) = split(";", $_);
24: }
25: close(LOCK);
26: my $cnt = kill 6, $pid;
27: if ($cnt != 0) {
28: printf "process %i killed\n", $pid;
29: unlink $lockfile;
30: } else {
31: printf "Unable to kill %i\n", $pid;
32: exit 192;
33: }
34:}
35:__END__
36:=head1 NAME
37:
38:Terminates a single instance of a UNIX process, if it was started by smart_run.pl
39:It will kill the process only if the current process name and host matches what is
40:inside the lock file (and also if you are the owner of the process).
41:
42:To kill a program:
43:
44:./smart_kill.pl script.sh
45:
46:(Note than the full path of the script is not required, just the name).
47:
48:=head1 AuTHOR
49:
50:Jose Vicente Nunez Zuleta
51:
52:=head1 BLOG
53:
54:KodeGeeK - http://kodegeek.com
55:
56:=head1 LICENSE
57:
58:LGPL
59:
60:=cut

Una salida de ejemplo de los dos programas en acción:

[josevnz@localhost perl]$ ./smart_run.pl /home/josevnz/do_nothing.sh &
[1] 7998
[josevnz@localhost perl]$ Executing ‘do_nothing.sh’
Counter: 0
[josevnz@localhost perl]$ ./smart_kill.pl do_nothing.sh
Trying to kill ‘do_nothing.sh’
process 7998 killed
Aborted
[josevnz@localhost perl]$

Me tomó 30 minutos hacer los dos scripts (usted es más inteligente, así que seguro le tomará menos). Los scripts no son perfectos y de hecho pudieramos pensar en tener uno sólo que haga las dos cosas en vez de dos.

¿Como los mejoraría usted?. Como siempre se puede bajar el código desde aquí.

Buscar en Technorati:

Trucos UNIX: ¿Guardando la salida de todo lo que se hace?


Imaginemos que usted está trabajando en algo que requiere toda su atención y que usted no quiere olvidar ningún detalle de que fué lo que hizo; Si bien en Bash el comando “history” le va a decir que fué la última lista de cosas que usted introdujo por el teclado, no le va a guardar la salida de esos comandos al menos que los redirija a un archivo.

En esos casos lo mejor es usar el comando ‘script‘:

[josevnz@localhost ~]$ script -f
Script started, file is typescript
[josevnz@localhost ~]$ ls
bash company ebay jars mock-screens perl rpm workspace
bin cvs flickrapi-1.0a3 java mp3 public_html shopping xmlrpc-1.2-b1
blog data fotos jedit mysql_backup redhat specs
book Desktop googleapi lehman opensource remotetea src
c++ docs gpg lib outsourcing reports tmp
certification dshield html man passwords resume typescript
[josevnz@localhost ~]$ ps -ef|grep root
root 1 0 0 09:50 ? 00:00:01 init [5]
root 2 1 0 09:50 ? 00:00:00 [ksoftirqd/0]
root 3 1 0 09:50 ? 00:00:00 [watchdog/0]
root 4 1 0 09:50 ? 00:00:00 [events/0]
root 5 1 0 09:50 ? 00:00:00 [khelper]
root 6 1 0 09:50 ? 00:00:00 [kthread]
[josevnz@localhost ~]$ df -k
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
27297988 6594116 19294848 26% /
/dev/hda1 101086 9950 85917 11% /boot
/dev/shm 253532 0 253532 0% /dev/shm
[josevnz@localhost ~]$ exit
Script done, file is typescript

Todo el contenido de la sesión está en el archivo ‘typescript‘. Allí están todos los comandos, con una característica y es que script va a guardar tambien la ejecución de teclas como backspace, enter, etc. Sin embargo eso no le resta utilidad ya que usted pudiera usarlo para ‘monitorear’ lo que un usuario está haciendo en tiempo real en una ventana mientras usted lo vigila con ‘tail -f typescript

Ahora veamos otro problema y su solución. ¿Nunca le ha pasado que quiere correr un comando y quiere guardar los errores y la salida normal en un archivo, pero a la vez quiere ver la salida en tiempo real? Usted pudiera ejecutar el comando en una ventana así por ejemplo:

find / -type f > /tmp/findlog-$$.log 2>&1 (en una ventana)
tail -f /tmp/findlog-*.log (en otra ventana, fijese como tenemos que adivinar el nombre completo de la bitacora, por el $$ anterior que significa el número del proceso actual)

Pero usted, como un usuario superpoderozo de UNIX dice: No joda, yo le pongo una “T” (pronunciado en Inglés como Ti) a eso:

find / -type f 2>&1 | tee /tmp/findlog-$$.log

Tee va a tomar STDIN y lo va a imprimir por STDOUT (pantalla) y al archivo que usted diga (/tmp/findlog-$$.log).

Hoy usted aprendió dos comandos que muchas veces son olvidados en UNIX: script y tee. Espero le sean de utilidad 🙂

Buscar en Technorati: ,

Echando código: ¿Como hacer web-scrapping con Perl?

Web-scrapping no es un término nuevo, y no es más que procesar una página web utilizando un lenguaje de programación; La idea es eliminar el HTML (presentación) que no nos interesa para luego procesar los datos que están en la pagína web.

Típicamente esta era una de las alternativas usadas por los desarrolladores antes de la venida de los “Web services” or fees en XML como Atom o RSS. Su uso aún es muy difundido, ya que no todos los sitios web proveen la información de manera amigable para programas, por diversas razones.

Perl es una maravilla en ese sentido, ya que es casi trivial sacar la información usando expresiones regulares; Sin embargo si la página es compleja ni siquiera la mejor de las expresiones regulares va a ayudar.

Vamos a hacer un programita que haga lo siguiente:

  • Vaya a la página de los últimos 100 actualizados de VeneBlogs y se traiga el contenido
  • Nos imprima el titulo de la página y el URL de verdad. Veneblogs tiene un enlace el cual oculta el URL de verdad (y con el cual seguro miden el tráfico) pero nosotros queremos el URL real de el sitio web.

¿Suena interesante? Es una aplicación sencilla, pero eso le dará una idea de las cosas que se pueden hacer con Web Scraping y Perl; La estrategía aqui es identificar el pedazo de código HTML en donde podemos localizar nuestra información sin equivocarnos y luego sacarla de allí.

Revizando el URL de los “top100” de VeneBlogs, podemos ver que el HTML es muy limpio y que es bastante sencillo identificar en donde está la información de los usuarios:

   1:<div id="innercontent">
2: <h2>&Uacute;ltimos 100 Blogs Actualizados</h2>
3: <p><strong>NOTA:</strong> Todas las horas están en el huso
horario venezolano (UTC - 4.00 h).</p>
4: <dl>
5: <dd><a title="Veneblogs - Directorio de Blogs de Venezuela - Enlace
Externo hacia Diario de un poeta gris" href="/?redidblog=1580" onmouseover=" window.status='
http://poetagris.blogspot.com'; return true" onmouseout="window.status=''; return true">
Diario de un poeta gris</a></dd>
6:<dt>Fecha de Actualización : 08/13/05 -- 11:16:45 am</dt>
7:
8:<dd><a title="Veneblogs - Directorio de Blogs de Venezuela - Enlace Externo
hacia El Tecnorrante" href="/?redidblog=584" onmouseover=" window.status='
http://atorrante.blogspot.com'; return true" onmouseout="window.status=''; return true"
>El Tecnorrante</a></dd>
9:<dt>Fecha de Actualización : 08/13/05 -- 11:06:52 am</dt>
10:<dd><a title="Veneblogs - Directorio de Blogs de Venezuela - Enlace Externo
hacia MagicVenezuela.com" href="/?redidblog=2660" onmouseover=" window.status='
http://www.magicvenezuela.com'; return true" onmouseout="window.status=''; return true"
>MagicVenezuela.com</a></dd>
11:<dt>Fecha de Actualización : 08/13/05 -- 10:55:55 am</dt>

¿Que herramientas necesitamos en Perl? Vamos a utilizar un parser de HTML, llamado HTML::Parser. E mi caso este no estaba instalado en Fedora Core 4, así que lo mandamos a instalar (you voy a utilizar CPAN):

perl -MCPAN -e’install HTML::Parse’

El otro módulo a usar es LWP::UserAgent y es quien nos va a permitir bajarnos el URL. En mi caso ya está instalado en Fedora Core 4, pero si no lo tiene entonces repita los pasos anteriores para instalar un módulo de CPAN.

La técnica tiene sus problemas; Si el HTML es complicado, o está mal escrito o cambia con frecuencia, tratar de sacar los datos de esta manera puede ser una pesadilla (no hay almuerzo grátis). En fin, el código:

   1:#!/usr/bin/perl
2:
3:use strict;
4:use LWP::UserAgent;
5:
6:# Be carefull with this one as nested elements can be ignored and
7:# HTML normally is not well formed!
8:my @ignore_tags = (
9: "head",
10: "h1",
11: "strong",
12: "form"
13: );
14:my ($title, $url);
15:
16:# Define the "format" header we will use for printing:
17:format STDOUT_TOP =
18:@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
19:"Blog title:", "URL:"
20:---------------------------------------------------------------- ----------------------------------
21:.
22:format STDOUT =
23:@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
24:$title, $url
25:.
26:
27:use constant URL_TOP100_VENEBLOGS
28: => "http://www.veneblogs.com/feeds/ultimos100.php";
29:use constant DEFAULT_TIMEOUT
30: => 180;
31:
32:my $agent = LWP::UserAgent->new({
33: agent => 'get_veneblogs_top100.plx/kodegeek 0.1',
34: timeout => DEFAULT_TIMEOUT
35: });
36:my $response = $agent->get(URL_TOP100_VENEBLOGS);
37:if (! $response->is_success) {
38: die "[ERROR]: Unable to retrieve the HTML from '" . URL_TOP100_VENEBLOGS .
39: "', Status: '" . $response->status_line . "'";
40:}
41:my $parser = HTML::Parser->new(
42: api_version => 3,
43: start_h => [ \&start_a, "tagname, attr" ]
44: );
45:$parser->ignore_tags(@ignore_tags);
46:$parser->parse($response->decoded_content());
47:
48:# ****** Functions used on the script *******
49:# Callback function used to print the contents of the HTML file
50:sub start_a {
51: my $tagname = $_[0];
52: my %attr = %{$_[1]};
53: if ( ($tagname eq "a") && ($attr{title} =~ m#veneblogs#i) ) {
54: $attr{title} =~ m#enlace externo hacia (.*)#i;
55: $title = $1;
56: $attr{onmouseover} =~ m#http://(.*)';#;
57: $url = $1;
58: if ( (length($title) == 0) || (length($url) == 0) ) {
59: return;
60: }
61: #printf "%s, %s\n", $title, $url;
62: write;
63: }
64:}
65:__END__
66:=head1 NAME
67:
68:get_veneblogs_top100.plx - Get the VeneBlog Top 100 list as text.
69:
70:=head1 DESCRIPTION
71:
72:This script will download show the Blog name and the URL for the "100 TOP" Blogs of Veneblogs; Each
73:blog title will be show along with their real URL.
74:
75:=head1 AUTHOR
76:
77:Jose Vicente Nunez Zuleta (josevnz@yahoo.com)
78:
79:=head1 BLOG
80:
81:KodeGeek - http://kodegeek.com
82:
83:=head1 LICENSE
84:
85:GPL
86:
87:cut

La salida de ejemplo:


Blog title: URL:
---------------------------------------------------------------- ----------------------------------
>> Rozanel www.rozanel.blogspot.com
Brea... www.carlosbrea.com
El Blog De Juancho juan-casanas.blogspot.com
Hedonista reprimida en busca del nirvana canelita.blogspot.com
rubenologia.net www.rubenologia.net
BlogaCine | Blog Venezolano sobre Cine www.blogacine.com
quieto quieto.motocine.com/
La Taguarita taguarita.blogspot.com
unocontodo light unocontodo.blogspot.com/
Da Vinci's Element. Artes & Tecnologia dvinci.outnloud.net

Hay varias referencias obscuras en el código; Entre ellas:

  • El uso de Expresiones regulares para terminar de obtener los valores deseados de los atributos ‘title‘ y ‘onmouseover‘ de la etiqueta ‘a‘ en el HTML.
  • El uso de reportes en Perl, para obtener una salida formateada

En pocas palabras, le sale estudiar ;). Le recomiendo que se lea las siguientes páginas man: LPW::UserAngent, HTML::Parser, perlre, perlform.

En un próximo articulo les voy a mostrar como hacer lo mismo pero con Java y utilizando un enfoque un poco menos tradicional (el cual también puede ser aplicado a Perl, pero me provocó jugar con Java esta vez :D). Puede bajarse el código de aqui.

Buscar en Technorati: , cpan

Trucos UNIX: ¿Como ver la lista de directorios rápidamente?

Este es el tipo de cosas que uno necesita hacer rápido, así que ¿por donde empezar?. Supongamos que sólo quiero ver los directorios y nada más.

Bueno, el clásico: Usando ls y grep:


[josevnz@localhost ~]$ ls -l /|egrep "^drwx"
drwxr-xr-x 2 root root 4096 Jun 29 20:45 bin
drwxr-xr-x 4 root root 1024 Jun 19 22:09 boot
drwxr-xr-x 11 root root 5040 Aug 13 07:52 dev
drwxr-xr-x 82 root root 12288 Aug 13 07:51 etc
drwxr-xr-x 3 root root 4096 Jun 19 22:39 home
drwxr-xr-x 11 root root 4096 Jun 29 20:41 lib
drwx------ 2 root root 16384 Jun 19 18:04 lost+found
drwxr-xr-x 4 root root 4096 Aug 13 07:51 media
drwxr-xr-x 2 root root 0 Aug 13 07:51 misc
drwxr-xr-x 4 root root 4096 Jul 17 23:43 mnt
drwxr-xr-x 2 root root 0 Aug 13 07:51 net
drwxr-xr-x 2 root root 4096 May 23 00:28 opt
drwxr-x--- 17 root root 4096 Aug 10 06:36 root
drwxr-xr-x 2 root root 12288 Jun 29 20:45 sbin
drwxr-xr-x 1 root root 0 Aug 13 03:50 selinux
drwxr-xr-x 2 root root 4096 May 23 00:28 srv
drwxr-xr-x 10 root root 0 Aug 13 03:50 sys
drwxrwxrwt 13 root root 4096 Aug 13 15:08 tmp
drwxr-xr-x 15 root root 4096 Jun 22 21:46 usr
drwxr-xr-x 22 root root 4096 Jun 19 22:26 var

Me da mucha información y sólo los directorios.
Otra forma, usando ‘find’:

[josevnz@localhost ~]$ find / -maxdepth 1 -type d
/
/boot
/usr
/lib
/opt
/selinux
/dev
/var
/root
/sbin
/srv
/tmp
/misc
/media
/etc
/bin
/mnt
/lost+found
/proc
/home
/net
/sys

Así sólo veo los directorios. ¿Que pasa si le agrega la opción ‘-ls’?

Quizas pudiera usar el programa ‘tree’ pero no viene instalado por omisión (y usted lo que queria era resolver el problema rápido, ¿no es así?)

¿Como lo haría usted, pero rápido?

Buscar en Technorati:

Echando código: Las mejores prácticas al desarrollar aplicaciones web

Hace unos días coloqué en JavaVen la siguiente pregunta: ¿Cuales son las mejores prácticas para organizar el código en proyectos grandes de aplicaciones Web?. No obtuve respuesta y al principio eso me molestó un poco, ya que en teoría es una situación con la que todos los que han desarrollado aplicaciones web han pasado más de una vez.

¿Pero es totalmente cierto? Es decir, ¿es una experiencia que se repite tanto que se pueden sacar patrones?

Si y no; Hay elementos comunes, pero por otro lado, cada proyecto es una experiencia única, con requerimientos propios los cuales vienen de la cultura de la organización en las cuales deben ser implementados. En mi experiencia, esa “danza” o protocolo es mucho mayor en compañias grandes que en compañias pequeñas en las cuales la informalidad predomina; Y no es que que por ser “grandes” sean más burocraticas, sino que las compañias grandes necesitan un esqueleto más fuerte para soportar las múltiples interacciones entre clientes y desarrolladores.

Si bien la meta de una organización es hacer que el negocio prospere (y el software es sólo un medio), no se puede negar que un patrón efectivo de desarrollo de aplicaciones web es deseable, no sólo por elegancia sino porque lo que se busca al final es que el exito de un proyecto sea algo repetible.

Al final yo y otros miembros mucho más experimentados que yo del equipo discutimos y acordamos como resolver este problema en particular; Todos estabamos claros que una fundación fuerte es necesaria pero por otro lado no queriamos ahogarnos en detalles burocraticos, porque lo que importa es hacer el trabajo.

¿Y porqué nadie respondió en JavaVen? ¿No saben, les da ladilla o qué fué lo que pasó?. Echar código, o pensar en arquitecturas es glamoroso; Yo pienso que es dificil salir de nuestra zona de comodidad para hacer cosas que nos molestan, entre ellas pensar en como organizar mejor el código. Otra posibilidad es que planear con anterioridad algo tan grande es dificil y como es una experiencia muy particular no es muy útil proponer un lineamiento.

De cualquier modo no tener respuestas a veces es bueno, porque nos obliga a pensar 🙂

En mi busqueda me conseguí con 3 enlaces que me parecieron muy relevantes. Seguro hay más por allí, pero en mi opinión son un buen punto de partida:

Buscar en Technorati: