[gull] Truc et astuces: bash connector

felix felix at f-hauri.ch
Thu Feb 15 21:01:27 CET 2018


On Thu, Feb 15, 2018 at 07:56:21AM +0100, Laurent Franceschetti wrote:
> 
> Surtout quel est le problème que cette méthode résoud, et quelle est l’idée 
> centrale de la méthode?

Eliminer les ``forks'' répétitifs qui peuvent être évités.

Petit exemple: Voici un fichier:

  $ wget http://f-hauri.ch/vrac/scTestFile.raw.gz
  scTestFile.raw.gz   100%[===================>]  12.14K  --.-KB/s  in 0.004s

Qui contient des lignes (1000) de montants suivits de dates:

  $ zcat scTestFile.raw.gz | (head -n3;tail -n7)
       2032.55  Jul 22 00:12:45 2007
       6229.85  Apr 19 20:31:15 2010
       3089.75  Sun Nov  2 08:48:10 2014
       3816.30  Sat Nov 19 21:12:50 2016
       7934.70  May 23 16:47:40 2008
       2969.45  Aug 30 2017 01:43:45
       3569.00  2011-12-29 17:07:20
        594.40  Thu Mar  5 05:44:40 2015
       9546.85  Dec 31 2015 06:56:45
       3445.75  2016-07-14 18:43:15

Pour
  - unifier la présentation des dates et
  - calculer le total des montants,
je peux:

  $ tot=0.0
  $ time while read val date;do
        tot=$(bc -l <<<"$tot+$val")
        printf "%11.2f %(%a %d %b %Y %T)T\n" $val $(
            date -d "$date" +%s
        )
    done < <(zcat scTestFile.raw.gz) > >(head -n3;tail -n7)
      2032.55 dim 22 jui 2007 00:12:45
      6229.85 lun 19 avr 2010 20:31:15
      3089.75 dim 02 nov 2014 08:48:10
      3816.30 sam 19 nov 2016 21:12:50
      7934.70 ven 23 mai 2008 16:47:40
      2969.45 mer 30 aoû 2017 01:43:45
      3569.00 jeu 29 déc 2011 17:07:20
       594.40 jeu 05 mar 2015 05:44:40
      9546.85 jeu 31 déc 2015 06:56:45
      3445.75 jeu 14 jui 2016 18:43:15
  real    2m0.433s
  user    0m20.960s
  sys     0m24.550s

Euh oui, je l'ai fait sur un raspberry-pi... 2 minutes!

  $ echo $tot
  4674781.85

Bon, à présent voyons:

  $ wget https://f-hauri.ch/vrac/shell_connector.sh
  shell_connector.sh  100%[===================>]   7.93K  --.-KB/s    in 0.005s  

  $ . shell_connector.sh 
  $ newConnector /usr/bin/bc -l 0 0 
  $ newConnector /bin/date '-f - +%s' @0 0
  $ echo >&$BCIN tot=0

Oui, je stoque la variable tot dans `bc`...

  $ time while read val date ;do
      echo >&$BCIN tot=tot+$val
      myDate "$date" mDate
      printf "%11.2f %(%a %d %b %Y %T)T\n" $val $mDate
    done < <(zcat scTestFile.raw.gz) > >(head -n3;tail -n7)
      2032.55 dim 22 jui 2007 00:12:45
      6229.85 lun 19 avr 2010 20:31:15
      3089.75 dim 02 nov 2014 08:48:10
      3816.30 sam 19 nov 2016 21:12:50
      7934.70 ven 23 mai 2008 16:47:40
      2969.45 mer 30 aoû 2017 01:43:45
      3569.00 jeu 29 déc 2011 17:07:20
       594.40 jeu 05 mar 2015 05:44:40
      9546.85 jeu 31 déc 2015 06:56:45
      3445.75 jeu 14 jui 2016 18:43:15
  real    0m8.043s
  user    0m2.370s
  sys     0m0.800s

Voilà, en évitant ~2000 forks, je le fais en 8" au lieu de 120"!

  $ myBc tot montotal
  $ echo $montotal 
  4674781.85

Tant que mon shell courant existe et que je ne ferme pas les
descripteurs, je peux continuer à les utiliser...

  $ ps --sid $(ps ho sid $$) fw
    PID TTY      STAT   TIME COMMAND
   4625 pts/2    Ss     0:00 -bash
   9146 pts/2    S      0:00  \_ /usr/bin/bc -l
   9150 pts/2    S      0:00  \_ /bin/date -f - +%s
   9188 pts/2    R+     0:00  \_ ps --sid 4625 fw

Voilà, j'espère avoir montré l'intérêt de la méthode.
Bonne soirée!

-- 
 Félix Hauri  -  <felix at f-hauri.ch>  -  http://www.f-hauri.ch


More information about the gull mailing list