web-dev-qa-db-fra.com

Quel est le consensus général sur "Utilisation inutile du chat"?

Lorsque je pipe plusieurs commandes Unix, telles que Grep, SED, TR, etc. J'ai tendance à spécifier le fichier d'entrée en cours de traitement à l'aide de CAT. Alors quelque chose comme cat file | grep ... | awk ... | sed ....

Mais récemment après quelques commentaires laissés sur mes réponses indiquant que c'était une utilisation inutile de chat, je pensais que je poserais la question ici.

J'ai regardé la question et je suis tombé sur la question article de Wikipedia sur UUC et l'utilisation inutile de CAT Award et il me semble que les arguments fabriqués sont du point de vue de l'efficacité.

La question la plus proche que j'ai rencontrée ici était celle-ci: est-ce inutile d'appeler Cat? - Mais ce n'est pas tout à fait ce que je demande.

Je suppose que suggère que le camp UUCOC est d'utiliser cmd1 args < file | cmd2 args | cmd3 .. ou si la commande a une option à lire depuis le fichier, puis passer dans le fichier sous forme d'argument.

Mais pour moi cat file | cmd1 ... | cmd2 semble beaucoup plus facile à lire et à comprendre. Je n'ai pas à me souvenir de différentes manières d'envoyer des fichiers d'entrée à différentes commandes et le processus s'écoule logiquement de gauche à droite. Première entrée, puis le premier processus ... et ainsi de suite.

Est-ce que je n'ai pas omis de comprendre quels arguments sont faits sur l'utilisation inutile du chat? Je comprends que si je gère un travail cron qui fonctionne toutes les 2 secondes qui fait beaucoup de traitement, alors dans ce cas, le chat pourrait être inutile. Mais sinon quel est le consensus général sur l'utilisation de chat?

41
arunkumar

Il est inutile dans le sens où l'utiliser comme ça ne fait rien d'autre que les autres options plus efficaces ne peuvent pas (c'est-à-dire de produire des résultats appropriés).

Mais cat est bien plus puissant que juste cat somefile. Consulter man cat ou lire ce que j'ai écrit dans cette réponse . Mais si vous n'avez absolument besoin que du contenu d'un fichier unique, vous pouvez obtenir un avantage de performance de ne pas utiliser cat pour obtenir au contenu du fichier.

En ce qui concerne la lisibilité, cela dépend de vos goûts personnels. J'aime cating des fichiers dans d'autres commandes pour la même raison, surtout si les aspects de performance sont négligeables.

Cela dépend aussi de ce que vous êtes script. Si c'est votre propre coquille et vos méthodes de commodité pour votre machine de bureau, personne sauf que vous vous souciez. Si vous trébuchez sur un cas où l'outil suivant de la chaîne serait préférable de pouvoir rechercher et distribuer cela comme un logiciel fréquemment utilisé sur un système minimal Linux sur un routeur basse performance ou un dispositif similaire avec des limites réelles sur capacité de traitement, c'est différent. Cela dépend toujours du contexte.

21
Daniel Beck

Dans chaque jour, utilisez la ligne de commande, il n'est pas vraiment très différent. Vous n'allez particulièrement remarquer aucune différence de vitesse depuis le temps sur la CPU évitée en n'utilisant pas cat, votre CPU va simplement être inactif. Même si vous êtes en boucle à travers des centaines ou des milliers (voire des centaines de milliers) d'objets de toutes les affaires, cela ne va pas faire beaucoup différence, sauf si vous êtes sur un système très chargé (charge la moyenne/N CPU> 1).

L'endroit où le caoutchouc rencontre la route consiste à former de bonnes habitudes et à décourager les mauvais. Pour traîner un cliché moisi, le diable est dans les détails. Et ce sont des détails comme celui-ci qui séparent le médiocre du grand.

C'est comme en conduisant une voiture, pourquoi faire un virage à gauche lorsque vous pouvez simplement faire trois droits? Bien sûr que vous pouvez, et cela fonctionne parfaitement. Mais si vous avez compris le pouvoir des virages à gauche, alors trois droits semblent idiotes.

Il ne s'agit pas d'enregistrer une poignée de fichier, 17k de RAM et 0,004 secondes de l'heure du processeur. Il s'agit de toute la philosophie de l'utilisation d'unix. La "puissance des virages de gauche" dans mon illustration n'est pas simplement simplement Redirection d'une entrée, c'est la philosophie UNIX. Entièrement grokking, cela vous fera exceller beaucoup mieux que ceux qui vous entourent, et vous ferez le respect de ceux qui comprennent.

17
bahamat

J'utilise souvent cat file | myprogram Dans des exemples. Parfois, je suis accusé d'une utilisation inutile de chat ( http://www.iki.fi/era/unix/award.html ). Je ne suis pas d'accord pour les raisons suivantes:

Il est facile de comprendre ce qui se passe.

Lors de la lecture d'une commande UNIX, vous vous attendez à une commande suivie d'arguments suivis de la redirection. IT est Possibilité de mettre la redirection n'importe où, mais il est rarement vu - ainsi que des gens auront un temps plus difficile de lire l'exemple. je crois

    cat foo | program1 -o option -b option | program2

est plus facile à lire que

    program1 -o option -b option < foo | program2

Si vous déplacez la redirection jusqu'au départ, vous confondez des personnes qui ne sont pas habituées à cette syntaxe:

    < foo program1 -o option -b option | program2

et des exemples doivent être faciles à comprendre.

Il est facile de changer.

Si vous connaissez le programme peut lire à partir de CAT, vous pouvez normalement supposer que cela peut lire la sortie de tout programme qui sortira à STDOUT, et vous pouvez donc l'adapter pour vos propres besoins et obtenir des résultats prévisibles.

Il souligne que le programme n'a pas échoué, si STDIN n'est pas un fichier régulier.

Il n'est pas sûr de supposer que si program1 < foo fonctionne alors cat foo | program1 va aussi travailler. Cependant, c'est est En pratique sûre pour assumer le contraire. Ce programme fonctionne si STDIN est un fichier, mais échoue si l'entrée est une tuyau, car elle utilise la recherche:

    # works
    < foo Perl -e 'seek(STDIN,1,1) || die;print <STDIN>'

    # fails
    cat foo | Perl -e 'seek(STDIN,1,1) || die;print <STDIN>'

J'ai examiné la pénalité de performance sur http://oletange.blogspot.dk/2013/10/USESSE-USE-OF-CAT.HTML La conclusion est n'utilise pas cat file | Si la complexité du traitement est similaire à celle d'un simple grep et de performances plus que la lisibilité. Pour d'autres situations cat file | c'est bien.

14
Ole Tange

Je pense que la position emmenée par certaines de ces commentaires sur quelque chose étant un UUC est que si on comprend vraiment la syntaxe UNIX et Shell, on n'utiliserait pas de chat dans ce contexte. Il est considéré comme comme en utilisant une grammaire médiocre: je peux écrire une phrase en utilisant une grammaire médiocre et que je pense toujours que mon point de vue, mais je démontre également ma mauvaise compréhension de la langue et par extension, ma mauvaise éducation. Donc, dire que quelque chose est un UUCC est une autre façon de dire que quelqu'un ne comprend pas ce qu'ils font.

En ce qui concerne l'efficacité, si vous exécutez un pipeline de la ligne de commande, il faut moins de temps pour que la machine soit exécutée cat somefile | il ne fait que pour vous de penser s'il pourrait être plus efficace d'utiliser < somefile. Cela n'a pas d'importance.

12
garyjohn

Je n'étais pas au courant de la récompense jusqu'à aujourd'hui lorsque certaines recrues ont essayé d'épingler l'UUCO sur moi pour une de mes réponses. C'était un cat file.txt | grep foo | cut ... | cut .... Je lui ai donné un morceau de mon esprit et seulement après avoir fait tellement visité le lien qu'il m'a donné en faisant référence aux origines du prix et à la pratique de le faire. Une recherche ultérieure m'a conduit à cette question. Un peu malheureusement malheureusement, malgré une considération consciente, aucune des réponses n'incluait ma justification.

Je n'ai pas voulu être défensive lorsque je l'éduque. Après tout, dans mes jeunes années, j'aurais écrit la commande comme grep foo file.txt | cut ... | cut ... Parce que chaque fois que vous faites le single simple greps, vous apprenez le placement de l'argument de fichier et il est prêt à savoir que le premier est le modèle et les derniers sont des noms de fichiers.

C'était un choix conscient lorsque j'ai répondu à la question avec le préfixe cat PREFIX en partie à cause d'une raison de "bon goût" (dans les mots de la Torvalds de linus) mais principalement pour une raison de la fonction convaincante.

Cette dernière raison est plus importante, je vais donc le mettre en premier. Lorsque je propose un pipeline comme solution, je m'attends à ce qu'elle soit réutilisable. Il est fort probable qu'un pipeline soit ajouté à la fin de ou épissé dans un autre pipeline. Dans ce cas, avoir un argument de fichier à Grep invite la réutilisabilité, et bien éventuellement silencieusement sans message d'erreur si l'argument de fichier existe. C'est à dire. grep foo xyz | grep bar xyz | wc vous donnera combien de lignes dans xyz contient bar _ pendant que vous vous attendez au nombre de lignes contenant à la fois foo et bar. Dès avoir à modifier des arguments en une commande dans un pipeline avant de l'utiliser, il est sujette aux erreurs. Ajoutez-y la possibilité d'échecs silencieux et cela devient une pratique particulièrement insidieuse.

La première raison n'est pas sans importance que de nombreux "goûts" sont simplement une justification subconsciente intuitive des choses comme les défaillances silencieuses au-dessus que vous ne pouvez pas penser à raison pour le moment où une personne ayant besoin d'éducation dit "mais n'est pas ce chat inutile ".

Cependant, je vais essayer de faire consciemment l'ancien "bon goût" que j'ai mentionné. Cette raison concerne l'esprit de design orthogonal de Unix. grep ne pas cut et ls ne pas grep. Donc à tout le moins grep foo file1 file2 file3 va contre l'esprit de design. La façon orthogonale de le faire est cat file1 file2 file3 | grep foo. À présent, grep foo file1 est simplement un cas particulier de grep foo file1 file2 file3, et si vous ne le traitez pas, vous pouvez au moins en train d'utiliser des cycles d'horloge cérébrale essayant d'éviter le prix de CAT inutile.

Cela nous conduit à l'argument selon lequel grep foo file1 file2 file3 est concaténant et cat concaténate de sorte qu'il est propice à cat file1 file2 file3 mais parce que cat ne concaté pas dans cat file1 | grep foo Par conséquent, nous violons l'esprit de la fois le cat et le Tout-Puissant UNIX. Eh bien, si tel était le cas, UNIX aurait besoin d'une commande différente pour lire la sortie d'un fichier et la cracher à STDOUT (pas le paginer ou quoi que ce soit juste une broche pure à stdout). Donc, vous auriez la situation où vous dites cat file1 file2 ou vous dites dog file1 et rappelez-vous consciencieusement d'éviter cat file1 Pour éviter d'obtenir le prix, tout en évitant ainsi dog file1 file2 Comme, espérons-le, la conception de dog lancerait une erreur si plusieurs fichiers sont spécifiés.

J'espère que, à ce stade, vous sympathisez avec les concepteurs UNIX pour ne pas inclure une commande séparée pour cracher un fichier à stdout, tout en nommant cat pour concaténer plutôt que de lui donner un autre nom. <edit> Il y a un tel chien, le malheureux < Opérateur. Il est regrettable son placement à la fin du pipeline empêchant une composabilité facile. Il n'y a pas de moyen syntaxiquement ou esthétiquement propre de le placer au début. Il est également regrettable de ne pas être assez général suffisant pour que vous commenciez avec le chien, mais ajoutez simplement un autre nom de fichier si vous souhaitez également être traité après la précédente. (Le > D'autre part n'est pas la moitié aussi mauvaise. Il a un placement presque parfait à la fin. Il ne s'agit généralement pas d'une partie réutilisable d'un pipeline, et il est donc distingué symboliquement.) </edit>

La question suivante est pourquoi est-il important d'avoir des commandes qui ne craignent que de créer un fichier ou la concaténation de plusieurs fichiers à STDOUT, sans traitement ultérieur? Une des raisons est d'éviter de disposer de chaque commande UNIX qui fonctionne sur l'entrée standard pour savoir comment analyser au moins un argument de fichier de ligne de commande et l'utiliser comme entrée s'il existe. La deuxième raison est d'éviter que les utilisateurs devaient se rappeler: (a) où se déroulent les arguments du nom de fichier; et (b) éviter le bogue de pipeline silencieux comme mentionné ci-dessus.

Cela nous amène à pourquoi grep a la logique supplémentaire. La justification consiste à autoriser la fluidité utilisateur des commandes utilisées fréquemment et sur une base autonome (plutôt que comme un pipeline). C'est un léger compromis d'orthogonalité pour un gain important de convivialité. Toutes les commandes ne doivent pas être conçues de cette manière et les commandes qui ne sont pas fréquemment utilisées doivent éviter complètement la logique supplémentaire des arguments de fichier (rappelez-vous que la logique supplémentaire conduit à une fragilité inutile (possibilité d'un bug)). L'exception est d'autoriser des arguments de fichier comme dans le cas de grep. (En passant, notez que ls a une raison complète de non seulement accepter, mais pas à peu près des arguments de fichier)

Enfin, ce qui aurait pu être fait mieux, c'est si des commandes exceptionnelles telles que grep (mais pas nécessairement ls) génère une erreur si l'entrée standard est disponible. Ceci est raisonnable car les commandes incluent la logique qui enfreint l'esprit orthogonal de l'UNIX Tout-Puissant pour la commodité de l'utilisateur. Pour plus de commodité de l'utilisateur, i. e. Pour éviter les souffrances causées par une défaillance silencieuse, ces commandes ne devraient pas hésiter à violer leur propre violation en alertant l'utilisateur s'il existe une possibilité de défaillance silencieuse.

5
randomstring

Pour tous ceux qui disent que le chat est acceptable d'utiliser parce qu'il "sent" mieux ou "est plus lisible" que je ne dirais que ceci:

Pour vous peut-être ... mais pas envers les autres personnes qui peuvent lire ou essayer de comprendre votre code. Si vous n'essaierez jamais d'exercer d'autres d'autres avec vos exemples ou de partager votre code, alors par tous les moyens, veuillez l'utiliser à votre propre loisir.

J'ajouterai également ce commentaire, l'utilisateur et l'administrateur de Linux de longue date ... (et il y en a beaucoup d'entre nous), cela fait saigner nos yeux de voir cela. Pourquoi? Parce qu'il utilise des ressources sur des systèmes que nous contrôlons les ressources serrées. La commande CAT et le tuyau lui-même utilisent des poignées de mémoire et de fichier supplémentaires totalement inutiles. Vous avez noué des ressources que mon système a besoin gratuit et que vous n'avez rien gagné qui puisse expliquer l'utilisation de ces ressources. C'est un énorme non non.

Maintenant, je peux m'asseoir ici et débattre des choses comme le code odeur ou la lisibilité de la journée avec n'importe qui, mais à la fin de la journée, c'est une question d'écriture ou de fausse et de temps que vous utilisez des ressources sur un système et ne gagnez rien pour cela ... il est faux.

En tant qu'utilisateur à domicile, vous pouvez apprendre de mes conseils et apprendre de meilleures façons de faire des choses ou que vous pouvez choisir d'être aveuglés par "l'odeur" des chats, votre choix ... mais savez que si vous utilisez ouvertement cette pratique, vous serez appelé. Sur cette pratique tout le temps et vous devrez douter silencieusement qu'ils ont raison et vous êtes têtu parce que c'est vrai. :-)

0
David Dreggors