web-dev-qa-db-fra.com

Pourquoi pipe au chat seulement pour rediriger?

Je vois parfois des choses comme:

cat file | wc | cat > file2

Pourquoi faire ceci?

Quand les résultats (ou les performances) seront-ils différents (favorablement) simplement:

cat file | wc > file2
29
OJFord
cat file | wc | cat > file2

serait généralement deux utilisations inutiles de cat comme cela est fonctionnellement équivalent à:

< file wc > file2

Cependant, il peut y avoir un cas pour:

cat file | wc -c

plus de

< file wc -c

C'est-à-dire désactiver l'optimisation que de nombreuses implémentations wc font des fichiers réguliers.

Pour les fichiers réguliers, le nombre d'octets dans le fichier peut être obtenu sans avoir à lire tout le contenu du fichier, mais simplement à effectuer un appel stat() Système l'appelez et récupérez la taille que celle stockée dans l'inode.

Maintenant, on peut vouloir que le fichier soit lu par exemple parce que:

  • les informations stat() ne peuvent pas être approuvées (comme pour certains fichiers dans /proc ou /sys sur Linux):

    $ < /sys/class/net/lo/mtu wc -c
    4096
    $ cat /sys/class/net/lo/mtu | wc -c
    6
    
  • on veut vérifier la quantité de données pouvant être lues (comme dans le cas d'un disque dur défaillant).
  • on veut juste obtenir des points de repère sur la vitesse rapide des données.
  • on veut que le contenu du fichier soit mis en cache en mémoire.

Bien sûr, ce sont des exceptions. Dans le cas général, vous préférez utiliser < file wc -c Pour des raisons de performance.


Maintenant, vous pouvez imaginer encore plus de scénarios extrêmes extrêmes où on peut vouloir utiliser: cat file | wc | cat > file2:

  • peut-être wc a un profil d'APPARMOR ou un autre mécanisme de sécurité qui l'interdit de lire ou d'écrire dans des fichiers alors qu'elle est autorisée pour cat (qui serait inouïe)
  • peut-être cat est capable de traiter de gros (comme dans> 232 octets) fichiers, mais pas wc sur ce système (des choses comme si elles ont été nécessaires pour certaines commandes sur certains systèmes du passé).
  • peut-être que l'on veut wc (et le premier cat) pour exécuter et lire le fichier entier (et être tué à la toute dernière minute) même si file2 Vous ne pouvez pas être ouvert pour écrire.
  • peut-être que l'on veut cacher l'échec (Statut de sortie) d'ouverture ou de lecture du contenu de file. Bien que wc < file > file2 || : Aurait plus de sens.
  • peut-être que l'on veut cacher (à partir de la sortie de lsof (liste des fichiers ouverts))) Le fait qu'il obtienne un nombre de mots à partir de file ou qu'il stocke un nombre de mots dans file2.
32
Stéphane Chazelas

Ces deux exemples sont tilisations inutiles de CAT . Les deux sont équivalents à wc < file1 > file2. Il n'y a aucune raison d'utiliser cat dans cet exemple, sauf si vous utilisez cat file comme un stand-in temporaire pour quelque chose qui génère de manière dynamique la production.

37
larsks

Bien que je ne suis pas en désaccord avec l'argument pour dire qu'il s'agit d'une "utilisation inutile de chat", il Can Les raisons pour cela:

Dans de nombreuses langues (y compris l'anglais), les mots et les phrases sont lus de gauche à droite, ce qui montre que le flux de données de la même manière peut apparaître plus naturel au lecteur.

Une raison pour le deuxième cat pourrait être de masquer le code de retour. Tel que:

$ wc < /etc/passw
sh: /etc/passw: Cannot find or open the file.
$ echo $?
1

Alors que avec cat:

$ wc < /etc/passw | cat
sh: /etc/passw: Cannot find or open the file.
$ echo $?
0

Cela peut entrer en jeu si la coquille a set -e ensemble. Dans le premier exemple, cela abandonnerait la coquille après wc alors que dans ce dernier exemple, cela continuerait. De toute évidence, il y a d'autres moyens de traiter cela.

De plus, la différence de performance des deux déclarations (c'est-à-dire avec ou sans CAT) est négligeable (en particulier sur les machines d'aujourd'hui) et s'il était important, Shell est la mauvaise langue à utiliser.

17
DarkHeart

Supposons que prog fourche une nouvelle sous-processus et des sorties, et la nouvelle sous-processus écrit quelque chose à sa sortie standard puis en sorties.

Alors la commande

prog

ne pas attendre que le sous-traitement quitte, et il affichera l'invite de la coquille tôt. Mais la commande

prog | cat

j'attendra un EOF sur le stdinal de cat, qui attend efficacement le sous-processus de quitter. Il s'agit donc d'une utilisation utile de cat.

9
pts