2011-02-27 20 views
238

dire che ho un file di /templates/apple e voglioEsecuzione di comandi multipli in una riga in guscio

  1. metterlo in due luoghi diversi e quindi
  2. rimuovere l'originale.

Quindi, /templates/apple verrà copiato /templates/used E /templates/inuse e poi, dopo che mi piacerebbe rimuovere l'originale.

È cp il modo migliore per farlo, seguito da rm? O c'è un modo migliore?

voglio fare tutto in una sola riga così sto pensando che sarebbe simile:

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

E 'questa la sintassi corretta?

risposta

483

Si utilizza | (pipe) per dirigere l'output di un comando in un altro comando. Quello che state cercando è && all'operatore di eseguire il comando successivo solo se il precedente è riuscita:

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

O

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

In sintesi (non esaustivo) di bash operatori di comando/separatori :

  • | tubi (condotte) lo standard output (stdout) di un comando nell'input standard di un altro. Si noti che stderr va ancora nella sua destinazione predefinita, qualunque cosa accada.
  • |& pipe sia stdout e stderr di un comando nello standard input di un altro. Molto utile, disponibile in bash versione 4 e successive.
  • && esegue il comando di destra di && solo se il precedente è riuscito.
  • || esegue il comando di destra di || ma solo il precedente non è riuscito.
  • ; esegue il comando di destra di ; indipendentemente dal fatto che il comando precedente abbia avuto esito positivo o negativo. A meno che non sia stato precedentemente invocato lo set -e, che causa l'errore bash in caso di errore.
56

Perché non cp nella posizione 1, quindi mv nella posizione 2. Questo si occupa di "rimuovere" l'originale.

E no, non è la sintassi corretta. | viene utilizzato per "pipe" l'output di un programma e trasformarlo in input per il programma successivo. Quello che vuoi è ;, che separa più comandi.

cp file1 file2 ; cp file1 file3 ; rm file1 

Se si richiede che i singoli comandi devono avere successo prima che il prossimo può essere avviato, allora devi usare && invece:

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

In questo modo, se uno dei comandi cp fallisce, il rm non verrà eseguito.

2

Prova questa ..

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

1

L'utilizzo dei tubi mi sembra strano. Ad ogni modo dovresti usare l'operatore logico e bash.

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

Se i comandi cp falliscono, rm non verrà eseguito.

Oppure, è possibile creare una riga di comando più elaborata utilizzando un ciclo for e un cmp.

Renaud

7

noti che cp A B; rm A è esattamente mv A B. Sarà anche più veloce, poiché non è necessario copiare effettivamente i byte (supponendo che la destinazione si trovi sullo stesso file system), rinominare semplicemente il file. Così si vuole cp A B; mv A C

2

Un'altra opzione sta scrivendo Ctrl + VCtrl + J alla fine di ogni comando.

Esempio (sostituire # con Ctrl + VCtrl + J):

$ echo 1# 
echo 2# 
echo 3 

uscita:

1 
2 
3 

Questo eseguirà i comandi indipendentemente precedenti fallito.

Uguale: echo 1; echo 2; echo 3

Se si desidera interrompere l'esecuzione sui comandi falliti, aggiungere && alla fine di ogni riga, tranne l'ultimo.

Esempio (sostituire # con Ctrl + VCtrl + J):

$ echo 1 &&# 
failed-command &&# 
echo 2 

uscita:

1 
failed-command: command not found 

In zsh è anche possibile utilizzare Alt + Invio o Esc + Invio invece di Ctrl + VCtrl + J

Problemi correlati