Dis que j'ai un fichier /templates/Apple
et que je veux
Ainsi, /templates/Apple
sera copié dans /templates/used
ET /templates/inuse
, puis je souhaite supprimer l’original.
Est-ce que cp
est le meilleur moyen de le faire, suivi de rm
? Ou y a-t-il un meilleur moyen?
Je veux tout faire en une seule ligne, je pense donc que cela ressemblerait à quelque chose comme:
cp /templates/Apple /templates/used | cp /templates/Apple /templates/inuse | rm /templates/Apple
Est-ce la syntaxe correcte?
Vous utilisez |
(pipe) pour diriger la sortie d'une commande dans une autre commande. Ce que vous recherchez, c'est l'opérateur &&
pour exécuter la commande suivante uniquement si la commande 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 (de manière non exhaustive) les opérateurs/séparateurs de commande de bash:
|
conduit (pipelines) la sortie standard (stdout
) d'une commande à l'entrée standard d'une autre. Notez que stderr
continue à utiliser sa destination par défaut, quel qu’il soit.|&
pipe à la fois stdout
et stderr
d'une commande dans l'entrée standard d'une autre. Très utile, disponible dans les versions 4 et supérieures de bash.&&
exécute la commande de droite de &&
uniquement si la précédente a réussi.||
exécute la commande de droite de ||
seulement la précédente a échoué.;
exécute la commande de droite de ;
toujours, que la commande précédente ait abouti ou non. Sauf si set -e
a déjà été appelé, ce qui entraîne l'échec de bash
en cas d'erreur.Pourquoi pas cp
à l'emplacement 1, puis mv
à l'emplacement 2. Cela permet de "supprimer" l'original.
Et non, ce n'est pas la syntaxe correcte. |
est utilisé pour "diriger" la sortie d'un programme et la transformer en entrée pour le programme suivant. Ce que vous voulez, c'est ;
, qui sépare plusieurs commandes.
cp file1 file2 ; cp file1 file3 ; rm file1
Si vous avez besoin que les commandes individuelles DOIVENT réussir avant que le prochain puisse être démarré, utilisez plutôt &&
:
cp file1 file2 && cp file1 file3 && rm file1
De cette façon, si l'une des commandes cp
échoue, le rm
ne s'exécutera pas.
Notez que cp A B; rm A
est exactement mv A B
. Ce sera plus rapide aussi, car vous n'avez pas à copier les octets (en supposant que la destination se trouve sur le même système de fichiers), il suffit de renommer le fichier. Donc, vous voulez cp A B; mv A C
Une autre option est de taper Ctrl+VCtrl+J à la fin de chaque commande.
Exemple (remplacez #
par Ctrl+VCtrl+J):
$ echo 1#
echo 2#
echo 3
Sortie:
1
2
3
Cela exécutera les commandes peu importe si les précédentes ont échoué.
Identique à: echo 1; echo 2; echo 3
Si vous souhaitez arrêter l'exécution sur des commandes ayant échoué, ajoutez &&
à la fin de chaque ligne, à l'exception de la dernière.
Exemple (remplacez #
par Ctrl+VCtrl+J):
$ echo 1 &&#
failed-command &&#
echo 2
Sortie:
1
failed-command: command not found
Dans zsh
, vous pouvez également utiliser Alt+Enter ou Esc+Enter au lieu de Ctrl+VCtrl+J
Essaye ça..
cp /templates/Apple /templates/used && cp /templates/Apple /templates/inuse && rm /templates/Apple
L'utilisation de tuyaux me semble bizarre. Quoi qu'il en soit, vous devez utiliser l'opérateur logique and
Bash:
$ cp /templates/Apple /templates/used && cp /templates/Apple /templates/inuse && rm /templates/apples
Si les commandes cp
échouent, la rm
ne sera pas exécutée.
Vous pouvez également créer une ligne de commande plus élaborée à l’aide d’une boucle for
et de cmp
.