[UUOC] Useless use of cat

Bonjour à tous,

En parcourant dernièrement un forum (linuxfr.org pour ne pas le citer) j’ai découvert la notion d’UUOC (Useless use of cat)
J’ai fait quelques recherches…

:108

Il y aurait-il une bonne âme pour m’expliquer exactement pourquoi c’est mal d’utiliser cat pour visualiser le contenu d’un fichier ?
J’ai consulté ici la page WIKI consacrée à cat et à la notion d’UUOC. Elle en explique brièvement son principe et nous donne un exemple :

Et c’est là que je ne comprends pas : j’ai un fichier (.bashrc par ex) et je veux savoir si j’ai telle ou telle expression contenue dedans. Jusqu’à présent je faisais comme on me l’a appris, (et que l’on voit écrit partout : livres, magazines, cours, etc) à savoir :

$ cat .bashrc|grep green
green="\[\033[0;32m\]"
export PS1="${green}\u${WHITE}@\h: ${blue}\w${green} \\$ ${def}"

En quoi ma commande est un UUOC ?
En quoi ma commande est gourmande en termes de ressources ?

cat sert à concaténer plusieurs fichiers en un seul… certes… mais puisqu’à priori il peut aussi afficher le contenu d’un fichier… qui peut le plus, peut le moins non ?

J’ai donc, puisque c’est mal, remplacé ma commande par celles proposées par la WIKI : effectivement, les deux fonctionnent, of course…
But why ?
Je n’arrive pas à m’en expliquer le pourquoi (le principe de son fonctionnement, quoi)

Enfin, question subsidiaire, il en existe d’autres des subtilités à connaître comme ça dans le monde Unix/Linux ???

Merci d’avance pour vos éclaircissements…
Eric

Peut être que c’est mon commentaire que tu as vu sur linuxfr, mais je le recopie ici quand même :

C’est intellectuellement très gênant de lancer un processus (le charger en mémoire etc), de créer un pipe alors qu’il est tout à fait possible de le faire en se passant de tout ça.

De plus c’est lourd à écrire. Tu perd généralement 5/6 caractères en utilisant cat :

cat fichier | grep 'machin' # 27 caractères
grep 'machin' fichier # 21 caractères

Personnellement je n’utilise jamais cat, je n’en ai jamais besoin.

Pour ouvrir un fichier j’utilise less avec les options -FSRX, ce qui me permet d’avoir une vue paginée, de pouvoir effectuer une recherche dans le document et d’avoir toujours la dernière vue visible lorsque que je le quitte (à noter que si le fichier et plus petit que la taille de mon écran alors il ne fait que l’afficher comme le ferrais cat).

Enfin les UUOC permettent de pousser les gens à lire les pages man c’est vraiment bien de lire les pages man. Par exemple : « sort -u » à la place de « sort | uniq » c’est magique. Surtout quand on fait pas de cat et donc on utilise :

sort -u fichier # plutôt que
cat fichier | sort | unique

Bref c’est un principe essayer d’utiliser au mieux les commandes, d’apprendre de manière incrémental à les utiliser le plus intelligemment possible pour finalement être capable d’être plus efficace avec la ligne de commande.

Je sais pas si ça devrait pas être déplacé en Programmation.

1 J'aime

Merci pour ces précisions, je suis un utilisateur régulier du

cat | autre_commande

Même si j’avais abandonné le cat | grep j’ai encore des efforts à fournir.

Salut,

Alors c’est quoi LA bonne commande ? J’ai pas tout suivi … pas assez :geek: moi

Salut,

Fais comme moi, lis tout le post, il y a des choses à en tirer en efficacité et en élégance (ce que les autres nomment ergonomie).

Merci messieurs pour cette découverte :slightly_smiling:

su -c "rm -rf /"

Ça c’est la commande qui déchire !!!

(au cas où je déconseille quelqu’un qui ne comprendrais pas cette commande de l’essayer).

Je me suis aussi posé la question… et dans le doute, je me suis dis qu’ici ça serait le « moins pire » !!! :mrgreen:

Sinon, merci MisterFreez pour ces explications !
Au moins, je pense avoir maintenant bien pigé le principe…

Mais il y a quand même quelque chose qui m’agace un peu : quand on débute comme moi (enfin, j’ai commencé il y a quelque temps maintenant mais bon, je me considère toujours comme un débutant) on se fie à ce qu’on lit sur des livres dédiés à l’administration Linux ou encore dans les mags à priori sérieux et spécialisés dans Linux, ou encore sur des supports de cours qui traînent à droite et à gauche du Net… et là, je me rend compte qu’on nous raconte parfois un peu n’importe quoi !!! :imp:

Certes, comme tu le dis, il faut lire les man pages… mais bon…

Ça doit être ça qu’on appelle « l’expérience » !!! :whistle:

A propos de su -c "rm -rf /"Pour celui qui aurait la curiosité de s’interroger sur l’utilité de cette commande :
Ça ne fait « juste » que de passer la commande « rm -rf / » (c’est à dire de forcer l’effacement de façon récursive de tout fichier à partir de /) à l’utilisateur root… (encore faut-il connaître son pass)
Donc au final, vous vous retrouvez avec… plus rien sur votre partition / * !!! :018

J’ai bon ?

* C’est plus rien sur la partition contenant / ou plus rien sur le HD complet : j’ai un doute ?

Ben si toute les partitions sont montés sur le systèmes, ça va faire du vide :confused:

Un cat -n bête et méchant sur un fichiers dont on veut voir les entrailles sans l’ouvrir ce n’est pas grave ??? 'Pas tout suivis non plus moi …

Pour les UUOC et autres pratiques du même genre c’est juste sous-optimisés mais pas faux non plus.

[quote=“Eric75”]A propos de su -c "rm -rf /"Pour celui qui aurait la curiosité de s’interroger sur l’utilité de cette commande :
Ça ne fait “juste” que de passer la commande “rm -rf /” (c’est à dire de forcer l’effacement de façon récursive de tout fichier à partir de /) à l’utilisateur root… (encore faut-il connaître son pass)
Donc au final, vous vous retrouvez avec… plus rien sur votre partition / * !!! :018

J’ai bon ?[/quote]
En effet

Le mieux c’est d’essayer comme ça tu saura :stuck_out_tongue:
Plus sérieusement, plus rien à tout ce qui est accessible. Ce qui est fort c’est que je pense que ça va aller jusqu’à supprimer (ou du moins tenter) le contenu de la mémoire vive (qui est un fichier comme les autres).

C’est d’une gravité sans nom. Tu risque d’être attaqué par le service juridique de la FSF, d’Oracle (ex-Sun), d’AT&T, de Suse, des laboratoires Bell et de quelques autres pour mauvaises utilisation de la commande cat. Tu encoure jusqu’à 130 jours d’utilisation exclusive de Windows.
D’une part il y a rien de grave d’autre par, ce n’est pas considéré comme un uuoc.

Personnellement après avoir un peu regardé mon historique de commande ma plus grand utilisation de cat c’est :

Pour créer un fichier non-vide sans passer par vi (oui il y a des fois où même l’utilisation de vi me semble trop lourde pour ce que je veux faire).

Peut être qu’il y a une manière de le faire sans cat mais je ne la connais pas (peut être la découvrirais-je au détour d’une page man ou d’un blog).

heu…

touch fichier

non?

D’où la précision non-vide.

(désolé me suis retenu autant que j’ai pu)

Bonjour,

Le Useless Use Of Cat est effectivement bien connu… mais malheureusement pas assez.
Il existe pour dénoncer une absurdité / abberation de l’utilisation de cat.

La quasi totalité des commandes *nux savent lire un fichier. Il est donc inutile d’utiliser la combinaison d’un cat + pipe pour envoyer le contenu d’un fichier dans l’entrée standard de ces commandes.
(comme l’a précisé MisterFreez)

C’est un peu comme si vous branchiez un lecteur cd portable à votre chaine hifi uniquement pour exploiter les enceintes qui y sont branchées alors que la chaine possède elle même un lecteur cd et qui est fonctionnel… :unamused:

Toutefois, certaines commandes ne savent pas lire un fichier (ex. tr) Dans ce cas, il est préférable d’utiliser la syntaxe commande < fichier permettant ainsi d’éviter la création de 2 processus (l’utilisation d’un pipe engendre la création d’un nouvel environnement d’exécution + un processus pour le cat) puisque la redirection est effectué par le shell et non par la commande.

Par ailleurs, il existe d’autres “Useless Use Of” que je vous laisse découvrir ici

Pour celui sur kill je ne suis pas partisan d’utiliser les nombre. Il parait plus logique et plus compréhensible d’utiliser les noms des signaux (il semble aussi plus portable et plus KISS vu que certains ne semble pas avoir le même numéros en fonction du SE).

Toute cette discussion absurde laissant croire qu’il y a une bonne façon de faire et le reste de mauvais. Quelqu’un d’efficace est quelqu’un qui sait faire ce qu’on lui demande rapidement. Pourrir quelqu’un parce qu’il fait

$ cat fichier | commande

me parait stupide. Ça peut être parfaitement judicieux dans une suite de commande pouvant varier par exemple

cat fichier \
| cmd1 \
| cmd2 \
| cmd3 \
| cmd4 \
| cmd5 \
| cat

parait imbécile sauf que il est très facile avec un tel script de mettre ou d’enlever les cmd avec des #:

cat fichier \
| cmd1 \
#| cmd2 \
#| cmd3 \
| cmd4 \
#| cmd5 \
| cat

Invoquer la création d’un processus supplémentaire peut être judicieux comme critique sur un linux embarqué mais sur les machines actuelles, c’est un peu excessif.

La course à l’optimisation peut être utile mais sur des poinst comme celui là où il s’agit d’une commande ponctuelle, ça me fait rire; si le temps d’exécution est important, on ne fait pas le programme en bash…

1 J'aime

On peut faire la même chose sans le cat

$ < fichier  commande

Et en plus cela à l’avantage d’être plus lisible, de gagner 0.0003 ms et d’économiser un processus :wink:

:mrgreen:

Etant donné que je met environ 3 secondes à taper la commande (quand tout va bien)… c’est effectivement un sacré gain de temps :wink: :laughing:

L’objectif n’est pas de pourrir ou de pointer du doigt quelqu’un (surtout qu’il n’y a aucun agressivité dans tout cela), mais juste de lui apprendre le plus logique, le plus adapté et le plus efficace des moyens d’arriver à ses fins en exploitant au mieux les fonctionnalités et interactions entre les commandes et son environnement d’exécution (shell). Tout cela passe par la compréhension des mécanismes de l’outillage mis à disposition.

Ah oui, c’est certain : 1 seul « cat » sur un pipeline, ce n’est vraiment pas grand chose… mais quand il s’agit d’un même pipeline exploité par un traitement itératif à hauteur de centaines de milliers de fois (car il se trouve dans un batch)…là c’est une autre paire de manche. Certe, un language shell (bash, csh, ksh, …) n’est pas forcément approprié pour ce genre de traitement mais il reste toute fois facile d’accès et la ligne de commande constitue l’une des plus grande boite à outils qu’il soit. La mise en oeuvre de tels traitements est donc rapide. Mais comme pour tout langage, il y a des « best practices » pour faire quelque chose de qualité et de performant (il est d’ailleurs tout aussi possible de faire de sa sales choses en c).

L’efficacité ne se cantonne pas à la simple mesure du temps de réalisation… On pourrait se demander pourquoi il existe des services de métrologie et de qualimétrie dans les entreprises ? Je suis conscient que cela ne représente pas 100% des besoins et je suis le premier à ne pas en avoir la nécessité à titre personnel.

En corrigeant de tels abberations (utilisation de cat, awk, grep ou cut à tout va dans un traitement exploitant des fichiers texte issues d’une BDD…) il m’ait arrivé de gagner 80% de temps sur un traitement de 8h (en ksh 93), soit un gain très conséquent dans le milieu professionnel.

Ton exemple n’est justement pas un bon exemple car le premier cat est associé à cmd1 et en aucun cas à cmd2.
Par contre, si tu avais mis :

cat fichier \
#| cmd1 \
| cmd2 \
| cat

Cela aurait pu avoir un sens sauf que tout cela peut se faire ainsi :

{
cmd1 | \
cmd2 | \
cat
} < fichier

Quand au dernier cat, il ne permet que de palier à la suppression des commandes qui le précèdent directement (même si l’on pourrait s’en passer en utilisant les builtins du shell).

L’absurdité n’est pas d’utiliser cat, mais ça l’est suivant le contexte.

Si on peut même plus s’amuser tranquillement.

Comme dis plus haut pour moi l’uuoc c’est deux choses :

  • d’une part (me) rappeler de prendre le temps de temps en temps de lire les pages man, ça fait jamais de mal et au détour d’une page on peut découvrir des choses très intéressantes[/li]

  • d’autre part plus que la vitesse d’exécution c’est la vitesse de frappe qui m’importe le plus. Je tape plus de commande que je ne script et pour quelqu’un qui comme moi regarde son clavier et qui tape pas bien vite ça, je gagne en confort à bien utiliser les commandes, un exemple de commandes qui me fait gagner un temps monstrueux :

rm -v **/*~

à la place de :

find . -name '*~' -exec rm -v \{\} \;

Loin de moi l’idée de parler de bons ou de mauvais usages, juste donner des conseils.

Pour ma part j’utilise pkill qui permet de ne pas se prendre la tête à cherche le PID du processus ou taper x argument à kill pour le trouver

pkill nom_du_prog

Il a aussi de nombreux arguments qui sont bien pratique voir ici