<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.mymind.fr/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Mind... - Tag - pratique</title>
  <link>http://blog.mymind.fr/</link>
  <atom:link href="http://blog.mymind.fr/feed/tag/pratique/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>fr</language>
  <pubDate>Thu, 01 Dec 2011 21:43:54 +0100</pubDate>
  <copyright>© 2007-2008 Florent Bruneau</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Compter les fichiers</title>
    <link>http://blog.mymind.fr/post/2007/08/30/Compter-les-fichiers</link>
    <guid isPermaLink="false">urn:md5:a4d72e31c767c980a39751dea09efb0a</guid>
    <pubDate>Thu, 30 Aug 2007 23:12:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>Devel</category><category>pratique</category><category>zsh</category>    
    <description>&lt;p&gt;C'est un peu la suite de mon post &quot;Outils pratiques&quot; où je donnais deux scripts permettant de rendre les commandes SVN plus conviviales. Encore une fois, je réinvente sans doute la roue (des outils équivalents doivent déjà exister... sans doute en mieux), mais je pense que chercher ce genre d'outils sur internet m'aurait pris plus de temps que ce qu'il m'a fallu pour le développer.&lt;/p&gt;


&lt;p&gt;En ce moment je manipule des fichiers, beaucoup de fichiers (et même, beaucoup de gros fichiers), que j'ouvre, rouvre, et ferme et puis referme. Et à force d'ouvrir, on oublie parfois de refermer, et là, c'est comme une fuite de mémoire, sauf que le nombre limite de fichiers ouverts est beaucoup plus rapidement atteinte que la limite de mémoire... dans la configuration de base sur un linux, un programme n'a le droit qu'à 1024 descripteurs de fichiers. D'où mon problème&amp;nbsp;: comment traquer les &quot;file-handle leaks&quot;&amp;nbsp;?&lt;/p&gt;    &lt;p&gt;Pour le faire, je me suis fait rapidement un petit script qui permet d'analyser les données issues d'un &lt;code&gt;strace&lt;/code&gt;. &lt;code&gt;strace&lt;/code&gt; est, pour ceux qui ne le savent pas, un programme très pratique qui permet de lister les appels systèmes. Dans mon cas présents, surveiller les ouvertures fermetures de fichiers revient à traquer les commandes &lt;code&gt;open&lt;/code&gt; (ouverture d'un fichier), et les commandes &lt;code&gt;close&lt;/code&gt;. Donc, je récupère simplement la liste des appels à &lt;code&gt;open&lt;/code&gt; et &lt;code&gt;close&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
[bash]
strace -f -e trace=open,close mon programme 2&amp;gt; /quelque/part
&lt;/pre&gt;


&lt;p&gt;Et ainsi, le fichier &lt;code&gt;/quelque/part&lt;/code&gt; contient la liste complète des appels à &lt;code&gt;open&lt;/code&gt; et &lt;code&gt;close&lt;/code&gt; effectués par mon programme (et ses processus fils). Il ne reste plus alors qu'à analyser le contenu de &lt;code&gt;/quelque/part&lt;/code&gt;. Pour ceci, il suffit de peu de lignes de code (en perl pour ma part, mais d'autres auraient fait la même chose en shell, python... ou n'importe quel langage de scripting)&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
[perl]
#!/usr/bin/perl 
 
my %files; 
my %modes; 
my %lines; 
 
my $lineNb = 0; 
my $maxOpened = 0; 
my $currentOpened = 0; 
my $totalOpened = 0; 
 
for $line (&amp;lt;STDIN&amp;gt;) { 
  if ($line =~ /open\\(&amp;quot;([^&amp;quot;&amp;quot;]+)&amp;quot;, ([^\\)]+)\\)\\s*=\\s*(\\d+)/) { 
    $files{$3} = $1; 
    $modes{$3} = $2; 
    $lines{$3} = $lineNb; 
    $totalOpened++; 
    $currentOpened++; 
    if ($currentOpened &amp;gt; $maxOpened) { 
      $maxOpened = $currentOpened; 
    } 
  } 
  if ($line =~ /close\\((\\d+)\\)/ &amp;amp;&amp;amp; $files{$1} ne '') { 
    $files{$1} = ''; 
    $currentOpened--; 
  } 
  $lineNb++; 
} 
 
print &amp;quot;$totalOpened files opened, max. $maxOpened at the same time
&amp;quot;; 
print &amp;quot;$currentOpened files not closed
&amp;quot;; 
for $id (keys %files) { 
  local $file = $files{$id}; 
  local $mode = $modes{$id}; 
  local $line = $lines{$id}; 
 
  if ($file ne '') { 
    print &amp;quot;[line $line] id=$id, open $file with mode $mode
&amp;quot;; 
  } 
} 
&lt;/pre&gt;


&lt;p&gt;Pour simplifier le tout, on rajoute une fonction dans le &lt;code&gt;zshrc&lt;/code&gt; pour wrapper tout ça, et ça donne (attention, ceci ne fonctionne que sous linux, &lt;code&gt;mktemp&lt;/code&gt; n'a pas la même syntaxe sur MacOS, et surtout, &lt;code&gt;strace&lt;/code&gt; n'est pas disponible sur Mac&lt;/p&gt;

&lt;pre&gt;
[bash]
function checkFiles() { 
  TEMPFILE=`mktemp` 
  strace -f -e trace=open,close $* 2&amp;gt; $TEMPFILE 
  cat $TEMPFILE | ~/.zsh/trackFiles.pl 
  rm $TEMPFILE 
} 
&lt;/pre&gt;


&lt;p&gt;Avec, ça, il ne me répond&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
% checkFiles cp test test2
12 files opened, max. 2 at the same time
0 files not closed
&lt;/pre&gt;


&lt;p&gt;Si maintenant, je fais un programme minimaliste qui oublie de fermer un fichier&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
[c]
#include &amp;lt;stdio.h&amp;gt; 
 
int main() { 
  FILE* file = fopen(&amp;quot;test&amp;quot;, &amp;quot;r&amp;quot;); 
  return file != NULL ? 0 : 1; 
} 
&lt;/pre&gt;

&lt;pre&gt;
% gcc test.c -o tester
% checkFiles ./tester
3 files opened, max. 1 at the same time
1 files not closed
[line 4] id=3, open test with mode O_RDONLY
&lt;/pre&gt;


&lt;p&gt;Voilà, maintenant je sais que mon programme oublie de fermer un fichier, que ce fichier s'appelle &quot;test&quot;, et qu'il est ouvert en read-only. La ligne &quot;4&quot; est la ligne dans la sortie de &lt;code&gt;strace&lt;/code&gt;, et n'a aucun rapport avec la ligne 4 du fichier source (contrairement aux apparences).&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/08/30/Compter-les-fichiers#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/08/30/Compter-les-fichiers#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/35</wfw:commentRss>
      </item>
    
  <item>
    <title>Outils pratiques</title>
    <link>http://blog.mymind.fr/post/2007/03/13/Outils-pratiques</link>
    <guid isPermaLink="false">urn:md5:9493e53484f0ab915a8ca15e826de2fc</guid>
    <pubDate>Tue, 13 Mar 2007 19:21:00 +0100</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>Devel</category><category>pratique</category><category>SVN</category><category>zsh</category>    
    <description>&lt;p&gt;Etant donné que je travaille énormément avec &lt;a href=&quot;http://subversion.tigris.org&quot;&gt;SVN&lt;/a&gt;. C'est un outils très addictif... à tel point que je l'utilise dès que je travaille sur un projet (seul ou à plusieurs), je crée un reposoire pour le projet (c'est un excellent moyen de ne pas perdre son travail suite à une fausse manoeuvre). Comme en plus je ne supporte pas les front-end pour SVN, je travaille toujours en ligne de commandes...&lt;/p&gt;    &lt;p&gt;Pour pouvoir améliorer la sortie des commandes SVN dans mes consoles, j'ai fait surchargé la commande &lt;code&gt;svn&lt;/code&gt; par une fonction &lt;code&gt;zsh&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
[bash]
function svn() {
    if [[ $1 == &amp;quot;ci&amp;quot; || $1 == &amp;quot;commit&amp;quot; || $1 == &amp;quot;propedit&amp;quot; || $1 == &amp;quot;propset&amp;quot; || $1 == &amp;quot;help&amp;quot; ]]; then
        /usr/local/bin/svn $*
    elif [[ $1 == &amp;quot;preci&amp;quot; || $1 == &amp;quot;precommit&amp;quot; ]]; then
        /usr/local/bin/svn status | grep -v '?' | ~/.zsh/zshcolorsvn
    else
        /usr/local/bin/svn $* | ~/.zsh/zshcolorsvn
    fi
}
&lt;/pre&gt;


&lt;p&gt;Cette fonction est donc très simple&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;si la commande nécessite un interaction de l'utilisateur, on appel directement le programme &lt;code&gt;svn&lt;/code&gt; (le cas de &lt;code&gt;help&lt;/code&gt; permet de ne pas casser la tab-completion de &lt;code&gt;zsh&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;sinon on envoi la sortie de svn dans &lt;a href=&quot;http://blog.mymind.fr/mind/public/misc/zshcolorsvn&quot;&gt;un script&lt;/a&gt; qui réalise sa coloration syntaxique&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ceci donne un résultat de la forme suivante&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.mymind.fr/public/screenshots/svn-diff.jpg&quot;&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/.svn-diff_m.jpg&quot; alt=&quot;Exemple de svn diff&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.mymind.fr/public/screenshots/svn-update.jpg&quot;&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/.svn-update_s.jpg&quot; alt=&quot;Exemple de svn update&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.mymind.fr/public/screenshots/svn-status.jpg&quot;&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/.svn-status_s.jpg&quot; alt=&quot;Exemple de svn status&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;C'est donc extrêmement pratique&amp;nbsp;; ça permet de distinguer facilement les modifications, ça permet aussi de voir d'un seul coup d'oeil les conflits et la liste des fichiers modifiés. En plus ça fonctionne également avec des commandes comme &lt;code&gt;cvs&lt;/code&gt; ou &lt;code&gt;diff&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
[bash]
# SVN
function svn() {
    if [[ $1 == &amp;quot;ci&amp;quot; || $1 == &amp;quot;commit&amp;quot; || $1 == &amp;quot;propedit&amp;quot; || $1 == &amp;quot;propset&amp;quot; || $1 == &amp;quot;help&amp;quot; ]]; then
        /usr/local/bin/svn $*
    elif [[ $1 == &amp;quot;preci&amp;quot; || $1 == &amp;quot;precommit&amp;quot; ]]; then
        /usr/local/bin/svn status | grep -v '?' | ~/.zsh/zshcolorsvn
    else
        /usr/local/bin/svn $* | ~/.zsh/zshcolorsvn
    fi; fi
}

# SVN avec conversion de la sortie en latin1
function svn_utf8() {
    if [[ $1 == &amp;quot;ci&amp;quot; || $1 == &amp;quot;commit&amp;quot; ]]; then
        svn $*
    else
        svn $* | iconv -f utf8 -t iso-8859-1
    fi
}

function cvs() {
    if [[ $1 == &amp;quot;diff&amp;quot; ]]; then
        shift 1
        /usr/bin/cvs diff -ubN $* 2&amp;gt; /dev/null | ~/.zsh/zshcolorsvn
    elif [[ $1 == &amp;quot;ci&amp;quot; || $1 == &amp;quot;commit&amp;quot; || $1 == &amp;quot;propedit&amp;quot; || $1 == &amp;quot;propset&amp;quot; || $1 == &amp;quot;help&amp;quot; ]]; then
        /usr/bin/cvs $*
    else
        /usr/bin/cvs $* 2&amp;gt; /dev/null | ~/.zsh/zshcolorsvn
    fi;
}

function diff() { /usr/bin/diff -u $* | ~/.zsh/zshcolordiff }
&lt;/pre&gt;


&lt;p&gt;Les scripts nécessaires sont disponibles&amp;nbsp;: &lt;a href=&quot;http://blog.mymind.fr/public/misc/zshcolorsvn&quot;&gt;zshcolorsvn&lt;/a&gt; et &lt;a href=&quot;http://blog.mymind.fr/public/misc/zshcolordiff&quot;&gt;zshcolordiff&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Seul défaut&amp;nbsp;: pour pouvoir utiliser les commandes sans coloration... il faut taper chemin complet.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/03/13/Outils-pratiques#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/03/13/Outils-pratiques#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/12</wfw:commentRss>
      </item>
    
</channel>
</rss>
