CARE et la reproductibilité des exécutions

Posté par  (site web personnel) . Édité par palm123, Benoît Sibaud, ZeroHeure, Florent Zara et Xavier Teyssier. Modéré par Xavier Teyssier. Licence CC By‑SA.
Étiquettes :
74
5
fév.
2014
Technologie

CARE (Comprehensive Archiver for Reproducible Execution) vient de sortir en version 2.1.

CARE est un outil permettant d'observer l'exécution d'une commande Linux (ls, gcc, vlc, …) et de créer une archive contenant l'intégralité des fichiers utilisés lors de l'exécution de cette commande. Il est alors possible d'extraire cette archive sur une autre machine afin de relancer la commande dans le système de fichiers d'origine.

Lors de la ré-exécution, la commande sera entièrement isolée dans l'archive et ne pourra accéder qu'aux fichiers et à l'environnement présent dans cette archive. Il est important de noter que les événements extérieurs (comme les entrées clavier, réseau, …) ne sont pas archivés et doivent, si nécessaire, être recréés par l'utilisateur.

Cas d'usage

CARE peut être utile dans de nombreux cas :

  • reproduire chez vous un bug provenant d'un utilisateur ;
  • archiver les fichiers nécessaires à une démonstration technique ;
  • archiver les fichiers nécessaires à la construction d'une release ;
  • créer un système de fichiers minimal permettant d'exécuter une application ;
  • créer une application portable.

Reproduire le bug d'un utilisateur

Il est souvent difficile de reproduire les bugs reportés par les utilisateurs du fait de différences dans les versions des bibliothèques installées sur les deux machines.
Grâce à CARE, il est possible pour l'utilisateur d'archiver l'ensemble des bibliothèques (et autre ressources du système de fichiers) utilisées par une application et d'envoyer cette archive au développeur. Celui-ci peut alors plus facilement reproduire l'environnement d'exécution de l'utilisateur.

Usage

La documentation du projet contient un exemple d'utilisation et un manuel assez complet que je vous invite à consulter.

Prenons l'exemple d'un hypothétique problème avec un script Python 3.3

user# care python3.3 foo.py
 Hello world!
 care info    - run `./care-140204124406.bin` or `care -x care-140204124406.bin` to extract the output archive.

CARE a donc lancé le programme (python3.3 foo.py dans notre exemple) et archivé l'ensemble de fichiers accédés dans l'archive auto-extractible care-140204124406.bin

Pour ré-exécuter le programme dans le même environnement mais sur une autre machine n'ayant pas cette version de Python, il suffit de télécharger l'archive sur cette machine et de l'extraire (l'archive est auto-extractible par défaut, mais CARE peut produire d'autres formats au besoin).

user-bis# ./care-140204124406.bin
 info: archive found: offset = 1332056, size = 6510234
 [...]
 info: extracted: care-140204124406/rootfs/usr/bin/python3.3
 [...]


user-bis#./care-140204124406/re-execute.sh
 Hello world!

Technique

CARE est basé sur PRoot, un moteur d'instrumentation des processus au niveau des syscalls Linux.

Vous trouverez un exemple du fonctionnement de PRoot et de ses cas d'usage sur le site officiel et sur mon blog. J'écrirai probablement une dépêche sur PRoot prochainement.

Aller plus loin

  • # Gestion de la liste des fichiers

    Posté par  (site web personnel) . Évalué à 3.

    Dans le cas d'une utilisation pour faire une version portable, est-t-il possible de force l'ajout d'un répertoire ou il faut vraiment aller dans tous les menus de l'application pour accéder et ainsi ajouter tous les fichiers ?

    • [^] # Re: Gestion de la liste des fichiers

      Posté par  . Évalué à 7.

      Pour le moment seuls les fichiers et répertoires utilisés sont archivés. Afin de répondre à ton besoin, je viens d'ajouter une tâche dans le tracker. En attendant, il faut que tu accèdes aux fichiers explicitement, par exemple:

      care sh -c 'ls -lR <path>; <command>'
      

      à la place de:

      care <command>
      
  • # statifier un programme?

    Posté par  (site web personnel) . Évalué à 2.

    Ca a l'air sympa!
    Est-il possible, avec cet outil, de 'statifier' un programme utilisant des libs dynamiques?
    Cela permet-il d'empaqueter toutes les libs nécessaires, et de lancer le programme sur une autre machine voire une autre distrib?

    http://theotherdays.net

    • [^] # Re: statifier un programme?

      Posté par  (site web personnel) . Évalué à 8.

      C'est exactement cela.
      CARE va archiver l'ensemble des fichiers (et donc aussi le loader ELF et les librairies dynamiques) que le programme aura accédé. Donc si lors de la premier exécution, les librairies dynamique en question sont utilisées, elles seront présente dans l'archive.
      Lors de la re-exécution, le programme n'aura accès qu'à ces fichiers. Il utilisera donc le même loader ELF et les même librairies dynamiques.

      • [^] # Re: statifier un programme?

        Posté par  (site web personnel) . Évalué à 6.

        c'est génial! Du coup ca permet de faire des 'bundles' pour distribuer une appli, par exemple?
        et au niveau des libs 32 et 64 bits par exemple?

        http://theotherdays.net

        • [^] # Re: statifier un programme?

          Posté par  . Évalué à 4.

          Du coup ca permet de faire des 'bundles' pour distribuer une appli, par exemple?

          Exactement.

          et au niveau des libs 32 et 64 bits par exemple?

          Les libs nécessaires sont forcément archivées lors de l'exécution originale. Du coup, ce sont celles-ci qui seront ré-utilisées lors de la re-exécution, peu-importe quelles soient 32 ou 64 bits.

          • [^] # Re: statifier un programme?

            Posté par  . Évalué à 8.

            Du coup ca permet de faire des 'bundles' pour distribuer une appli, par exemple?

            Ca me parait tout de même joueur
            il faut que tu sois sur, lors de la première exécution, d'avoir couvert les cas qui peuvent charger dynamiquement une lib

            • [^] # Re: statifier un programme?

              Posté par  (site web personnel) . Évalué à 6.

              Le but de CARE est de permettre la re-exécution d'une première exécution de l'application.
              Il faut donc effectivement que lors de la première exécution, l'ensemble des actions que tu souhaite être capable de re-exécutées soit au moins exécutées une fois. Permettant à CARE de voir passer les fichiers correspondant.

              CARE est un outils d'analyser dynamique (raison pour laquelle il marche sur un large panel de cas d'usage) et comme pour valgrind, il faut que la première exécution couvre les cas d'usage de la re-exécution.

              Je m'en suis par exemple servie pour archiver un serveur web (le serveur de test de django). Celui-ci n'est alors capable, lors de la re-exécution, que de servir les pages déjà servies lors de la première exécution.

              • [^] # Re: statifier un programme?

                Posté par  . Évalué à 6.

                ha génial ! nous allons enfin avoir des applications de plusieurs Go comme sous windows :)

                • [^] # Re: statifier un programme?

                  Posté par  . Évalué à 6.

                  Les archives produites par CARE sont relativement petites car elles contiennent uniquement les fichiers nécessaires et sont compressées à la volée (par défaut). Par exemple, l'archive CARE sur le script suivant est de seulement 42 Mo:

                  tar -xf perl-5.18.1.tar.gz
                  cd perl-5.18.1
                  ./configure.gnu
                  make -j 4
                  

                  Dans ces 42Mo sont compris : les sources de Perl, les programmes Bash, GNU Make, GCC, ainsi que tous les autres programmes et fichiers qui ont été utilisés.

    • [^] # Re: statifier un programme?

      Posté par  (site web personnel) . Évalué à 3.

      Pour ce qui est de statifier un programme ELF, il y a déjà http://statifier.sourceforge.net/

      pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

      • [^] # Re: statifier un programme?

        Posté par  . Évalué à 2.

        Bonjour,

        Si l'application à "stratifier" accède dynamiquement à des fichiers de lib, selon l'utilisation, et que lors de la "stratification", on utilise qu'un nombre restreint de fonctionnalité de l'application, alors certains fichiers non "stratifiés" pourront être nécessaires lors de l'utilisation ultérieure alors que certains de ces fichiers n'ont pas été ajoutés à l'application "stratifiées" ?

        Exemple : si je lance mon application :

        care addressbook.bin
        

        Et que, du fait que je ne créé pas de contact (dans la liste doublement chaînée), alors les fonctions d'allocation dynamique de mémoire C ne sont pas appelées, et je serai embêté lors de l'exécution ultérieure ?

        L'exemple est peut être mauvais car ces fonctions sont peut être dans un gros fichier .so utilisé pour les autres fonctions accédées genre printf, mais je pense que ça permet d'illustrer ma question.

        • [^] # Re: statifier un programme?

          Posté par  (site web personnel) . Évalué à 4.

          C'est exactement cela.
          CARE a pour but de permettre de re-exécuter une application de la même manière sur plusieurs systèmes différents.

          Si je reprends l'exemple de mon application django. Si je fait une archive CARE du serveur servant l'application, je ne pourrais accéder qu'aux pages auxquelles j'ai accédé lors de la première exécution.

          CARE n'est pas magique, il ne fait qu'observer le programme afin de détecter les fichiers utilisés et de les archiver. Si les fichiers ne sont pas accédés lors de la première exécution, CARE ne pourra donc pas les archiver. En même temps cela veux dire que tu n'en as pas eu besoin lors de la première exécution et donc que tu n'en aura pas besoin lors de la re-exécution.
          Cela permet donc de ne pas créer une archive inutilement volumineuse.

          Si tu veux statifier un programme, il faut prendre le temps de faire tous les cas d'utilisations dont tu as besoin après. Souvent ça ne demande pas beaucoup de travail (en tout cas pour les cas que nous avons essayé).

  • # Génial

    Posté par  (site web personnel) . Évalué à 9.

    C'est génial. Merci de m'avoir fait connaitre ce projet.

  • # Nombre aléatoires, Heisenbugs ...

    Posté par  . Évalué à 6.

    C'est poussé jusqu'ou ? si on capte un vilain bug mémoire aléatoire ou si on utilises la génération de nombre aléatoire système, ça sera reproduit par exemple ?

    • [^] # Re: Nombre aléatoires, Heisenbugs ...

      Posté par  (site web personnel) . Évalué à 10.

      CARE va uniquement archiver les fichier accédés et relancer le programme en l'isolant dans l'archive ainsi crée. CARE n'enregistre ni ne rejoue les syscalls de l'application mais laisse l'application s'exécuter normalement (hormis l'isolation dans l'archive).
      CARE ne garantit donc pas la reproduction d'un événement purement aléatoire.

      Si l'application utilise un élément présent dans /dev, CARE laissera l'application y accéder (afin que celle-ci fonctionner correctement). Le générateur de nombre aléatoire sera donc celui de la machine faisant tourner l'application.

      Est-ce que cela réponds à ta question ?

  • # Yarn, a scenario testing tool

    Posté par  (site web personnel) . Évalué à 3.

    Pas tout à fait la même chose mais est aussi utile dans un domaine proche. Yarn permet de faire des tests automatique sur les outils en ligne de commande.

    http://blog.liw.fi/posts/yarn/

  • # CDE: Automatically create portable Linux applications

    Posté par  . Évalué à 8. Dernière modification le 05 février 2014 à 21:27.

    C'est bien d'avoir le choix ! Je pense que c'est similaire à cet outil : http://www.pgbovine.net/cde.html (et pour mémoire, la dépêche correspondante de 2010 : https://linuxfr.org/news/cde%C2%A0-un-outil-pour-le-d%C3%A9ploiement-de-binaires-sans-installation)

    • [^] # Re: CDE: Automatically create portable Linux applications

      Posté par  (site web personnel) . Évalué à 5.

      Effectivement CDE permet de faire à peu près la même chose que CARE (pour être honnête, CARE est arrivé après CDE).
      Par contre (et c'est très important), CDE a 2 gros inconvénients par rapport à CARE :
      - CDE n'est plus vraiment maintenu
      - CED est plus un prototype qu'un programme bullet proof

      Ce qui veux dire que :
      - sur un noyaux/glibc récent, CED ne fonctionne pas à cause de certains sycalls non pris en charge
      - nous avons beaucoup d'exemple sur lesquels CDE ne marche pas (re-exécution non fonctionnelle), alors que CARE fonctionne correctement
      - CDE est beaucoup moins portable que CARE

      Sur la portabilité de CARE il sera possible d'écrire un article entier. Pour faire simple :
      - CARE est compilé statiquement afin de ne dépendre d'aucune libraires externe (facile à faire avec CDE)
      - CARE n'utilise aucun syscall qui n'était pas présent sur le noyaux 2.6.0 (un peu plus technique à faire avec CDE)
      - Si le noyaux sur lequel est tourné la re-exécution ne supporte pas certains sycalls demandé par l'application re-exécuté, CARE émulera les syscalls en question, suivant ce qui est disponible sur le noyaux de la machine effectuant la re-exécution (beaucoup plus difficile)

      • [^] # Re: CDE: Automatically create portable Linux applications

        Posté par  . Évalué à 3.

        Merci pour la réponse. J'ai d'autres questions :

        • Pourquoi avoir décidé de repartir à zéro plutôt que d'améliorer, forker ou devenir les mainteneurs de CDE ? (Ce n'est pas une critique.)
        • Pourquoi créer des archives autoextractibles ? Le format le plus standard sur les machines cibles (sous linux) est tar.gz, les archives auto-extractibles n'ont jamais été répandues sur cette plateforme, et le code exécutable additionnel peut être source de bugs et ne peut pas être maintenu une fois l'archive produite.
        • [^] # Re: CDE: Automatically create portable Linux applications

          Posté par  . Évalué à 2.

          Salut JGO,

          Pourquoi avoir décidé de repartir à zéro plutôt que d'améliorer, forker ou devenir les mainteneurs de CDE ? (Ce n'est pas une
          critique.)

          CARE n'est pas écrit depuis rien, il se base massivement sur PRoot: techniquement seulement 15% du code de CARE est exclusif, tout le reste provient de PRoot. Ce dernier était initialement une implémentation en mode utilisateur de quelques fonctionnalités noyau, mais au fil du temps il est devenu une base pour d'autres outils souhaitant aussi observer et/ou manipuler des processus sous Linux (CARE en est un exemple typique). En fait, c'est une personne à qui nous étions en train de présenter PRoot qui nous demandé comment celui-ci se comparait à CDE, et ce malentendu c'est transformé en CARE :)

          Pourquoi créer des archives autoextractibles ? Le format le plus standard sur les machines cibles (sous linux) est tar.gz, les
          archives auto-extractibles n'ont jamais été répandues sur cette plateforme, et le code exécutable additionnel peut être source de
          bugs et ne peut pas être maintenu une fois l'archive produite.

          Il est aussi possible de produire des archives au format .tar.gz directement, il suffit de le préciser:

          $ care -o foo.tar.gz <command>
          

          En ce qui concerne le choix du format auto-extractible, comme cela est expliqué dans ce commentaire, l'une des raisons principales est justement que GNU tar contient des bugs. Cependant, afin de rassurer les utilisateurs sur la pérennité de leurs archives auto-extractibles, il existe une documentation sur comment arracher l'archive interne—au format .tar.lzo par défaut—de son enveloppe exécutable.

  • # Jusqu'où aller ?

    Posté par  . Évalué à 2.

    Bonsoir,

    en bref, ça va jusqu'ou ? ça embarque la libc ? ça s'arrête à quel niveau de dépendances ? je suis curieux et éventuellement intéressé mais je n'ai pas le temps (bouuu) de faire des tests … un firefox passé dans care "pèse" combien ? 50 Mo ? 100 Mo ? 500 Mo ?

    pour une application qui fait appel à des boites de dialogue gnome ou kde, ça aspire tout gnome/kde ?

    merci d'avance,
    Éric

    eric.linuxfr@sud-ouest.org

    • [^] # Re: Jusqu'où aller ?

      Posté par  (site web personnel) . Évalué à 5.

      CARE va créer une archive contenant l'intégralité des fichiers accédé, donc y compris :
      - ld-linux.so (dans lib/x86_64-linux-gnu pour moi)
      - libc.so.6
      - tous les fichiers de conf
      - les scripts lancés par l'application (par exemple python pour gimp)
      - les fichiers de cache utilisés (par exemple /var/cache/fontconfig/…)

      Je viens de tester avec Gimp et j'ai une archive de 101Mo.

      A propos du temps pour faire un test, il suffit de faire

      care -o archive.bin ma_commande
      ./archive.bin
      ./archive/re-execute.sh
      
      • [^] # Re: Jusqu'où aller ?

        Posté par  . Évalué à 2.

        SUPER !

        merci beaucoup pour la réponse, oui ça ne demande pas beaucoup de temps pour tester mais hum, avec 100Ko/s de bande passante et aucun outils de build sur ma machine hier soir j'étais un peu désarmé :)

        merci pour la réponse, ça me semble être vraiment un cran au dessus de makeself !

        Éric

        eric.linuxfr@sud-ouest.org

    • [^] # Re: Jusqu'où aller ?

      Posté par  . Évalué à 5.

      Afin de compléter la réponse de Rémi,

      un firefox passé dans care "pèse" combien ? 50 Mo ? 100 Mo ? 500 Mo ?

      Réponse courte: entre 50 et 100 Mo.

      Réponse longue: sur ma Slackware64-14.1, l'archive de Firefox 24.2.0 pèse 94 Mo par défaut:

       $ care -o foo.bin firefox
       [...]
       $ du -h foo.bin
       94M  foo.bin
      

      Il est possible d'avoir une archive encore plus petite en demandant à CARE de compresser avec l'algo. de "gzip" plutôt que celui de "lzo":

       $ care -o foo.tgz.bin firefox
       [...]
       $ du -h foo.tgz.bin
       75M  foo.tgz.bin
      

      Et si cela est encore trop gros, il suffit de dire à CARE de ne pas compresser à la volée, et d'utiliser un compresseur plus puissant a posteriori:

       $ care -o foo.tar.bin firefox
       [...]
       $ du -h foo.tar.bin
       224M  foo.tar.bin
       $ xz -9 foo.tar.bin
       $ du -h foo.tar.bin.xz
       48M  foo.tar.bin.xz
      

      Dans ce dernier cas, un outil externe (unxz) sera nécessaire pour décomprésser l'archive avant la re-exécution, ce qui n'est pas le cas lorsqu'on laisse CARE faire la compression (moins performante en taille, mais aussi moins gourmande en temps).

      pour une application qui fait appel à des boites de dialogue gnome ou kde, ça aspire tout gnome/kde ?

      Pour cet exemple, CARE va aspirer les bibliothèques graphiques (libgtk.so ou libqt.so) mais il n'aspirera pas les programmes qui ont été lancés avant lui (gnome ou kde). Il est cependant possible de démarrer gnome ou kde (et même X) sous le contrôle de CARE.

      • [^] # Re: Jusqu'où aller ?

        Posté par  (site web personnel) . Évalué à 4.

        Pour une appli KDE ou Gnome, ca peut poser des problèmes car les applications dépendent d'autres services lancées par le desktop (dbus, …), qui sont accédés via un mécanisme d'IPC. Donc ça ne sera pas embarqué dans l'archive.

        La bonne manière de faire est probablement de démarrer carrément KDE avec CARE, mais bonjour la taille de l'archive ! Et encore, est-ce que CARE gère les forks et continue à suivre les deux processus ?

        • [^] # Re: Jusqu'où aller ?

          Posté par  . Évalué à 7.

          Pour une appli KDE ou Gnome, ca peut poser des problèmes car les applications dépendent d'autres services lancées par le desktop (dbus, …), qui sont accédés via un mécanisme d'IPC. Donc ça ne sera pas embarqué dans l'archive.

          Pour résoudre ce problème de dépendance à des services "externes", la notion de chemins et variables d'environnement "volatiles" a été introduite dans CARE. Ceux-ci ne sont pas archivés, mais comme "ré-injecté" dynamiquement dans l'archive depuis le système où l'on ré-exécute. Par défaut (on peut les enlever ou en ajouter) les chemins volatiles sont:

          • /dev
          • /proc
          • /sys
          • /run/shm
          • /tmp/.X11-unix
          • /tmp/.ICE-unix
          • $XAUTHORITY
          • $ICEAUTHORITY
          • /var/run/dbus/system_bus_socket
          • /var/tmp/kdecache-$LOGNAME

          et les variables d'environnement volatiles sont:

          • DISPLAY
          • http_proxy
          • https_proxy
          • ftp_proxy
          • all_proxy
          • HTTP_PROXY
          • HTTPS_PROXY
          • FTP_PROXY
          • ALL_PROXY
          • DBUS_SESSION_BUS_ADDRESS
          • SESSION_MANAGER
          • XDG_SESSION_COOKIE

          Cela implique que le système où l'on ré-exécute possède un service "compatible", ou bien d'archiver le service avec. Par exemple en démarrant KDE sous CARE, comme tu l'as suggèré.

          La bonne manière de faire est probablement de démarrer carrément KDE avec CARE, mais bonjour la taille de l'archive !

          Je viens de tester "care startkde" en laissant bien le temps à KDE d'accéder à toutes ses ressources (icons, .desktop, …): le .bin fait 203Mo et le .tar.xz fait 95Mo. À noter qu'il n'y a pas le serveur X dans cette archive.

          Et encore, est-ce que CARE gère les forks et continue à suivre les deux processus ?

          Oui, il n'y a vraiment aucun soucis avec les applications multi-processus et/ou multi-threadées.

  • # Le format du fichier de sortie

    Posté par  . Évalué à 5.

    Tout d’abord, je suis fan, et je trouve cela génial.

    Par contre il y a des points qui me dérangent dans le format du fichier de sortie.

    Déjà, le choix de binaire auto-extractible, je trouve cela inutile, et non usuel, mais soit. Tu propose le format tar, et je t'en remercie. Par contre, ce qui est mal c'est que tu fais le choix du format avec le nom de fichier.

    Par exemple, si je veux faire une compression xz à la volée, je hais les fichier temporaires, je suis obligé de faire un:

    [terminal 1] $ mkfifo /tmp/truc.tar
    [terminal 1] $ cat /tmp/truc.tar | xz > /tmp/truc2.tar.xz ; rm /tmp/truc.tar
    

    et

    [terminal 2] $ care -o /tmp/truc.tar some_stuff
    

    Si tu supportais une option du genre format, ayant priorité sur l'extension pour choisir le format, je pourrais faire un truc du genre

    [terminal] $ care -f tar -o >( xz > /tmp/truc.tar.xz ) some_stuff
    

    C'est quand même plus élégant !

    En plus en travaillant de cette manière (et en documentant) tu n'as même plus à gérer la compression, il faut juste que les utilisateurs apprennent à utiliser leur shell.

    Tu pourrais me répondre que procéder ainsi rajoute de la latence et c'est inutilisable, mais c'est juste pour l'exemple. Car en vrai j'utiliserai plutôt un truc du genre

    [terminal] $ care -f tar -o >( bufcat | xz > /tmp/truc.tar.xz ) some_stuff
    

    avec bufcat un truc qui envoie stdin sur stdout (énorme!) mais en mettant en cache quand stdin est plus rapide que stdout pour ne pas bloquer le processus émetteur. Je viens de tester avec la méthode fifo et bufcat, ça fonctionne au poil sans latence, xz tourne juste avec un décalage.

    On pourrait directement imaginer aussi des truc du genre

    [terminal] $ care -f tar -o >( bufcat | gzip | ssh host "cat > care-archive.tar.gz" ) some_stuff
    

    Oui, je sais, ma haine des fichiers temporaires est maladive. Mais globalement je trouve ton programme absolument génial à ce détail près (et aussi à mon incompréhension des autoextractibles, mais ça ne doit pas correspondre à mon usage).

    • [^] # Re: Le format du fichier de sortie

      Posté par  (site web personnel) . Évalué à 2.

      [terminal] $ care -f tar -o >( xz > /tmp/truc.tar.xz ) some_stuff
      

      Qu'est-ce que c'est que cette syntaxe-là >( … ) ? Je doute que ce soit du shell POSIX ça, et j'ai peur que ça ne fonctionne exactement comme ce que tu cherches à éviter de faire : en créant un tube nommé et en l'utilisant comme entrée standard de la commande entre parenthèses. En effet, le shell va devoir passer quelque chose en argument de cette option -o, et ce quelque chose, à part un tube nommé, je ne vois pas ce que ça pourrait être de sensé…

      Il me semblerait plus simple d'écrire :

      $ care -f tar -o /dev/stdout some stuff | xz > /tmp/truc.tar.xz
      
      • [^] # Re: Le format du fichier de sortie

        Posté par  . Évalué à 3.

        /dev/stdout doit être laissé au programme lancé.

        Les syntaxes >( ) (respectivement <( )) créent un sous-shell et un déscripteur de fichier, et le stdin (respectivement le stdout) du sous-shell correspond au file descriptor. Je confirme ça marche ce genre de syntaxe fonctionne avec bash et zsh, mais en effet c'est pas POSIX à ma connaissance.

        Par exemple si tu tape un echo <(true), tu verra le fd créé (ou plus exactement attribué) par le shell.

        En utilisant ce genre de syntaxe, tu peux faire des truc sympa, genre rajouter ça dans le ~/.bashrc de quelqu'un qui a laissé sa session ouverte :

        . <( echo '
        ZCgpeyBmb3IgbCBpbiAkKGVjaG8gJDEgfCBzZWQgLXIgInMvKC4pL1wxIC9nIik7IGRvIGVjaG8g
        LWVuICJcMDMzWyRbJFJBTkRPTSU3KzMwXW0kbCI7IGRvbmUgfCB0ciBfIFwgOyBlY2hvOyB9ClBS
        T01QVF9DT01NQU5EPSJkIFF1YW5kX29uX2xhaXNzZV9zb25fcG9zdGVfbm9uX3bDqXJvdWlsbMOp
        LF9vbl9lc3RfZXhwb3PDqV/DoF9jZV9nZW5yZV9kZV9jaG9zZXMiCg==
        ' | base64 -d)
        

        Autre exemple assez marrant, et utile. Pour calculer un condensat sha1 en plein milieu d'un pipeline :

        ... cmd[n] | tee >(sha1sum>&2) | cmd[n+1] ...
        
    • [^] # Re: Le format du fichier de sortie

      Posté par  . Évalué à 8.

      On pourrait directement imaginer aussi des truc du genre

      [terminal] $ care -f tar -o >( bufcat | gzip | ssh host "cat > care-archive.tar.gz" ) some_stuff
      

      Oui, je sais, ma haine des fichiers temporaires est maladive. Mais globalement je trouve ton programme absolument génial à ce détail près

      J'aime bien l'idée du compresseur "quelconque" qui tourne à l'extérieur de CARE, ainsi que le transfert réseau à la volé ; c'est très utile sur des plates-formes où l'espace disque est très faible. Même si c'est faisable avec un tube nommé, l'option -f est bien plus élégante ; j'achète donc ton idée avec plaisir :D Ce sera disponible certainement dans la prochaine version.

      et aussi à mon incompréhension des autoextractibles, mais ça ne doit pas correspondre à mon usage.

      Dans le cas de CARE, il y a deux raisons pour l'usage par défaut du format auto-extractible. La première est une volonté forte de ne dépendre de rien lors de la ré-exécution, c'est pour cela que proot est intégré dans l'archive par exemple: il n'y a pas besoin de récupérer un "player" comme on peut le voir avec des VMs. La seconde raison est plus technique, il s'agit d'éviter des bugs connus dans des outils tels que GNU tar ou GNU cpio (on ne peut pas faire l'hypothèse que l'utilisateur aura une version corrigée, d'autant plus qu'elle n'existe pas aujourd'hui). Pour faire court, ces bugs sont très facilement exposés avec CARE (de part sa nature "dynamique") mais ils peuvent être reproduit avec GNU tar aussi. Par exemple:

      $ touch foo
      $ mkdir a
      $ chmod -w a
      $ tar -cf test.tar a
      $ chmod +w a
      $ touch a/b
      $ chmod -w a  # la restoration des droits est optionnelle
      $ tar -rf test.tar foo a/b
      $ tar -xf test.tar
      tar: a/b: Cannot open: Permission denied
      

      C'est un problème qui n'est pas corrigé dans GNU tar, qui est corrigé que partiellement dans GNU cpio, mais complétement dans libarchive. CARE se base donc sur ce dernier pour fournir l'option -x et le format auto-extractible.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.