Si je veux que le contenu de file2
corresponde à celui de file1
, je pourrais évidemment simplement courir cp file1 file2
.
Toutefois, si je veux tout conserver, à l' file2
exception du contenu (propriétaire, autorisations, attributs étendus, ACL, liens physiques, etc.), je ne voudrais pas courir cp
. contenu de file1
dans file2
.
Il semble que ce qui suit le ferait:
< file1 > file2
Mais ça ne marche pas. file2
est tronqué à rien et non écrit. cependant,
cat < file1 > file2
ça marche.
Cela m'a surpris que la première version ne fonctionne pas.
La deuxième version est-elle un UUOC? Y a-t-il un moyen de faire cela sans invoquer une commande, simplement en utilisant des redirections?
Note: Je suis conscient que UUOC est plus un point de pédant qu'un véritable anti-pattern.
* Comme tniles09 découvert , cp
volonté dans le travail fait dans ce cas.
la source
< file1 > file2
ce soit ce que vous voulez dépend du shell.<
...file1
n'existe pas ou est illisible et que vous l'ouvrez<
avant que la>
sortie ne soit ouverte, puis considérez ce qui se passe lorsque vous autorisezcat
à essayer de l'ouvrir.cat
(par défaut), exécutant essentiellement la deuxième commande. Voir la réponse de Stéphane Chazelas ci-dessous pour plus de détails qu’un commentaire.Réponses:
cat < file1 > file2
n'est pas un UUOC. Classiquement,<
et>
faire des redirections qui correspondent à des duplications de descripteur de fichier au niveau du système. Les duplications de descripteurs de fichiers en elles-mêmes ne font rien (bon, les>
redirections sont ouvertes avecO_TRUNC
, donc pour être exact, les redirections en sortie tronquent le fichier en sortie). Ne laissez pas les<
>
symboles vous confondre. Les redirections ne déplacent pas de données - elles attribuent des descripteurs de fichier à d'autres descripteurs de fichier.Dans ce cas, vous ouvrez
file1
et affectez ce descripteur de fichier au descripteur de fichier0
(<file1
==0<file1
)file2
et affectez ce descripteur de fichier au descripteur de fichier1
(>file2
==1>file2
).Maintenant que vous avez deux descripteurs de fichier, vous avez besoin d'un processus pour regrouper les données entre eux - et c'est ce à quoi ils
cat
servent.la source
Ce n'est pas le cas, car, comme d'autres l'ont souligné, le comportement en question dépend du shell. Comme vous l'avez fait remarquer, c'est un peu pédant , peut-être même drôle. , genre de sujet.
Cependant, sur les systèmes GNU, votre prémisse a une autre solution disponible:
cp --no-preserve=all file1 file2
. Essayez ceci, je pense que cela satisfera la situation décrite (par exemple, modifier le contenu defile2
tout en ne modifiant pas ses attributs).Exemple :
UPDATE En fait, je viens de remarquer que mon système lui-
cp
même semble conserver les attributs sauf si-a
ou-p
sont spécifiés. J'utilise bash shell et GNU coreutils. Je suppose que vous apprenez quelque chose de nouveau chaque jour ...Résultats de test (par Wildcard) incluant un lien physique et différentes autorisations:
la source
Dans
zsh
, le shell où< file1 > file2
fonctionne, le shell appellecat
.Pour une ligne de commande composée uniquement de redirections et pas de commande ni d'assignations,
zsh
invoque$NULLCMD
(cat
par défaut) à moins que la seule redirection ne soit une redirection,<
auquel cas$READNULLCMD
(pager
par défaut) est appelée à la place. (à moins que ce nezsh
soit danssh
ou l'csh
émulation, auquel cas il se comporte comme les coquilles qu'il émule).Alors:
est en fait le même que
et
est le même que
la source
ne fonctionne pas car il n'y a pas de commande là-bas; pas de processus. Le shell ouvre / crée les fichiers et organise les redirections (ce qui signifie que les descripteurs de fichiers référençant ces fichiers sont définis comme 0 et 1: entrée standard et sortie standard). Mais il n’ya rien à faire là-bas, exécuter une boucle pour lire à partir de l’entrée standard et écrire sur la sortie standard.
zsh
effectue ce travail en substituant une commande configurable par l'utilisateur dans ce cas de "commande NULL". La commande n'est pas visible dans la ligne de commande, mais elle est toujours là. Un processus est créé pour cela et il fonctionne de la même manière.NULLCMD
estcat
par défaut, donc signifie en< from > to
réalité danscat < from > to
zsh
, sauf siNULLCMD
est défini sur autre chose; c'est une commande "chat implicite".Une "utilisation inutile de chat" se produit lorsque
cat
est utilisé comme intermédiaire pour lire un fichier et transmettre les données à un autre processus, dont le descripteur de fichier pourrait simplement être connecté au fichier d'origine.Si
cat
est amovible de la situation, de sorte que les commandes restantes peuvent toujours effectuer la même tâche, il est inutile. Si ce n'est pas amovible, alors ce n'est pas inutile.A
cat
qui est replacable est pas la même chose. Par exemple, au lieu de,cat > file
nous pouvons utiliservi file
pour créer le fichier. Cela ne compte pas comme suppression decat
, tout en utilisant ce qui reste pour accomplir la même tâche.Si
cat
est le seul commande du pipeline, elle ne peut évidemment pas être supprimée. aucune réorganisation de ce qui reste ne fera le travail équivalent.Certains scripteurs de shell utilisent
cat
parce qu’ils pensent que cela leur permet de déplacer l’opérande d’entrée plus près du côté gauche de la ligne de commande. Cependant, les redirections peuvent être n'importe où dans la ligne de commande:la source
f -
de goudron.tar xf -
est justetar x
.cat
est impliqué dans la création du fichier? La réponse dit clairement que la coquille fait cela. De quel problème> file
parlez-vous? Je l’utilise souvent seul pour tronquer un fichier existant à une longueur nulle ou pour s’assurer qu’il existe. Cette question concerne pourquoi< from > to
ne fonctionne pas commecat < from > to
UUoC et non pas "donnez-moi s'il vous plaît des raisons pour lesquelles cecat
n'est pas un bon substitut pourcp
".tar
est l' archiveur de bandes . De nombreusestar
implémentations fonctionnent toujours avec le premier lecteur de bande par défaut.< file1 > file2
Cela semble dépendre du shell, sur zsh cela fonctionne, mais pas sur bash.edit: déclaration fausse supprimée
la source
cp -a
préserve les attributs de fichier1 et remplace les attributs de fichier2. Opposé du comportement souhaité. De plus, je ne peux même pas dire en consultant la page de manuel ce qui se passera avec les liens physiques, mais je pense qu’il est prudent de dire que les liens physiques de file2 ne seront pas conservés.En plus de toutes les bonnes réponses, vous pouvez éviter un UUOC en simulant un
cat
:Ces commandes ne copient pas les métadonnées du fichier, en clair
cp
ferait .la source
cat
. Ici, vous avez besoin d’une commande pour déplacer les données entre les deux descripteurs de fichier etcat
c’est l’un des meilleurs pour cela. Voyez aussipv
ce qui pourrait être utilisésplice()
sous Linux pour fifos (bien que ce ne soit pasfadvise(POSIX_FADV_SEQUENTIAL)
comme GNUcat
).dd
commande pour les fichiers binaires semble bonne ... oucat
fonctionnerait-elle aussi bien pour les fichiers binaires?cat
fonctionne également pour les fichiers binaires (Unix ne distingue généralement pas; cependant, certains outils fonctionnent spécifiquement ligne par ligne, tels que awk, grep, wc, ... POSIX définit également une longueur minimale de ligne, donc en théorie un outil orienté ligne pourrait refuser de traiter des lignes excessivement grandes.)sed '' < file1 > file2
;-)Si cela fonctionne, ne le répare pas.
j'utiliserais
et ne pas transpirer le PC de la sémantique.
la source