web-dev-qa-db-fra.com

Comment cette commande est-elle légale? "> file1 <file2 cat"

En supposant file2 existe déjà, la commande

> file1 < file2 cat

semble copier le contenu de file2 à file1.

Mais je ne peux pas comprendre cette structure.

Je comprends que "Rien" est dirigé vers file1, (création ou suppression de son contenu). Ensuite, le contenu de file2 est dirigé vers file1.

Pourquoi cat après file2? comment sait-il cat file2 si les opérandes ne sont pas dans le bon ordre?

61
shaqed

Avant que le shell n'exécute la commande cat sur la ligne de commande, il recherche les redirections.

Il existe deux redirections:

  1. >file1 Cela fera passer la sortie standard de la commande à file1.
  2. <file2 Cela fera que l'entrée standard de la commande proviendra de file2.

Le fait que ces redirections soient placées dans un emplacement bancal sur la ligne de commande n'a pas d'importance.

$ cat <file2 >file1

est le même que

$ <file2 cat >file1

ce qui est le même que

$ <file2 >file1 cat

etc.¹

Notez que l'utilitaire cat dans toutes ces instances est exécuté sans aucun argument de ligne de commande . Les redirections ne sont pas des opérandes de la commande cat, ce sont des instructions au Shell pour configurer des redirections dans et hors de la commande (en connectant ses entrées et sorties standard aux fichiers). Le shell configure les redirections avant d'appeler la commande.

La différence entre cat file et cat <file (ou, si vous voulez, <file cat) est que dans le premier cas, l'utilitaire cat lui-même ouvre le fichier, qui est donné comme opérande sur la ligne de commande, pour la lecture, tandis que dans le second cas, le Shell ouvrira le fichier et y connectera le flux d'entrée de cat². Dans le second cas, cat remarquera qu'aucun opérande de fichier ne lui a été attribué et basculera automatiquement en lecture à partir de son entrée standard. C'est une fonctionnalité de cat, et de certains autres utilitaires, pas quelque chose que tous les utilitaires font.

cat lira également à partir de son entrée standard si on lui donne l'opérande -. Encore une fois, ceci est spécial uniquement pour cat et pour certains autres utilitaires (c'est-à-dire rien que le Shell fait). Pour utiliser cat sur un fichier du répertoire courant dont le nom est -, ajoutez un chemin d'accès au nom de fichier, tel que ./-.

¹ L'ordre des redirections est toujours important dans certaines circonstances; Avec cat <file2 >file1, par exemple, file1 ne sera pas tronqué si file2 est inaccessible (les redirections sont analysées de gauche à droite). Le placement relatif du mot cat est cependant encore arbitraire et n'influencera pas cela.

² Voir aussi la question " cat donne une erreur différente lors de l'ouverture d'un fichier inexistant ".


Le fait que le shell configure les redirections avant même d'exécuter la commande sur la ligne de commande est la raison pour laquelle des choses comme celles-ci échouent et vous vous retrouvez avec un fichier de sortie vide:

$ sort file >file

Ici, le shell tronquera (vide) le fichier file avant d'exécuter sort file et en connectant la sortie standard de sort au fichier. L'utilitaire sort ouvrira alors file et triera son contenu (ce qui n'est rien). Le résultat (rien) est transmis via le flux de sortie standard à file.

Le remède dans ce cas particulier (pour trier un fichier "sur place") est

$ sort -o file file

ou

$ sort file >file.sorted && mv file.sorted file

qui est plus ou moins ce que fait sort lors de l'utilisation de -o fichier pour spécifier le nom du fichier de sortie.


Juste pour sauvegarder la déclaration selon laquelle les redirections peuvent précéder le nom réel de l'utilitaire sur la ligne de commande:

Une "commande simple" est une séquence d'affectations et de redirections de variables facultatives, dans n'importe quelle séquence, éventuellement suivie de mots et de redirections, terminée par un opérateur de contrôle. [réf: POSIX Shell Command Language 2.9.1 Commandes simples]

Et aussi sur la redirection ne faisant pas partie des opérandes de l'utilitaire:

Le numéro facultatif, l'opérateur de redirection et Word ne doivent pas apparaître dans les arguments fournis à la commande à exécuter (le cas échéant). [réf: redirection POSIX Shell Command Language 2.7)

118
Kusalananda