526 votes

Shell - Commandes multiples sur une ligne

Dire que j'ai un fichier /templates/apple et je veux

  1. mettre dans deux endroits différents, puis
  2. retirez l'original.

Donc, /templates/apple sera copié /templates/used ET /templates/inuse et puis, après ce que j'aimerais supprimer l'original.

Est - cp le meilleur moyen pour ce faire, suivi par rm? Ou est-il un meilleur moyen?

Je veux tout faire en une seule ligne donc, je pense qu'il ressemblerait à quelque chose comme:

cp /templates/apple /templates/used | cp /templates/apple /templates/inuse | rm /templates/apple

Est-ce la bonne syntaxe?

1051voto

Maxim Yegorushkin Points 29380

Vous utilisez | (pipe) pour diriger la sortie d'une commande dans une autre commande. Ce que vous cherchez est - && de l'opérateur d'exécuter la commande suivante que si la précédente a réussi:

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple

Ou

cp /templates/apple /templates/used && mv /templates/apple /templates/inuse

Pour résumer (non-exhaustive) de commande de bash opérateurs/séparateurs:

  • | conduites (canalisations) la sortie standard (stdout) d'une commande vers l'entrée standard d'une autre. Notez que stderr va encore dans sa destination par défaut, tout ce qui arrive d'être.
  • |&tuyaux à la fois stdout et stderr d'une commande vers l'entrée standard d'une autre. Très utile, disponible en bash version 4 et au-dessus.
  • && exécute la droite de la commande de l' && que si la précédente a réussi.
  • || exécute la droite de la commande de l' || seulement il la précédente a échoué.
  • ; exécute la droite de la commande de l' ; toujours, peu importe si la commande précédente a réussi ou échoué. À moins d' set -e a été précédemment invoquées, ce qui provoque bash échouer sur une erreur.

119voto

Marc B Points 195501

Pourquoi ne pas cp à la position 1, puis mv à la position 2. Cela prend soin de "retrait" de l'original.

Et non, ce n'est pas la bonne syntaxe. | est utilisé pour le "tuyau" de sortie d'un programme et de le transformer en entrée pour le prochain programme. Ce que vous voulez est - ;, qui se sépare de plusieurs commandes.

cp file1 file2 ; cp file1 file3 ; rm file1

Si vous avez besoin que les commandes individuelles DOIT se terminer avant la prochaine peut être démarré, vous devez alors utiliser && à la place:

cp file1 file2 && cp file1 file3 && rm file1

De cette façon, si l'une des cp commandes échoue, l' rm ne sera pas exécuté.

13voto

glenn jackman Points 69748

Notez que cp A B; rm A est exactement mv A B . Il sera plus rapide aussi, car vous n'avez pas besoin de copier les octets (en supposant que la destination est sur le même système de fichiers), renommez simplement le fichier. Donc, vous voulez cp A B; mv A C

5voto

Renaud Points 2779

À l’aide de tuyaux semble bizarre pour moi. En tout cas, vous devez utiliser la logique et bash opérateur.

Si le cp commandes échouent, la rm ne sera pas exécuté.

Ou, vous pouvez faire une ligne de commande plus élaboré en utilisant une boucle et cmp.

Renaud

3voto

Peter Points 1024

Essaye ça..

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X