Comment cette commande est-elle légale? “> Fichier1 <fichier2 cat”

61

En supposant file2qu'il existe déjà, la commande

> file1 < file2 cat

semble copier le contenu de file2to file1.

Mais je ne peux pas comprendre cette structure.

Je comprends que "rien" est dirigé vers file1(créer ou effacer son contenu). Ensuite, le contenu de file2est dirigé vers file1.

Pourquoi est cataprès file2? comment savoir cat file2si les opérandes ne sont pas dans le bon ordre?

shaqed
la source
11
Quel "ordre correct"? Pouvez-vous fournir un lien vers des ressources / du matériel d'apprentissage où un "ordre correct" est décrit?
Lightness Races avec Monica
7
Lorsque vous posez des questions comme celle-ci, vous devez spécifier le shell; les différents ont des cas différents, en particulier autour de la redirection.
chrylis -on strike-

Réponses:

117

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

Il y a deux redirections:

  1. >file1 Cela rendra la sortie standard de la commande à file1.
  2. <file2 Cela rendra l'entrée standard de la commande file2.

Le fait que ces redirections soient placées dans un emplacement insignifiant sur la ligne de commande importe peu.

$ cat <file2 >file1

est le même que

$ <file2 cat >file1

qui est le même que

$ <file2 >file1 cat

etc.¹

Notez que l' catutilitaire dans toutes ces instances est exécuté sans aucun argument de ligne de commande . Les redirections ne sont pas des opérandes pour la catcommande, mais des instructions pour permettre au shell de configurer des redirections dans et hors de la commande (en connectant son entrée et sa sortie standard à des fichiers). Le shell configure les redirections avant d' appeler la commande.

La différence entre cat fileet cat <file(ou, si l' on veut, <file cat) est que , dans le premier cas, l' catutilitaire lui-même ouvre le fichier, qui est donné comme un opérande sur la ligne de commande, pour la lecture, tandis que dans le second cas, la coque aura ouvrez le fichier et connectez catle flux d 'entrée à it². Dans le second cas, catremarquerez qu’il n’a pas reçu d’opérande de fichier et basculera automatiquement en lecture depuis son entrée standard. Il s’agit d’une caractéristique catet d’autres utilitaires que tous les utilitaires ne font pas.

catlit également à partir de son entrée standard si on lui donne l'opérande -. Encore une fois, cela n’est spécial que vers catet pour certains autres utilitaires (c’est-à-dire que le shell ne fait pas). Pour utiliser catun fichier dans le répertoire courant dont le nom est - , ajoutez un chemin d'accès au nom de fichier, par exemple ./-.

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

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


Le fait que le shell configure les redirections avant même d'exécuter la commande sur la ligne de commande explique pourquoi de telles choses échouent et que vous vous retrouvez avec un fichier de sortie vide:

$ sort file >file

Ici, le shell tronquera (vide) le fichier fileavant d'exécuter sort fileet de connecter sortla sortie standard au fichier. L' sortutilitaire va alors ouvrir fileet trier son contenu (ce qui n'est rien). Le résultat (rien) est transmis au 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

ce qui est plus ou moins ce que sortfait lorsque vous utilisez le -ofichier pour spécifier le nom du fichier de sortie.


Sauvegardez simplement que 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 de variables et de redirections facultatives, dans toute séquence, éventuellement suivies de mots et de redirections, terminées par un opérateur de contrôle. [ref: POSIX Shell Command Language 2.9.1 Commandes simples]

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

Le numéro facultatif, l'opérateur de redirection et le mot ne doivent pas apparaître dans les arguments fournis à la commande à exécuter (le cas échéant). [ref: Redirection du langage de commande POSIX Shell 2.7]

Kusalananda
la source
14
@Steve La liberté de déplacer des redirections peut être utilisée pour rendre certaines commandes plus claires, comme un pipeline avec une redirection d'entrée au début qui <in foo | bar >outplace tout dans un ordre logique. J'apprécie aussi beaucoup les echo >&2 Something bad happenederreurs générées par les scripts shell. Mais ce >out <in catn'est qu'un obscurcissement
2
Comment pourrait sort file >fileêtre correctement accompli?
seth10
11
@setht Avec sort -o file file.
Kusalananda
6
Très bonne réponse. Notez que l'ordre est important. < file1 > file2 catserait mieux que > file2 < file1 catcela éviterait d' file2être tronqué si file1on ne peut pas l'ouvrir.
Stéphane Chazelas
3
Ce qu'il faut savoir: lorsqu’un lien vers POSIX avec des fragments HTML, il est préférable de spécifier l’édition exacte (comme pubs.opengroup.org/onlinepubs/9699919799.2016edition ) car il est connu que les fragments changent entre les éditions d’une même révision de la spéc. (beaucoup de liens dans les réponses sur ce site, y compris le mien, sont maintenant erronés car les fragments pointent au mauvais endroit après la publication de l'édition 2016).
Stéphane Chazelas