Journal Le core utile

Posté par  . Licence CC By‑SA.
Étiquettes :
58
10
déc.
2015

Sommaire

GNU Coreutils

Ce journal concerne les utilitaires GNU. Ils sont présents dans toutes les distributions Linux, et tous les adeptes du shell les connaissent.

Mais connaissons-nous vraiment toutes ces commandes ?

J'ai donc listé le contenu du paquet coreutils de ma distribution, et j'ai écrit une description rapide pour les commandes que je ne connaissais pas, ou peu.

La doc GNU

base64
Codage/décodage d'un fichier dans le format base64.
Fonctionne avec l'entrée standard (on peut donc piper).

basename
Voir dirname

cat

chcon
Modifier le contexte de sécurité d'un fichier.
Ceci ne concerne que les utilisateurs de SELinux.
Le contexte de sécurité est visible avec ls -Z

chgrp

chmod

chown

chroot
Lancer une commande ou un shell en confinant le répertoire racine.

cksum
Calcule le checksum (CRC) d'un fichier. Donne également sa taille.

comm
Compare deux fichiers. La sortie se fait en colonnes.

cp

csplit
Découpe un fichier en différentes sections.
Chaque section est sauvée dans un fichier (on peut préciser la règle de nommage).
Les sections sont délimitées par un nombre de lignes, ou une regex.

cut

date

dd

df

dir
Ce n'est pas un alias vers ls.
La syntaxe des options l'évoque pourtant fortement.
Voir vdir.

dircolors
Permet de créer la variable shell LS_COLORS, au bon format selon le shell.

dirname
Voir basename.

du

echo

env

expand
Conversion des tabulations d'un fichier en espaces.
Voir unexpand.

expr
Évaluation d'une expression.
expr 1 = 2 : renvoie 0.
On peut aussi faire du calcul arithmétique ou du traitement de chaines.

factor
Factorise un nombre et imprime le résultat sur la sortie standard.
factor 16 : renvoie "2 2 2 2"

false
Ne fait rien, et le fait mal en plus.
Sûrement utile pour renvoyer une erreur de façon lisible dans un script.

fmt
Formatage simple de texte.
Me semble utile pour formater rapidement un texte aux lignes trop longues.

fold
Formatage simple de texte.
Ne semble pas très différent de fmt.
Je n'ai pas compris à quoi servait l'option -b.

head

hostid
Sort un nombre hexadécimal qui correspondrait à un identifiant pour l'hôte.
Pas de détails dans la page de manuel sur le mystérieux calcul utilisé.

id

install
Copie de fichiers d'un endroit vers un autre.
La page de manuel recommande quand même d'utiliser un vrai gestionnaire de package.

join
Permet une union sur deux fichiers.

link
Crée un hard link (version simplifiée de ln).

ln

logname
Équivalent à whoami.

ls

md5sum
Calcule le md5 d'un fichier, ou contrôle les sommes en utilisant une liste de fichiers.

mkdir

mkfifo

mknod

mktemp
Crée un répertoire temporaire garanti unique.

mv

nice

nl
Numérote les lignes d'un fichier.
Ne numérote pas les lignes vides (on peut le forcer).

nohup
Lance une commande en ignorant les signaux, et en redirigeant la sortie vers un fichier.

nproc
Sort le nombre de processeurs du système.

numfmt
Conversion de nombres vers un format plus lisible pour nous, les humains.
Semble surtout utile pour des conversion telles que 1000 -> 1K .

od
Dumpe un fichier en différentes bases.
Par défaut, c'est en octal, d'où le nom de la commande.

paste
Je n'ai pas compris l'intérêt de cette commande.

pathchk
Vérifie la validité d'un nom de fichier.
L'option -P permet de vérifier qu'un fichier ne commence pas par un tiret.
pathchk -P -- -toto : renvoie une erreur.

pinky
Permet d'obtenir des informations sur les utilisateurs connectés au système.
Semble très semblable à who , mais en plus lent.

pr
Pour imprimer à l'ancienne.

printenv
Équivalent à env.

printf

ptx
Pas compris l'intérêt.

pwd

readlink
Avec l'option -f , imprime le chemin complet du fichier.
Résout également tous vos problèmes de liens symboliques.

realpath
La même chose que readlink -f.

rm

rmdir

runcon
Lance un programme dans un certain contexte de sécurité.
Pour les utilisateurs de SELinux.

seq
Génère une séquence, et l'imprime sur la sortie standard.
seq 1 10

Équivalent built-in pour Bash : for (( … ))
for ((i=1; i<=10; i++)); do echo $i; done

sha1sum
sha224sum
sha256sum
sha384sum
sha512sum
Et bientôt sous vos yeux ébahis, la commande shasum et ses paramètres!

shred
Écrase un fichier avec des valeurs aléatoires, puis l'efface (si option -u)

shuf
Mélange le contenu d'un fichier en permutant ses lignes.
Fonctionne aussi avec l'entrée standard.

sleep

sort

split
Découpe un fichier en plusieurs morceaux.

stat
Donne toutes sortes d'information sur le système de fichiers, ou les fichiers eux-même.
Ex: sur quel point de montage suis-je en ce moment ? stat --printf="%m" .

stdbuf
Lance une commande et change la façon dont ses entrées/sorties sont bufferisées.
Après quelques essais sur mes logs, je ne vois pas de différence lors d'un grep sur 200Mo.

stty

sum
Encore un calcul de checksum

sync
Achève toutes les écritures en attente du FS.
Très utile après l'umount d'une clé USB : regardez comme elle clignote joliment.
(oui je sais, ce n'est pas normal de devoir faire ça après un umount).

tac
Du tac au cat.

tail

tee
Lit l'entrée standard, et écrit à la fois sur la sortie standard et dans un fichier.

test
Pour ma part, je trouve ça moins lisible que [

timeout
Lance une commande et envoie un signal au bout d'un certain temps.

touch

tr
Pour les conversions caractères par caractères.

true
Ne fait rien, mais le fait bien.

truncate
Définit la taille d'un fichier (de zéro à l'infini).
Si des données sont présentes, leur préservation dépend de la taille demandée.

tsort
Tri topologique.
Tous les détails ici.

tty
Donne le nom du périphérique utilisé comme tty, dans le terminal ou la console qui a lancé la commande

uname
Le whoami du noyau.

unexpand
Conversion des espaces d'un fichier en tabulations.
Voir expand.

uniq

unlink
Je ne vois pas la différence avec un rm.

users

vdir
Tout comme dir, ressemble fortement à ls.

wc

who
users, avec plus d'informations.

whoami
Bin c'est toi, voyons.

yes
Permet de sortir la chaine de son choix, jusqu'à que kill s'ensuive.
Par défaut, sort 'y'.

  • # typos

    Posté par  . Évalué à 2.

    J'ai eu beau me relire, il reste au moins deux typos après publication.

    Ne tenez pas compte des étoiles après base64 et basename , qui ne sont que le résultat d'une regex un peu malheureuse.

    Discussions en français sur la création de jeux videos : IRC freenode / #gamedev-fr

  • # false

    Posté par  . Évalué à 1.

    La commande false ne fait pas « mal » son travail, elle le fait bien. Son travail c'est d'échouer (renvoyer 1 en sortie de commande).

    • [^] # Re: false

      Posté par  . Évalué à 10.

      Tu mens.

    • [^] # Re: false

      Posté par  . Évalué à 7.

      $ false
      $ echo $?
      1

      • [^] # Re: false

        Posté par  . Évalué à 3.

        Il est vrai que false est rarement utilisé. Je n'ai pas souvenir d'en avoir jamais eu besoin en 20 ans de shell Unix/Linux.

        Par contre, true est beaucoup plus utile.

        Son premier usage est évidemment dans les scripts qui ont besoin d'une commande qui ne fait rien mais retourne un code d'erreur valide. On peut exploiter le fait que ses arguments soient ignorées.

        case "$1" in 
          -gz) COMPRESS=gzip ;;
          -bz) COMPRESS=bzip2 ;;
          *) COMPRESS=true ;;
        esac 
        ...
        if ! $COMPRESS file ; then
          echo "ABORT"
          exit
        fi 
        ...

        Le second usage assez classique est pour créer une boucle infinie.

        while true ; do read A ; echo "Salut $A" ; done
        • [^] # Re: false

          Posté par  . Évalué à 10.

          false est parfois utilisé dans le fichier /etc/passwd afin d'empêcher le login d'un utilisateur (système).

          Exemple sur ma Gentoo:
          portage:x:250:250:portage:/var/tmp/portage:/bin/false

          On trouve aussi /sbin/nologin.

        • [^] # Re: false

          Posté par  . Évalué à 5.

          On peut aussi utiliser true pour ignorer une erreur :

          mkdir data || true
        • [^] # Re: false

          Posté par  . Évalué à 5. Dernière modification le 10 décembre 2015 à 21:19.

          Il m'arrive d'utiliser true et false comme des … booléens !

              case "$1" in 
                -gz) COMPRESS=true ; FORMAT=gzip ;;
                -bz) COMPRESS=true ; FORMAT=bzip2 ;;
                *) COMPRESS=false ;;
              esac 
              ...
              if ! $COMPRESS ; then
                echo "ABORT"
                exit
              fi 
              ...

          Je sais pas si c'est une belle pratique, mais ça fonctionne !
          Entre le programme true, et le programme [ , je trouve que le shell c'est de la bidouille …

          Sinon je me t'attendais pas a trouver un programme du type de factor dans les core utils !
          Mais après réflexion, je me dit que c'est la base d'un certains nombre de concept de chiffrement (clé privée/publique,…)

          • [^] # Re: false

            Posté par  . Évalué à 5.

            Entre le programme true, et le programme [ , je trouve que le shell c'est de la bidouille …

            C’est horrible ce [… genre if [ -z $v ]; then… ça ressemble à quoi ? :) On peut même ôter le crochet fermant qui n’est autorisé par le langage que pour la seule bonne raison qu’un crochet ouvert qui reste ouvert c’est très grave… presque autant qu’une parenthèse !

            Maintenant j’essaie d’écrire : if test -z $v; then… c’est bien ce qu’il y a de plus logique et clair à lire selon moi.

            Oui le shell c’est spécial comme « langage de programmation » vu que ce n’en ai pas vraiment un.

            En m’y mettant j’ai eu un peu de mal avec la logique binaire… On a l’habitude de considérer que 1 représente vrai et 0 représente faux, or le code retour des programmes c’est 0 pour OK, par convention. Si je fais un if (rm toto) et que la commande « plante » (parce que le fichier toto n’existe pas par exemple) ma condition sera fausse.

            L’utilisation des opérateurs && et || entre plusieurs commandes permet souvent d’être concis et élégant, je trouve.

            • [^] # Re: false

              Posté par  . Évalué à 1.

              Là ou il faut faire bien attention avec ce crochet fermant, c'est de bien mettre une espace avant. Pour éviter le bug suivant: [ "$x" = "$y" -a "$w" = "$z"] . La comparaison de chaîne est à ce titre plus piégeuse car la deuxième condition sera silencieusement toujours fausse (sauf si effectivement on s'attend à ce que $w puisse valoir "$z]"…); par rapport à la comparaison numérique qui va déclencher une erreur de conversion. Du coup, je préfère aussi utiliser backquote test et aussi parce que c'est plus "parlant" :)
              Btw l'opérateur == est un bashisme totalement inutile, bref à ne pas utiliser.

              Pour le coup des && et || je suis plus partagé. Je n'arrive pas à produire d'exemple mais j'ai le souvenir qu'il y a des situations qui ne sont pas exprimables. Pour les cas simples ok. Il y a aussi l'idiome 'commande qui peut rater sans devoir tout faire exploser || true' utilisé dans un script en "set -e" qui est très pratique.

              À part ça, on voit aussi de temps en temps ':' à la place de true… ça fait gagner des caractères… :)
              Son autre utilité, c'est pour utiliser l'opérateur : ${var:=defaultvalue}, bien plus concis que d'écrire var=${var:-default}.
              Pour rebondir sur l'exemple parent de ce thread:

              case .. in
              -bz) COMPRESS=bzip2 ;;
              -gz) COMPRESS=gzip;;
              esac
              ${COMPRESS:+:} ${COMPRESS:-exit 1}

              • [^] # Re: false

                Posté par  . Évalué à 2.

                Notez qu'on peut faire encore plus concis:

                COMPRESS_bz=bzip2
                COMPRESS_gz=gzip
                eval COMPRESS=\$COMPRESS_${1##*-}
                ${COMPRESS:+:} ${COMPRESS:-exit 1}

                Si on veut avoir un diagnostique, il suffit d'écrire une fonction abort()…

                • [^] # Re: false

                  Posté par  . Évalué à 4.

                  Le genre de code qui va (si je n’y suis pas habitué pour une raison ou une autre) me nécessiter une heure pour rechercher sur le web et assimiler (c’est à dire accepter en son âme de codeur, profondément, que cela puisse pertinemment s’écrire ainsi…) avant de passer à la suite du code…

                  J’ai dit « concis && élégant », j’aurais du ajouter lisible pour le commun des programmeurs :)

                  Il faut reconnaître que l’« expansion de variable » en shell c’est une des caractéristiques de ce genre de langage et c’est rudement pratique.

            • [^] # Re: false

              Posté par  . Évalué à 2.

              En m’y mettant j’ai eu un peu de mal avec la logique binaire… On a l’habitude de considérer que 1 représente vrai et 0 représente faux, or le code retour des programmes c’est 0 pour OK, par convention

              Effectivement.

              Mais justement en utilisant true et false, on conserve la logique :

              $ perl -le '1 and print "ko"'
              ko
              $ perl -le '1 and print "ok"'
              ok
              $ true && echo ok
              ok
              $ false || echo ko
              ko
              

              Même si c'est vrai que c'est perturbant d'avoir false à 1 et true à 0. C'est généralement le contraire.

              # false; echo $?
              1
              # true; echo $?
              0
              

              Mais adapté à un shell, c'est logique.

              Dans tous les cas, le seul test intéressant, c'est nul ou non nul (on ne teste pas =1 pour vrai, on teste !=0).

              Quand on lance un programme, ce qui nous intéresse c'est de savoir si oui ou non le programme s'est bien exécuté (une seule possibilité). Dans le cas contraire, il peut être intéressant de savoir ce qui a planté. Du coup on peut avoir différents codes retours pour différentes situations.

              Donc c'est plus logique d'attribuer 0 à ok et !0 à toutes les situations non ok.

              Si je fais un if (rm toto) et que la commande « plante » (parce que le fichier toto n’existe pas par exemple) ma condition sera fausse.

              Je ne comprend pas.

              $ if (rm test); then echo ok; fi
              rm: cannot remove `test': No such file or directory
              $ touch test; if (rm test); then echo ok; fi
              ok
              
              • [^] # Re: false

                Posté par  . Évalué à 2.

                $ if (rm test); then echo ok; fi
                rm: cannot remove `test': No such file or directory
                $ touch test; if (rm test); then echo ok; fi
                ok
                

                Bah c’est justement ce que je dis, dans le premier cas la commande a un code retour ≠ 0 la condition est fausse alors que dans la deuxième le code retour est 0 est la condition est vrai :

                ≠ 0 implique faux
                0 implique vrai

                Donc c'est plus logique d'attribuer 0 à ok et !0 à toutes les situations non ok.

                Oui mais quand on apprend la logique on note 0 = faux et 1 = vrai, c’est le contraire en shell.

                Dans les autres langages de programmation on également plutôt l’habitude qu’une valeur différente de zéro soit évaluée vraie et zéro soit évalué faux.

                • [^] # Re: false

                  Posté par  . Évalué à 4.

                  Dans les autres langages de programmation on également plutôt l’habitude qu’une valeur différente de zéro soit évaluée vraie et zéro soit évalué faux.

                  Dans les autres langages de programmation true == vrai et false == faux.

                  Lorsqu'en c++ je fais un operateur de cast en bool, je renvoie true ou false, pas 0 ou 1.

                  Il m'arrive bien de faire if(ptr) ptr->…, mais je ne fais pas ça avec un entier par exemple.

                  Si j'ai un entier ou un type énuméré, je ne joue pas avec if( variable); au fait si ta variable c'est un flottant ça donne quoi ?

                  Alors certes, en C, c'est un poil différent, et j'ai déjà eu des blague avec des gens qui avaient fait des #define TRUE 1
                  qui ensuite faisaient des if( machin()==TRUE ) qui marchait pas parce que machin renvoyait autre chose que 0 et 1. (à noter que j'ai horreur des == true )

                  Ensuite si toutes les conventions de tous les langages étaient identique, on aurait qu'un seul langage :P

                  Il ne faut pas décorner les boeufs avant d'avoir semé le vent

                • [^] # Re: false

                  Posté par  . Évalué à 2.

                  Dans les autres langages de programmation on également plutôt l’habitude qu’une valeur différente de zéro soit évaluée vraie et zéro soit évalué faux.

                  3 cas, en fait.

                  1er cas : les pointeurs. Un pointeur nul signale une erreur, sinon c'est un succès.
                  2ème cas: les codes d'erreurs. Dans ce cas, 0 est souvent un succès, parce que c'est le code "erreur nulle".
                  3ème cas: on retourne pas de codes d'erreur, on les lance à coup d'exception.

                  Du coup, en fonction de si la bibliothèque renvoie des pointeurs ( fopen ) ou si elle renvoie des indexes ( open ) on se retrouve avec l'une ou l'autre philosophie. Pour la plupart des fonctions systèmes on à aussi le fameux errno, qui est à 0 quand aucun problème ne s'est produit.
                  Enfin, bien sûr ici je parlais du C.
                  Au final, on à bien 0 = false. C'est juste que tu ne te poses pas la bonne question. En fait, la question ce n'est pas "foo à t-il fonctionné correctement? (1=vrai, 0=faux)" mais "y'a-t-il eu une erreur lors du fonctionnement de foo? (1=vrai:échec, 0=faux:succès)". Avec le cas des pointeurs qui est une exception, car les pointeurs nuls sont invalides (mais est-ce vraiment imposé par le langage C, ou est-ce juste une convention? J'ai un doute…).

                  Dans des langages plus "évolués", on à plus souvent tendance à causer d'exceptions, du coup la valeur de retour ne signale plus les erreurs…

    • [^] # Re: false

      Posté par  . Évalué à 3.

      Le but de "true" et de "false" est d'ailleurs de les associer à des tests, non ?

      Emacs le fait depuis 30 ans.

      • [^] # Re: false

        Posté par  . Évalué à 4.

        Moi j'aime bien aussi utiliser true pour remplacer un binaire de mon système, par exemple pour overrider une commande défaillante qui est appelée dans un script de post-configure dpkg.
        C'est assez gruik et puis le truc c'est qu'on a tendance à oublier cette manip, jusqu'au moment où cette commande a vraiment son utilité… (dédicace perso à la personne qui a débuggé ma debian encore hier soir :p)

      • [^] # true et false

        Posté par  . Évalué à 2.

        Le but de "true" et de "false" est d'ailleurs de les associer à des tests, non ?

        Alors apparemment, leur intérêt de base est de servir de booléens pour alléger les tests ultérieurs.

        # Traitement des options
        faire_truc=false
        while [ $# -gt 0 ]; do
            case "$1" in
                --truc)
                    faire_truc=true
                    ;;
        []
            esac
            shift
        done
        
        if $faire_truc; then
            [On fait le truc]
        fi

        ou même

        $faire_truc && [on fait le truc]

        Si true et false n’étaient pas des commandes (ou qu’on utilisait à la place 0 et 1, oui et non…), il faudrait des tests plus lourds du style :

        if [ "$faire_truc" = "true" ]; then
        
        [ "$faire_truc" = "true" ] &&

        « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

        • [^] # Re: true et false

          Posté par  . Évalué à 1.

          Si true et false n’étaient pas des commandes (ou qu’on utilisait à la place 0 et 1, oui et non…), il faudrait des tests plus lourds du style :

          Comme je l'ai montré plus haut, pas besoin de if, true ou &&/|| pour faire une exécution conditionnelle en shell. Il suffit des opérateurs de substitutions !

          # commande a exécuter que si la variable COND est nulle ou vide
          ${COND:+:} ${COND:-commande}
          # et inversement, à n'exécuter que si COND n'est ni nulle ni vide
          ${COND:+commande}

          On peut donc très bien se passer de 'test' en utilisant les substitutions par commandes expr, sed, ls, readlink (bon ok là on pousse un peu) et les substitutions sur motifs (${var%motif} et autres) … :-)

          Dans l'autre exemple que j'ai montré, utilisé à bon escient ça peut être plus lisible, je trouve (tm)

          • [^] # Re: true et false

            Posté par  . Évalué à 6.

            Le problème est que ce n'est pas super lisible.
            Déjà que le shell n'est pas génial dans ce domaine, il n'est généralement pas utile d'en rajouter.

          • [^] # Re: true et false

            Posté par  . Évalué à 5.

            # commande a exécuter que si la variable COND est nulle ou vide
            `{mathjax} {COND:+:} `{COND:-commande}
            # et inversement, à n'exécuter que si COND n'est ni nulle ni vide
            ${COND:+commande}

            Rassure-moi, tu ne fais pas partie des gens qui trouvent le langage Perl illisible, au moins ?

            « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

            • [^] # Re: true et false

              Posté par  . Évalué à 2.

              J'aurais envie de répondre que non mais ça serait un peu malhonnête; je préfère encore me faire taxer d'avoir une double personnalité :D

              Pour enfoncer un peu le troll^Wclou, je vais ajouter que le principal problème du shell c'est qu'il est trop simple d'accès et à la fois trop compliqué à utiliser correctement. Un peu comme javascript quoi… Omni-présent, ayant des défauts (mal/méconnus), mais surtout, ils sont utilisés n'importe comment et par n'importe qui!

              Il est vrai que je connais pas trop bien perl pour pouvoir le juger et puis quand je l'utilise j'essaye de faire les trucs les plus simples et correctes possible. Et connaissant mes limites, j'essaye à ne jamais avoir à modifier un script de quelqu'un d'autre ! (La fois où j'ai du faire cela, et encore c'était quelque chose de relativement trivial, j'ai quand même tout réécrit).

              Par contre, quand j'utilise shell, j'aimes bien l'utiliser au maximum de ses capacités, et, malgré qu'elles soient très réduites, cela permet de faire des choses élégantes, parfois. Donc bref, pour répondre à Kerro, je ne code pas pour me faire relire par des incompétents… :-) C'est valable pour tout les languages. Va-t-on demander à un Chinois s'il trouve que son écriture est illisible ?

              Par exemple, je trouve plus élégant de faire

              debug=${cond:+echo}
              : ${debug=:} # $debug vaut 'echo' ou ':'
              
              $debug "Hello"
              $debug "World!"

              que

              debug=${cond:+true}
              : ${debug=false}
              $debug || echo "Bonjour"
              $debug || echo "Monde!"

              Ou encore pire encore, un gros if qui te prend déja 15 lignes rien que pour mettre une valeur à "true" ou "false". Après, les goûts, …

              • [^] # Re: true et false

                Posté par  . Évalué à 3. Dernière modification le 15 décembre 2015 à 17:45.

                EDIT :
                J’ai tout lu de travers, merci de ne pas lire la suite que je laisse pour je ne sais quelle raison… peut-être par honnêteté intellectuelle… bêtise, pour me faire fouetter… ou… choisissez.


                Dans ton cas, moi je fais :

                debug=echo
                
                $debug "Hello"
                $debug "World!"

                Pour du debug et si je n’en veux plus :

                $debug "Hello"
                $debug "World!"

                Voir, si les deux commandes ci-dessus sont dans hello.sh

                debug=echo ./hello.sh
              • [^] # Re: true et false

                Posté par  . Évalué à 1.

                PS: En recherche d'inspiration ou d'une bonne lecture sur l'oreiller ? Je vous conseille les /usr/src/build.sh, /etc/rc.subr et autres /usr/src/Makefile.inc* (tant qu'à faire..) de NetBSD et FreeBSD. Vous me remercierez ensuite (ou pas…).

  • # paste

    Posté par  . Évalué à 4.

    La commande paste permet de prendre plusieurs fichiers et de concaténer chaque ligne entre elles. C'est parfois pratique. :)

    Exemple : tu as f1 et f2 qui contiennent chacune une ligne, « Salut » pour f1 et « ça va ? » pour f2, paste f1 f2 va te donner la ligne « Salut ça va ? ».

    • [^] # Re: paste

      Posté par  . Évalué à 3. Dernière modification le 10 décembre 2015 à 12:25.

      un peu comme "cat f1 f2" alors ? ;)

      non en fait

      info coreutils 'paste invocation'
      indique que ça le fait ligne par ligne, avec une tabulation entre les éléments :

      $ cat num2
           1
           2
      $ cat let3
           a
           b
           c
      $ paste num2 let3
           1       a
           2       b
                   c
      

      « Le pouvoir des Tripodes dépendait de la résignation des hommes à l'esclavage. » -- John Christopher

      • [^] # Re: paste

        Posté par  . Évalué à 7.

        paste est surtout utile quand on doit manipuler des fichiers par colonne (csv, donnée pour gnuplot …)
        Il s'utilise aussi conjointement à cut :

        $ cut -f 1 -d ";" f1.csv > f1_1.csv
        $ cut -f 3 -d ";" f2.csv > f2_3.csv
        $ paste f1_1.csv f2_3.csv > f3.csv

        Ces trois commandes permettent de fussioner la colonne 1 d'un fichier et la colonne 3 d'un autre fichier.

        • [^] # Re: paste

          Posté par  . Évalué à 7.

          Ou plus simplement :
          paste <(cut -d';' -f1 f1.csv) <(cut -d';' -f3 f2.csv)

  • # comm

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

    Grand inconnu des utilisateurs, comm est magique dès qu'on cesse de l'utiliser sur des ligne de texte.

    Par exemple :

    #!/bin/bash
    
    function getlist {
        cd $1 && find . -type f -exec cksum {} \; | sort
    }
    
    comm -3 <(getlist $1) <(getlist $2) | sort -k 3,3

    Va lister le contenu de deux répertoires en affichant les fichiers présent uniquement dans la première arborescence dans la première colonne et ceux uniquement dans la seconde précédé par une tabulation (si on veut les fichiers présent des deux côtés, il suffit de supprimer le -3)

    C'est le genre d'outil qui rend les choses beaucoup plus facile quand on les connait !

  • # LFS ....

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

    < mode = PUB >

    On peut trouver une liste équivalente dans le livre LFS disponible ici

    Pour chacun des paquets de base, on retrouve la liste des binaires installés avec une description courte. Par exemple, pour les coreutils, il faut aller chercher sur cette page.

    LFS permet de construire son système, mais il peut également être un livre de référence ;o)

    < /mode >

  • # Unlink

    Posté par  . Évalué à 3.

    Il se vend comme un rm sans option qui fait juste un appel système à la primitive Posix unlink.

    Extrait de info unlink:

    Synopsis: It avoids the bells and whistles of the more commonly-used ‘rm’ command

    En plus, ça n'a pas l'air bien portable:

    On some systems ‘unlink’ can be used to delete the name of a directory. On others, it can be used that way only by a privileged user. In the GNU system ‘unlink’ can never delete the name of a directory.

  • # while true

    Posté par  (site web personnel) . Évalué à 10. Dernière modification le 10 décembre 2015 à 14:21.

    basename
    Voir dirname

    […]

    dirname
    Voir basename

    :-)

    • [^] # Re: while true

      Posté par  (site web personnel) . Évalué à 3. Dernière modification le 10 décembre 2015 à 14:37.

      Joli !

      Il faut y voir une « Recursive shell bomb » ?

    • [^] # Re: while true

      Posté par  . Évalué à 10.

      Récursion
      Voir récursion

  • # STOW

    Posté par  . Évalué à 6.

    install
    Copie de fichiers d'un endroit vers un autre.
    La page de manuel recommande quand même d'utiliser un vrai gestionnaire de package.

    Lorsque, dans ma jeunesse, je m'amusais à compiler plein de logiciels hors package manager, j'utilisais stow (un autre logiciel gnu) : http://www.gnu.org/software/stow/

    Le principe est un peu celui d'un package manager. Ça permet d'installer des logiciels sans saloper /bin /sbin, etc. Et donc de désinstaller simplement.

    À la différence de la majorité des packages manager, ça maintient une liste de symlinks, plutôt que de gérer l'emplacement des fichiers (vu qu'on prend des paquets sources, et pas packagés).

  • # Excellent post

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

    Excellent post, merci !

    Sinon, install est souvent utilisé dans "make install" (ou équivalent), notamment au moment de créer des paquets. Ce n'est donc pas un concurrent minable du package manager mais une commande de bas niveau pour copier un fichier en spécifiant les droits.

  • # units

    Posté par  . Évalué à 4.

    Concernant numfmt, moi j'aime bien la commande units. Elle permet de convertir plein de choses en plein d'autres chose

    You have: 3km
    You want: millilightyear
    * 3.1710025e-10
    / 3.1535768e+09
    You have: 82kg
    You want: sunmass
    * 4.1224674e-29
    / 2.4257317e+28
    You have: A4paper
    You want: cm2
    * 623.7
    / 0.0016033349
    You have: 1 pint
    You want: nebuchadnezzar
    * 0.031545098
    / 31.700646

    • [^] # Re: units

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

      J'offre une bière à celui qui implémente les conversions monétaires en temps réel dans units(1).

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

      • [^] # Re: units

        Posté par  . Évalué à 3.

        J'offre une bière à celui qui implémente les conversions monétaires en temps réel dans units(1).

        Suffit de transformer units en composante de Weboob. :)

        Pas très compliqué à priori. Il suffit de trouver le site Web kivabien et de le scrapper.

        (Note : ça ne veut pas dire que je vais le faire, mais je dis juste que ça ne me semble pas hautement infaisable).

        • [^] # Re: units

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

          Je crois que c'est dans le livre de K&R sur la programmation UNIX où justement en exemple on doit parser une page Internet concernant la bourse pour retrouver les données intéressantes en console.

  • # infinite loop detected

    Posté par  . Évalué à 5.

    basename : voir dirname.
    dirname : voir basename.

    J'ai l'impression d'être dans un Larousse.

  • # Des oublis ?

    Posté par  . Évalué à 2.

    "more", "awk" et "perl" ne font pas partis du système de base ?

    Emacs le fait depuis 30 ans.

    • [^] # Re: Des oublis ?

      Posté par  . Évalué à 3.

      awk et perl méritent bien leur propre paquet.

      Quand à more , il se trouve dans util-linux.

      Discussions en français sur la création de jeux videos : IRC freenode / #gamedev-fr

      • [^] # Re: Des oublis ?

        Posté par  . Évalué à 6.

        Quand à more , il se trouve dans util-linux.

        Mais bon, est-ce une bonne idée de s'en servir quand less(1) (paquet éponyme) est généralement toujours installé ?

        Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

        • [^] # Re: Des oublis ?

          Posté par  . Évalué à 2.

          est-ce une bonne idée de s'en servir

          Ça t’évite de finir par devoir retaper deux fois des commandes quand tu te retrouves sur un AIX qui ne connaît que more, parce que tes doigts tapent less plus vite que ton cerveau ne réfléchit ^^

          D’après le man de more:

          Cette version est particulièrement primitive. Les utilisateurs doivent se convaincre que
          less(1) constitue une excellente émulation de more(1) avec en plus de nombreuses améliorations.

          Le fait que ce programme soit toujours disponible ne serait-il pas lié à la norme POSIX ?

          • [^] # Re: Des oublis ?

            Posté par  . Évalué à 5.

            which less &>/dev/null || alias less=more

            Il ne faut pas décorner les boeufs avant d'avoir semé le vent

        • [^] # Re: Des oublis ?

          Posté par  . Évalué à 1.

          Quand tu as ni less pré-installé (même sur une distro GNU/Linux) ni Internet pour l'ajouter, oui, meilleur que cat en tout cas pour cet usage.

          Emacs le fait depuis 30 ans.

  • # logname != whoami

    Posté par  . Évalué à 6.

    Il me semble que logname et whoami sont différents. logname donne le nom de l'utilisateur qui s'est connecté au système (via /bin/login) alors que whoami est l'utilisateur courant. Il suffit de tester après une commande su pour s'en convaincre. Je confirme ça une fois au boulot.

    • [^] # Re: logname != whoami

      Posté par  . Évalué à 10. Dernière modification le 11 décembre 2015 à 10:13.

      foo$ logname
      foo
      foo$ whoami
      foo
      foo$ su - bar
      bar$ whoami
      bar
      bar$ logname
      foo
  • # Effet buf !

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

    stdbuf
    Lance une commande et change la façon dont ses entrées/sorties sont bufferisées.
    Après quelques essais sur mes logs, je ne vois pas de différence lors d'un grep sur 200Mo.

    En fait, je n’en ai eu aucune utilité pendant très longtemps, parce que par défaut, le buffer est géré assez intelligemment : en privilégiant l’efficacité pour les fichiers et les pipes, en le vidant à chaque fin de ligne pour la sortie standard.

    Le problème, avec les trucs intelligents, ce sont les cas particuliers où ils deviennent des conneries.

    En l’occurrence, la surveillance de quelque chose qui ne produit qu’une trace de temps en temps, afin de lancer une commande suite à certaines traces.

    Donc je fais tranquillement un

    udevadm monitor --udev |

    pour traiter la sortie derrière et… ça ne fonctionne pas, en tout cas pas avant que d’autres traces se soient accumulées, parce que le buffer du pipe n’est vidé que quand il est assez plein.

    Là, stdbuf permet de résoudre le problème en réglant le buffer pour qu’il se vide à chaque ligne :

    stdbuf -oL udevadm monitor --udev |

    Prendre une bonne disposition : beop.free.fr

  • # il y a une commande pour ça

    Posté par  . Évalué à 4.

    Dans mon cas elle s'appelle stdbuf.
    Merci pour ton post, je connaissais la majorité de ces commandes mais pas toues et une m'a attiré l'oeil : stdbuf.

    Dans ce post, j'écris mes déboire pour faire quelque chose qui me semblait très simple : transformer un script qui produit une ligne en sortie pour une ligne en entrée mais qui nécessite un init assez long en un service persistant tournant sur ma machine. Je pensais utiliser un pipe, voire une socket unix voire ip.

    Au final, la bonne réponse dans mon cas est bien un pipe. Mais quelle que soit la solution, je butais sur un problème : le script ne produit rien. En fait, il ne produit pas systématiquement une sortie pour une entrée : il bufferise. Ma solution a été d'ajouter un "sys.stdout.flush()" dans mon script appelé. Cependant, ce n'est pas très générique car si j'ai besoin de traiter des lignes en masse, je ne voudrai pas pénaliser les performances en flushant à chaque ligne.

    J'ai donc, à la suite de la lecture de ce post, reversé le contrôle en modifiant le script appelant par "stdbuf -oL ./script1.py".

    Cela fonctionne tout aussi bien tout en étant plus propre à mon goût.

Suivre le flux des commentaires

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