joe di castrohttp://joedicastro.com2012-10-19T22:40:00+02:00Productividad & Linux: Ncdu2012-10-19T22:40:00+02:00joe di castrohttp://joedicastro.com/productividad-linux-ncdu.html<p>Esta es una pequeña aplicación que sigue la máxima de <a href="http://es.wikipedia.org/wiki/Douglas_McIlroy">Doug Mcllroy</a> que acabaría resumiendo la filosofía Unix <em>"Escribe programas que hagan una sola cosa y que la hagan bien"</em>. Y siguiendo la línea de los programas que engloban esta serie de productividad sobre Linux, es un programa de consola que se maneja íntegramente con el teclado, y donde además los atajos están inspirados en los de <a href="http://www.vim.org/">Vim</a>.</p> <h2 id="ncdu">Ncdu</h2> <p><a href="http://dev.yorhel.nl/ncdu">Ncdu</a> es un acrónimo para "NCurses Disk Usage", es decir, "Uso de disco con interfaz ncurses". Lo que pretendía <a href="https://github.com/yorhel">Yoran Heling</a>, su autor, cuando creo <strong>ncdu</strong>, era obtener un analizador de uso de disco en consola que fuera lo suficientemente ligero para poder emplearlo en un servidor remoto a través de <a href="https://es.wikipedia.org/wiki/Ssh">ssh</a>. El gran acierto fue emplear la interfaz <a href="https://es.wikipedia.org/wiki/Ncurses">ncurses</a> para poder navegar por los directorios con extrema facilidad al mismo tiempo que se presentaba la información en un formato legible y amigable. El segundo y no menos importante acierto, es emplear los conocidos atajos de teclado de Vim para navegar entre los directorios.</p> <p>El resultado es un analizador de ocupación de disco que es realmente útil, agradable de utilizar y que es tan rápido y ligero que se puede emplear sin interfaz gráfica y en maquinas remotas. Es una gran ayuda para los administradores de sistemas, que hasta ahora nos teníamos que pelear con otras herramientas bastante menos agradables. Es la típica herramienta que cuando la utilizas por primera vez piensas ¿Por qué demonios no la habría encontrado antes?</p> <p style="text-align:center;"><img src="pictures/ncdu.png" width="700" height="559" alt="ncdu" /></p> <p>Como se puede ver la interfaz es muy limpia y carece de elementos superfluos que nos distraigan de lo importante, un pecado que cometen algunas de las aplicaciones gráficas más famosas, que cuentan con unos gráficos muy bonitos, pero realmente no demasiado útiles. Es sencillisima de emplear una vez que conoces los atajos y cuenta con ayuda integrada a la que se accede pulsando <strong><code>?</code></strong>. Incluso para aquellos que no están acostumbrados a navegar empleando las típicas teclas de vim (<strong>h</strong>, <strong>j</strong>, <strong>k</strong>, <strong>l</strong>), se pueden utilizar las teclas de dirección.</p> <h3 id="caracter+sticas">Características</h3> <p>Un programa de este tipo no necesita una funcionalidad muy elevada, pero destacare aquí algunas de las posibilidades que nos ofrece:</p> <ul> <li>Podemos ordenar los directorios/ficheros en función de su nombre o de su tamaño y en orden ascendente o descendente </li> <li>Se pueden eliminar directamente ficheros o directorios desde la aplicación, aunque también podemos iniciarla en modo solo lectura para prevenir borrados accidentales</li> <li>Se muestra o no, el porcentaje de espacio ocupado de forma gráfica y/o numérica</li> <li>El espacio empleado en disco puede hacer referencia al real o al aparente</li> <li>Los directorios y ficheros ocultos pueden ser o no mostrados</li> <li>Nos permite recalcular el espacio ocupado de un directorio concreto sin necesidad de volver a recalcular todo </li> <li>Tenemos la posibilidad de volcar la información a un archivo, que puede también ser leído por el mismo programa</li> <li>Es posible mostrar la información de un elemento individual en un cuadro emergente</li> </ul> <p>La verdad es que lo único que hecho en falta en el programa es quizás un poco de color para distinguir entre ficheros y directorios de forma más visual. Por lo demás, es muy rápido calculando el espacio, no he hecho una comparación directa, pero me parece ligeramente más rápido que Baobab.</p> <h3 id="alternativas">Alternativas</h3> <p>Existen varias alternativas decentes como aplicaciones gráficas, como los conocidos <a href="http://www.marzocca.net/linux/baobab/">Baobab</a> (que viene con las herramientas de Gnome) o <a href="http://www.jgoodies.com/freeware/jdiskreport/">JDiskReport</a>. Después existen múltiples alternativas tanto en modo gráfico como en modo consola que, sinceramente, no puedo recomendar a nadie, bien porque son más vistosos que prácticos o bien porque son directamente insufribles. Existe una alternativa en modo texto que algunos prefieren a ncdu que es <a href="http://gt5.sourceforge.net/">gt5</a>.</p>Monitorizar los cambios de tamaño en un directorio2011-05-17T21:52:00+02:00joe di castrohttp://joedicastro.com/monitorizar-los-cambios-de-tamano-en-un-directorio.html<p>Cuando administramos varias maquinas <abbr title="Linux, Unix, Solaris, BSD, etc">UN*X</abbr> nos puede interesar el tener controlados los cambios de tamaño en algunos directorios determinados, para poder observar pautas de comportamiento o ver cambios inesperados, para solucionar los problemas cuando o antes de que se produzcan. Y aunque hay varias formas de realizar esto, incluso con demonios que monitorizan los cambios en tiempo real (incrond, inotify, dnotify, gamin, watch, ...), puede que una solución más sencilla nos sea suficiente para directorios no críticos. Para instalaciones no complejas nos puede servir, por ejemplo, para no tener que lidiar con las <a href="http://en.wikipedia.org/wiki/Disk_quota">quotas de disco</a> (no siempre es una buena opción). O para evitar que por ejemplo una mala configuración en la rotación de los logs de una maquina acaben agotando el espacio disponible para la partición de sistema (caso real que me he encontrado más de una vez). </p> <p>Para poder monitorizar los cambios de tamaño de un directorio (y subdirectorios) he creado un sencillo script <strong>Python</strong> que registra los cambios en la ruta que le proporcionemos y luego envía un informe por correo al buzón del usuario local. Los datos de los directorios los registra en un fichero oculto (su nombre empieza por un <code>.</code>) binario de tipo <a href="http://docs.python.org/library/pickle.html#module-pickle">pickle</a> y el informe se guarda a su vez en un archivo de texto con el mismo nombre que el script, pero terminado en <code>.log</code>. </p> <p>El informe que genera nos muestra por un lado tantos los nuevos directorios, como los directorios que se han eliminado con la cifra del espacio en disco que ocupan (o liberan). Por otro lado también nos informa de los directorios que han cambiado de tamaño, mostrándonos en que porcentaje se han incrementado/decrementado y la cantidad de espacio que ha variado. Aquí podemos ver un ejemplo de uno de estos informes.</p> <div class="codehilite"><pre>SCRIPT ========================================================================= dir_size_monitor (ver. 0.2) http://joedicastro.com Changes in size of directories for .. on yourmachine ================================================================================ START TIME ===================================================================== Tuesday 05/17/11, 21:10:48 ================================================================================ NEW DIRECTORIES ________________________________________________________________ 799.72 KiB ./src/test/bibendum 1.14 MiB ./src/test/condimentum 2.31 MiB ./src/test/laoreet 204.28 KiB ./src/test/risus 2.90 MiB ./src/test/torquent DELETED DIRECTORIES ____________________________________________________________ 383.79 KiB ./src/test/adipiscing 5.38 MiB ./src/test/consequat 847.72 KiB ./src/test/etiam 938.93 KiB ./src/test/maecenas 3.55 MiB ./src/test/tincidunt 2.33 MiB ./src/test/viverra CHANGED DIRECTORIES ____________________________________________________________ 34.79 % 55.5 MiB ./src 34.82 % 55.5 MiB ./src/test -99.97 % 15.3 MiB ./src/test/odio -99.97 % 15.6 MiB ./src/test/tellus THRESHOLD VALUES _______________________________________________________________ The directories whose size differences are less than any of these values are ignored: Percentage: 10 % Size: 10.00 MiB .. STATISTICS __________________________________________________________________ 78 directories 215.04 MiB END TIME ======================================================================= Tuesday 05/17/11, 21:10:48 ================================================================================ </pre></div> <p>Opcionalmente podemos establecer dos valores de umbral para que se ignoren todos los cambios que estén por debajo de estas dos cifras. Para desactivarlos simplemente hay que dejarlos a cero. Estas cifras se refieren por un lado al porcentaje de diferencia mínimo que deseamos establecer para que se nos informe y por otro a la cantidad mínima (expresada en bytes) de espacio en disco que se ha incrementado/decrementado en ese directorio. Pueden funcionar los dos a la vez, por lo que se han de cumplir las dos condiciones, o solamente uno dejando el otro a cero.</p> <p>Si programamos este script para que se ejecute cada cierto tiempo, podemos tener una idea aproximada de los cambios producidos en el. Y digo aproximada porque este nos muestra únicamente los cambios registrados entre dos <em>instantáneas</em> tomadas, una en la ejecución anterior y otra en la ejecución actual. Y por lo tanto no esperemos obtener la relación de todos los cambios producidas entre ellas. Para conocer algo a ese nivel de detalle es mejor emplear uno de los servicios en tiempo real que mencionaba al principio. Dicho esto, es evidente que en la primera ejecución no tiene sentido informar de nada y de hecho hasta la segunda ejecución no empezara a generar informes.</p> <p>Este es el contenido de <a href="https://github.com/joedicastro/python-recipes/blob/master/dir_size_monitor.py">dir_size_monitor.py</a> es el siguiente:</p> <div class="codehilite"><pre><span class="c">#!/usr/bin/env python</span> <span class="c"># -*- coding: utf8 -*-</span> <span class="sd">&quot;&quot;&quot;</span> <span class="sd"> dir_size_monitor.py: Monitors changes in the size of dirs for a given path</span> <span class="sd">&quot;&quot;&quot;</span> <span class="c">#===============================================================================</span> <span class="c"># This Script monitors the changes in disk size for the directories included in</span> <span class="c"># a given path. It reports what directories are new or deleted. Also reports the</span> <span class="c"># directories in which their size increases or decreases above threshold values.</span> <span class="c"># These threshold values refer to the amount in difference of size of the </span> <span class="c"># directory or/and the percentage difference. These values can be overrided by </span> <span class="c"># setting them to zero.</span> <span class="c">#</span> <span class="c"># The final report is sended via email to the local user. This script is </span> <span class="c"># intended to run periodically (e.g. via cron) </span> <span class="c">#===============================================================================</span> <span class="c">#===============================================================================</span> <span class="c"># Copyright 2011 joe di castro &lt;joe@joedicastro.com&gt;</span> <span class="c">#</span> <span class="c"># This program is free software: you can redistribute it and/or modify</span> <span class="c"># it under the terms of the GNU General Public License as published by</span> <span class="c"># the Free Software Foundation, either version 3 of the License, or</span> <span class="c"># (at your option) any later version.</span> <span class="c">#</span> <span class="c"># This program is distributed in the hope that it will be useful,</span> <span class="c"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span> <span class="c"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span> <span class="c"># GNU General Public License for more details.</span> <span class="c">#</span> <span class="c"># You should have received a copy of the GNU General Public License</span> <span class="c"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span> <span class="c">#===============================================================================</span> <span class="n">__author__</span> <span class="o">=</span> <span class="s">&quot;joe di castro &lt;joe@joedicastro.com&gt;&quot;</span> <span class="n">__license__</span> <span class="o">=</span> <span class="s">&quot;GNU General Public License version 3&quot;</span> <span class="n">__date__</span> <span class="o">=</span> <span class="s">&quot;17/05/2011&quot;</span> <span class="n">__version__</span> <span class="o">=</span> <span class="s">&quot;0.2&quot;</span> <span class="k">try</span><span class="p">:</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">platform</span> <span class="kn">import</span> <span class="nn">pickle</span> <span class="kn">import</span> <span class="nn">logger</span> <span class="kn">from</span> <span class="nn">get_size</span> <span class="kn">import</span> <span class="n">best_unit_size</span><span class="p">,</span> <span class="n">get_size_fast</span> <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span> <span class="c"># Checks the installation of the necessary python modules </span> <span class="k">print</span><span class="p">((</span><span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s">&quot;An error found importing one module:&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">1</span><span class="p">]),</span> <span class="s">&quot;You need to install it&quot;</span><span class="p">,</span> <span class="s">&quot;Stopping...&quot;</span><span class="p">]))</span> <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span> <span class="k">def</span> <span class="nf">list4log</span><span class="p">(</span><span class="n">dirs_size_dict</span><span class="p">,</span> <span class="n">wpath</span><span class="p">,</span> <span class="n">dirs</span><span class="p">):</span> <span class="sd">&quot;&quot;&quot;Create a list of new or deleted directories for the log.&quot;&quot;&quot;</span> <span class="n">llst</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">ldir</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">dirs</span><span class="p">):</span> <span class="n">dsz</span> <span class="o">=</span> <span class="n">best_unit_size</span><span class="p">(</span><span class="n">dirs_size_dict</span><span class="p">[</span><span class="n">ldir</span><span class="p">])</span> <span class="n">llst</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot; {0:8.2f} {1} ./{2}&quot;</span><span class="o">.</span> <span class="n">format</span><span class="p">(</span><span class="n">dsz</span><span class="p">[</span><span class="s">&#39;s&#39;</span><span class="p">],</span> <span class="n">dsz</span><span class="p">[</span><span class="s">&#39;u&#39;</span><span class="p">],</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">ldir</span><span class="p">,</span> <span class="n">wpath</span><span class="p">)))</span> <span class="k">return</span> <span class="n">llst</span> <span class="k">def</span> <span class="nf">diff4log</span><span class="p">(</span><span class="n">before</span><span class="p">,</span> <span class="n">current</span><span class="p">,</span> <span class="n">wpath</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">threshold_pct</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">threshold_sz</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span> <span class="sd">&quot;&quot;&quot;Create a list of the directories that had size changes for the log.&quot;&quot;&quot;</span> <span class="n">llst</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">ddir</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">dirs</span><span class="p">):</span> <span class="n">pct</span> <span class="o">=</span> <span class="p">(((</span><span class="n">current</span><span class="p">[</span><span class="n">ddir</span><span class="p">]</span> <span class="o">-</span> <span class="nb">float</span><span class="p">(</span><span class="n">before</span><span class="p">[</span><span class="n">ddir</span><span class="p">]))</span> <span class="o">/</span> <span class="n">before</span><span class="p">[</span><span class="n">ddir</span><span class="p">])</span> <span class="o">*</span> <span class="mf">100.0</span><span class="p">)</span> <span class="n">diff</span> <span class="o">=</span> <span class="n">current</span><span class="p">[</span><span class="n">ddir</span><span class="p">]</span> <span class="o">-</span> <span class="n">before</span><span class="p">[</span><span class="n">ddir</span><span class="p">]</span> <span class="k">if</span> <span class="nb">abs</span><span class="p">(</span><span class="n">pct</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">threshold_pct</span> <span class="ow">and</span> <span class="nb">abs</span><span class="p">(</span><span class="n">diff</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">threshold_sz</span><span class="p">:</span> <span class="n">dsz</span> <span class="o">=</span> <span class="n">best_unit_size</span><span class="p">(</span><span class="n">diff</span><span class="p">)</span> <span class="n">llst</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot; {0:8.2f} % {1:8.1f} {2} ./{3}&quot;</span><span class="o">.</span> <span class="n">format</span><span class="p">(</span><span class="n">pct</span><span class="p">,</span> <span class="n">dsz</span><span class="p">[</span><span class="s">&#39;s&#39;</span><span class="p">],</span> <span class="n">dsz</span><span class="p">[</span><span class="s">&#39;u&#39;</span><span class="p">],</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">ddir</span><span class="p">,</span> <span class="n">wpath</span><span class="p">)))</span> <span class="k">return</span> <span class="n">llst</span> <span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">first_exec</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span> <span class="sd">&quot;&quot;&quot;Main section&quot;&quot;&quot;</span> <span class="c"># The path to monitor changes in directories dir_size</span> <span class="n">mon_pth</span> <span class="o">=</span> <span class="s">&quot;/your/path/to/monitor&quot;</span> <span class="c"># Ignore all directories that are below these percentage or absolute value </span> <span class="c"># of size difference. There are optional, set to zero to override them.</span> <span class="n">thld_pct</span> <span class="o">=</span> <span class="mi">20</span> <span class="c"># In percentage of difference in size for a directory</span> <span class="n">thld_sz</span> <span class="o">=</span> <span class="mf">10.486E6</span> <span class="c"># In bytes of absolute value of directory size difference</span> <span class="c"># Prepare the log</span> <span class="n">log</span> <span class="o">=</span> <span class="n">logger</span><span class="o">.</span><span class="n">Logger</span><span class="p">()</span> <span class="n">url</span> <span class="o">=</span> <span class="s">&quot;http://joedicastro.com&quot;</span> <span class="n">head</span> <span class="o">=</span> <span class="p">(</span><span class="s">&quot;Changes in size of directories for {0} on {1}&quot;</span><span class="o">.</span> <span class="n">format</span><span class="p">(</span><span class="n">mon_pth</span><span class="p">,</span> <span class="n">platform</span><span class="o">.</span><span class="n">node</span><span class="p">()))</span> <span class="n">log</span><span class="o">.</span><span class="n">header</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">head</span><span class="p">)</span> <span class="n">log</span><span class="o">.</span><span class="n">time</span><span class="p">(</span><span class="s">&quot;START TIME&quot;</span><span class="p">)</span> <span class="c"># Load the last dictionary of directories/sizes if exists</span> <span class="k">try</span><span class="p">:</span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;.dir_sizes.pkl&#39;</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">input_file</span><span class="p">:</span> <span class="n">bfr_dir</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">input_file</span><span class="p">)</span> <span class="k">except</span> <span class="p">(</span><span class="ne">EOFError</span><span class="p">,</span> <span class="ne">IOError</span><span class="p">,</span> <span class="n">pickle</span><span class="o">.</span><span class="n">PickleError</span><span class="p">):</span> <span class="n">bfr_dir</span> <span class="o">=</span> <span class="p">{}</span> <span class="n">first_exec</span> <span class="o">=</span> <span class="bp">True</span> <span class="c"># Get the current dictionary of directories/sizes</span> <span class="n">crr_dir</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">path</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">files</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">mon_pth</span><span class="p">):</span> <span class="k">for</span> <span class="n">directory</span> <span class="ow">in</span> <span class="n">dirs</span><span class="p">:</span> <span class="n">dir_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">directory</span><span class="p">)</span> <span class="n">dir_size</span> <span class="o">=</span> <span class="n">get_size_fast</span><span class="p">(</span><span class="n">dir_path</span><span class="p">)</span> <span class="n">crr_dir</span><span class="p">[</span><span class="n">dir_path</span><span class="p">]</span> <span class="o">=</span> <span class="n">dir_size</span> <span class="c"># First, Save the current dirs/sizes</span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">&quot;.dir_sizes.pkl&quot;</span><span class="p">,</span> <span class="s">&quot;wb&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">output_file</span><span class="p">:</span> <span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">crr_dir</span><span class="p">,</span> <span class="n">output_file</span><span class="p">)</span> <span class="c"># Create the list depending the status of directories</span> <span class="n">deleted</span> <span class="o">=</span> <span class="p">[</span><span class="n">d</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">bfr_dir</span> <span class="k">if</span> <span class="n">d</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">crr_dir</span><span class="p">]</span> <span class="n">added</span> <span class="o">=</span> <span class="p">[</span><span class="n">d</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">crr_dir</span> <span class="k">if</span> <span class="n">d</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">bfr_dir</span><span class="p">]</span> <span class="n">changed</span> <span class="o">=</span> <span class="p">[</span><span class="n">d</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">crr_dir</span> <span class="k">if</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">bfr_dir</span> <span class="k">if</span> <span class="n">crr_dir</span><span class="p">[</span><span class="n">d</span><span class="p">]</span> <span class="o">!=</span> <span class="n">bfr_dir</span><span class="p">[</span><span class="n">d</span><span class="p">]]</span> <span class="n">log</span><span class="o">.</span><span class="n">list</span><span class="p">(</span><span class="s">&quot;Deleted directories&quot;</span><span class="p">,</span> <span class="n">list4log</span><span class="p">(</span><span class="n">bfr_dir</span><span class="p">,</span> <span class="n">mon_pth</span><span class="p">,</span> <span class="n">deleted</span><span class="p">))</span> <span class="n">log</span><span class="o">.</span><span class="n">list</span><span class="p">(</span><span class="s">&quot;New directories&quot;</span><span class="p">,</span> <span class="n">list4log</span><span class="p">(</span><span class="n">crr_dir</span><span class="p">,</span> <span class="n">mon_pth</span><span class="p">,</span> <span class="n">added</span><span class="p">))</span> <span class="n">log</span><span class="o">.</span><span class="n">list</span><span class="p">(</span><span class="s">&quot;Changed directories&quot;</span><span class="p">,</span> <span class="n">diff4log</span><span class="p">(</span><span class="n">bfr_dir</span><span class="p">,</span> <span class="n">crr_dir</span><span class="p">,</span> <span class="n">mon_pth</span><span class="p">,</span> <span class="n">changed</span><span class="p">,</span> <span class="n">thld_pct</span><span class="p">,</span> <span class="n">thld_sz</span><span class="p">))</span> <span class="c"># If thresholds are nonzero, then report the values </span> <span class="k">if</span> <span class="n">thld_pct</span> <span class="ow">or</span> <span class="n">thld_sz</span><span class="p">:</span> <span class="n">tsz</span> <span class="o">=</span> <span class="n">best_unit_size</span><span class="p">(</span><span class="n">thld_sz</span><span class="p">)</span> <span class="n">log</span><span class="o">.</span><span class="n">list</span><span class="p">(</span><span class="s">&quot;Threshold Values&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;The directories whose size differences are less than any of &quot;</span> <span class="s">&quot;these values are ignored:&quot;</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="s">&quot;Percentage: {0:6} %&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">thld_pct</span><span class="p">),</span> <span class="s">&quot;Size: {0:6.2f} {1}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">tsz</span><span class="p">[</span><span class="s">&#39;s&#39;</span><span class="p">],</span> <span class="n">tsz</span><span class="p">[</span><span class="s">&#39;u&#39;</span><span class="p">])])</span> <span class="c"># Show some statistics for the analyzed path</span> <span class="n">mon_pth_sz</span> <span class="o">=</span> <span class="n">best_unit_size</span><span class="p">(</span><span class="n">get_size_fast</span><span class="p">(</span><span class="n">mon_pth</span><span class="p">))</span> <span class="n">log</span><span class="o">.</span><span class="n">list</span><span class="p">(</span><span class="s">&quot;{0} Statistics&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mon_pth</span><span class="p">),</span> <span class="p">[</span><span class="s">&quot;{0:8} directories&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">crr_dir</span><span class="p">)),</span> <span class="s">&quot;{0:8.2f} {1}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mon_pth_sz</span><span class="p">[</span><span class="s">&#39;s&#39;</span><span class="p">],</span> <span class="n">mon_pth_sz</span><span class="p">[</span><span class="s">&#39;u&#39;</span><span class="p">])])</span> <span class="n">log</span><span class="o">.</span><span class="n">time</span><span class="p">(</span><span class="s">&quot;END TIME&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">first_exec</span><span class="p">:</span> <span class="n">log</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&quot;Changes in size of directories&quot;</span><span class="p">)</span> <span class="n">log</span><span class="o">.</span><span class="n">write</span><span class="p">()</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span> <span class="n">main</span><span class="p">()</span> </pre></div> <p>Este script necesita los módulos <a href="http://joedicastro.com/conocer_el_tamano_de_un_directorio_con_python">get_size</a> y <a href="http://joedicastro.com/logger_informes_legibles_para_tus_scripts_python">logger</a> para poder funcionar. Solo es necesario descargar los archivos y guardarlos en el mismo directorio donde se aloje este script. La versión más actualizada de este script se puede encontrar en el repositorio <em>Python Recipes</em> alojado en <a href="http://github.com/joedicastro/python-recipes">github</a>.</p>Conocer el tamaño de un directorio con Python2011-05-16T21:05:00+02:00joe di castrohttp://joedicastro.com/conocer-el-tamano-de-un-directorio-con-python.html<p>Aunque conocer el tamaño de un directorio en sistemas como Linux es algo trivial, solo es necesario emplear el comando <code>du</code>, si queremos hacer lo mismo con <strong>Python</strong> -sin hacer uso de este comando- la cosa ya no es tan sencilla. Sobre todo si lo que queremos es una solución que nos devuelva tanto el tamaño de un fichero como el de un directorio. Cuando me encontré con esta necesidad lo primero que hice fue buscar en Internet para conocer alguna solución previa (reinventar la rueda no siempre es lo mejor) y me encontré con esto:</p> <div class="codehilite"><pre><span class="k">def</span> <span class="nf">get_dir_size</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="sd">&quot;&quot;&quot;Get size of a directory tree in bytes.&quot;&quot;&quot;</span> <span class="n">path_size</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">path</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">files</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="k">for</span> <span class="n">fil</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span> <span class="n">filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">fil</span><span class="p">)</span> <span class="n">path_size</span> <span class="o">+=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span> <span class="k">return</span> <span class="n">path_size</span> </pre></div> <p>Esta solución nos daría el tamaño en bytes de un directorio. Pero esta solución, que encontré en varios sitios, presentaba dos problemas:</p> <ul> <li> <p><strong>No da un tamaño exacto</strong>. Esto se debe a que no tiene en cuenta las carpetas y ficheros ocultos (los que empiezan con un <code>.</code> en Linux) y los ficheros especiales <code>..</code> (que apuntan al directorio superior). Además tampoco tiene en cuenta los enlaces simbólicos. Por está razón la salida de esta función no coincide con el espacio que nos reporta el comando <abbr title="Linux, Unix, Solaris, BSD, etc">UN*X</abbr> <code>du -bs</code></p> </li> <li> <p><strong>No funciona para un solo fichero</strong>. Solo trabaja cuando lo ejecutamos sobre un directorio, al hacerlo sobre un solo fichero nos dará como resultado siempre 0.</p> </li> </ul> <p>Teniendo en cuenta este punto de partida, elaboré una función que solucionara estos dos problemas y que devolviera el tamaño exacto de un directorio o fichero. Esta es la <strong>función que nos da el resultado correcto</strong>:</p> <div class="codehilite"><pre><span class="k">def</span> <span class="nf">get_size</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="sd">&quot;&quot;&quot;Get size of a directory tree or a file in bytes.&quot;&quot;&quot;</span> <span class="n">path_size</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">path</span><span class="p">,</span> <span class="n">directories</span><span class="p">,</span> <span class="n">files</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="k">for</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span> <span class="n">path_size</span> <span class="o">+=</span> <span class="n">os</span><span class="o">.</span><span class="n">lstat</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">filename</span><span class="p">))</span><span class="o">.</span><span class="n">st_size</span> <span class="k">for</span> <span class="n">directory</span> <span class="ow">in</span> <span class="n">directories</span><span class="p">:</span> <span class="n">path_size</span> <span class="o">+=</span> <span class="n">os</span><span class="o">.</span><span class="n">lstat</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">directory</span><span class="p">))</span><span class="o">.</span><span class="n">st_size</span> <span class="n">path_size</span> <span class="o">+=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="n">the_path</span><span class="p">)</span> <span class="k">return</span> <span class="n">path_size</span> </pre></div> <p>El resultado de esta función es el mismo que el que nos devuelve el comando Linux <code>du -bs</code>. Además tiene en cuenta los enlaces simbólicos y no los sigue. Luego buscando una <strong>solución ligeramente más rápida</strong> (aunque menos elegante y <em>pythonica</em>) y que siguiera dando resultados precisos, cree una variante basada en el empleo de generadores. </p> <div class="codehilite"><pre><span class="k">def</span> <span class="nf">get_size_fast</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="sd">&quot;&quot;&quot;Get size of a directory tree or a file in bytes.&quot;&quot;&quot;</span> <span class="k">def</span> <span class="nf">get_sizes</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="sd">&quot;&quot;&quot;Make a generator of individual file &amp; directory sizes.&quot;&quot;&quot;</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">islink</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="k">for</span> <span class="n">file_or_dir</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="n">path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">the_path</span><span class="p">,</span> <span class="n">file_or_dir</span><span class="p">)</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">path</span><span class="p">):</span> <span class="k">yield</span> <span class="n">os</span><span class="o">.</span><span class="n">lstat</span><span class="p">(</span><span class="n">path</span><span class="p">)</span><span class="o">.</span><span class="n">st_size</span> <span class="k">else</span><span class="p">:</span> <span class="k">for</span> <span class="n">size</span> <span class="ow">in</span> <span class="n">get_sizes</span><span class="p">(</span><span class="n">path</span><span class="p">):</span> <span class="k">yield</span> <span class="n">size</span> <span class="k">yield</span> <span class="n">os</span><span class="o">.</span><span class="n">lstat</span><span class="p">(</span><span class="n">the_path</span><span class="p">)</span><span class="o">.</span><span class="n">st_size</span> <span class="k">else</span><span class="p">:</span> <span class="k">yield</span> <span class="n">os</span><span class="o">.</span><span class="n">lstat</span><span class="p">(</span><span class="n">the_path</span><span class="p">)</span><span class="o">.</span><span class="n">st_size</span> <span class="k">return</span> <span class="nb">sum</span><span class="p">(</span><span class="n">get_sizes</span><span class="p">(</span><span class="n">the_path</span><span class="p">))</span> </pre></div> <h2 id="obtener_el_tama+o_del_directorio_en_la_mejor_unidad_posible">Obtener el tamaño del directorio en la mejor unidad posible</h2> <p>Estas funciones proporcionan el resultado que deseamos, pero lo entregan en una unidad difícilmente legible, en bytes. ¿Que ocurre si queremos verlo en <a href="http://es.wikipedia.org/wiki/Prefijo_binario">Mebibytes, GibiBytes</a>, ... y que además sea siempre la más adecuada para una mejor visualización? Para responder a esta pregunta desarrolle una función que nos hace precisamente esto, tomar un tamaño en bytes y devolvernos el valor correcto en la <a href="http://physics.nist.gov/cuu/Units/binary.html">unidad binaria IEC</a> más adecuada:</p> <div class="codehilite"><pre><span class="k">def</span> <span class="nf">best_unit_size</span><span class="p">(</span><span class="n">bytes_size</span><span class="p">):</span> <span class="sd">&quot;&quot;&quot;Get a size in bytes &amp; convert it to the best IEC prefix for readability.</span> <span class="sd"> Return a dictionary with three pair of keys/values:</span> <span class="sd"> &quot;s&quot; -- (float) Size of path converted to the best unit for easy read</span> <span class="sd"> &quot;u&quot; -- (str) The prefix (IEC) for s (from bytes(2^0) to YiB(2^80))</span> <span class="sd"> &quot;b&quot; -- (int / long) The original size in bytes</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">for</span> <span class="n">exp</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">90</span> <span class="p">,</span> <span class="mi">10</span><span class="p">):</span> <span class="n">bu_size</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="n">bytes_size</span><span class="p">)</span> <span class="o">/</span> <span class="nb">pow</span><span class="p">(</span><span class="mf">2.0</span><span class="p">,</span> <span class="n">exp</span><span class="p">)</span> <span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">bu_size</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">2</span> <span class="o">**</span> <span class="mi">10</span><span class="p">:</span> <span class="n">unit</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">:</span><span class="s">&quot;bytes&quot;</span><span class="p">,</span> <span class="mi">10</span><span class="p">:</span><span class="s">&quot;KiB&quot;</span><span class="p">,</span> <span class="mi">20</span><span class="p">:</span><span class="s">&quot;MiB&quot;</span><span class="p">,</span> <span class="mi">30</span><span class="p">:</span><span class="s">&quot;GiB&quot;</span><span class="p">,</span> <span class="mi">40</span><span class="p">:</span><span class="s">&quot;TiB&quot;</span><span class="p">,</span> <span class="mi">50</span><span class="p">:</span><span class="s">&quot;PiB&quot;</span><span class="p">,</span> <span class="mi">60</span><span class="p">:</span><span class="s">&quot;EiB&quot;</span><span class="p">,</span> <span class="mi">70</span><span class="p">:</span><span class="s">&quot;ZiB&quot;</span><span class="p">,</span> <span class="mi">80</span><span class="p">:</span><span class="s">&quot;YiB&quot;</span><span class="p">}[</span><span class="n">exp</span><span class="p">]</span> <span class="k">break</span> <span class="k">return</span> <span class="p">{</span><span class="s">&quot;s&quot;</span><span class="p">:</span><span class="n">bu_size</span><span class="p">,</span> <span class="s">&quot;u&quot;</span><span class="p">:</span><span class="n">unit</span><span class="p">,</span> <span class="s">&quot;b&quot;</span><span class="p">:</span><span class="n">bytes_size</span><span class="p">}</span> </pre></div> <p>Esta función nos devuelve un diccionario con tres claves:</p> <ul> <li><code>'s'</code>: Es el tamaño convertido a la mejor unidad IEC posible en términos de legibilidad.</li> <li><code>'u'</code>: Es el prefijo IEC para el tamaño anterior.</li> <li><code>'b'</code>: Es el tamaño original en bytes.</li> </ul> <p>Para entenderla, lo mejor es mostrar algunos ejemplos:</p> <div class="codehilite"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">get_size</span> <span class="gp">&gt;&gt;&gt; </span><span class="n">size</span> <span class="o">=</span> <span class="n">get_size</span><span class="o">.</span><span class="n">best_unit_size</span><span class="p">(</span><span class="mi">38467206502</span><span class="p">)</span> <span class="gp">&gt;&gt;&gt; </span><span class="s">&quot;{0:.2f} {1}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">size</span><span class="p">[</span><span class="s">&#39;s&#39;</span><span class="p">],</span> <span class="n">size</span><span class="p">[</span><span class="s">&#39;u&#39;</span><span class="p">])</span> <span class="go">&#39;35.83 GiB&#39;</span> <span class="gp">&gt;&gt;&gt; </span><span class="n">size</span> <span class="o">=</span> <span class="n">get_size</span><span class="o">.</span><span class="n">best_unit_size</span><span class="p">(</span><span class="mi">45332</span><span class="p">)</span> <span class="gp">&gt;&gt;&gt; </span><span class="s">&quot;{0:.2f} {1}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">size</span><span class="p">[</span><span class="s">&#39;s&#39;</span><span class="p">],</span> <span class="n">size</span><span class="p">[</span><span class="s">&#39;u&#39;</span><span class="p">])</span> <span class="go">&#39;44.27 KiB&#39;</span> <span class="gp">&gt;&gt;&gt; </span><span class="n">size</span> <span class="o">=</span> <span class="n">get_size</span><span class="o">.</span><span class="n">best_unit_size</span><span class="p">(</span><span class="mi">9878323</span><span class="p">)</span> <span class="gp">&gt;&gt;&gt; </span><span class="s">&quot;{0:.2f} {1} es igual a {2} bytes&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">size</span><span class="p">[</span><span class="s">&#39;s&#39;</span><span class="p">],</span> <span class="n">size</span><span class="p">[</span><span class="s">&#39;u&#39;</span><span class="p">],</span> <span class="n">size</span><span class="p">[</span><span class="s">&#39;b&#39;</span><span class="p">])</span> <span class="go">&#39;9.42 MiB es igual a 9878323 bytes&#39;</span> </pre></div> <p>Y evidentemente, combinar las dos funciones en una, nos evita tener que pasar las dos a un mismo directorio/fichero. </p> <div class="codehilite"><pre><span class="k">def</span> <span class="nf">get_unit_size</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="sd">&quot;&quot;&quot;Calculate size of a directory/file &amp; convert it for the best IEC prefix.</span> <span class="sd"> Return a dictionary with three pair of keys/values:</span> <span class="sd"> &quot;s&quot; -- (float) Size of path converted to the best unit for easy read</span> <span class="sd"> &quot;u&quot; -- (str) The prefix (IEC) for s (from bytes(2^0) to YiB(2^80))</span> <span class="sd"> &quot;b&quot; -- (int / long) The original size in bytes</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="n">bytes_size</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">path</span><span class="p">,</span> <span class="n">directories</span><span class="p">,</span> <span class="n">files</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">the_path</span><span class="p">):</span> <span class="k">for</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span> <span class="n">bytes_size</span> <span class="o">+=</span> <span class="n">os</span><span class="o">.</span><span class="n">lstat</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">filename</span><span class="p">))</span><span class="o">.</span><span class="n">st_size</span> <span class="k">for</span> <span class="n">directory</span> <span class="ow">in</span> <span class="n">directories</span><span class="p">:</span> <span class="n">bytes_size</span> <span class="o">+=</span> <span class="n">os</span><span class="o">.</span><span class="n">lstat</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">directory</span><span class="p">))</span><span class="o">.</span><span class="n">st_size</span> <span class="n">bytes_size</span> <span class="o">+=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="n">the_path</span><span class="p">)</span> <span class="k">for</span> <span class="n">exp</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">90</span> <span class="p">,</span> <span class="mi">10</span><span class="p">):</span> <span class="n">bu_size</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="n">bytes_size</span><span class="p">)</span> <span class="o">/</span> <span class="nb">pow</span><span class="p">(</span><span class="mf">2.0</span><span class="p">,</span> <span class="n">exp</span><span class="p">)</span> <span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">bu_size</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">2</span> <span class="o">**</span> <span class="mi">10</span><span class="p">:</span> <span class="n">unit</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">:</span><span class="s">&quot;bytes&quot;</span><span class="p">,</span> <span class="mi">10</span><span class="p">:</span><span class="s">&quot;KiB&quot;</span><span class="p">,</span> <span class="mi">20</span><span class="p">:</span><span class="s">&quot;MiB&quot;</span><span class="p">,</span> <span class="mi">30</span><span class="p">:</span><span class="s">&quot;GiB&quot;</span><span class="p">,</span> <span class="mi">40</span><span class="p">:</span><span class="s">&quot;TiB&quot;</span><span class="p">,</span> <span class="mi">50</span><span class="p">:</span><span class="s">&quot;PiB&quot;</span><span class="p">,</span> <span class="mi">60</span><span class="p">:</span><span class="s">&quot;EiB&quot;</span><span class="p">,</span> <span class="mi">70</span><span class="p">:</span><span class="s">&quot;ZiB&quot;</span><span class="p">,</span> <span class="mi">80</span><span class="p">:</span><span class="s">&quot;YiB&quot;</span><span class="p">}[</span><span class="n">exp</span><span class="p">]</span> <span class="k">break</span> <span class="k">return</span> <span class="p">{</span><span class="s">&quot;s&quot;</span><span class="p">:</span><span class="n">bu_size</span><span class="p">,</span> <span class="s">&quot;u&quot;</span><span class="p">:</span><span class="n">unit</span><span class="p">,</span> <span class="s">&quot;b&quot;</span><span class="p">:</span><span class="n">bytes_size</span><span class="p">}</span> </pre></div> <p>Que nos devuelve un diccionario similar al anterior, lo que nos proporciona la posibilidad de disponer tanto del tamaño en bytes como en la mejor unidad IEC posible con una única función. </p> <p>Todas estas funciones con ejemplos (y además una clase que hace uso de ellas), se pueden encontrar en el fichero <code>get_size.py</code> en mi repositorio <em>Python Recipes</em> que se encuentra alojado en <a href="http://github.com/joedicastro/python-recipes">github</a>. Si se ejecuta el fichero como un script puede verse una comparativa de las diversas funciones en rendimiento y precisión con respecto al comando <code>du -bs</code></p>