Qual è il valore aggiunto dell'opzione -T in GNU cp e mv?


26

Perché alcuni comandi GNU Coreutils hanno l' -T/--no-target-directoryopzione? Sembra che tutto ciò che fa possa essere raggiunto usando la semantica del .(self dot) in una gerarchia di directory Unix tradizionale.

Considerando:

cp -rT /this/source dir

L' -Topzione impedisce alla copia di creare una dir/sourcesottodirectory. Piuttosto /this/sourceviene identificato con dire il contenuto viene mappato di conseguenza tra gli alberi. Quindi, ad esempio, /this/source/foo.cva avanti dir/foo.ce così via, anziché a dir/source/foo.c.

Ma questo può essere facilmente realizzato senza l' -Topzione usando:

cp -r /this/source/. dir  # Probably worked fine since dawn of Unix?

Semanticamente, il componente del punto finale viene copiato come figlio di dir, ma ovviamente quel "figlio" esiste già (quindi non deve essere creato) ed è effettivamente dirse stesso, quindi l'effetto /this/pathè identificato con dir.

Funziona bene se la directory corrente è la destinazione:

cp -r /this/tree/node/. . # node's children go to current dir

C'è qualcosa che puoi fare solo con -Tquello che può razionalizzare la sua esistenza? (Oltre al supporto per i sistemi operativi che non implementano la directory dot, una logica non menzionata nella documentazione.)

Il trucchetto di cui sopra non risolve le stesse condizioni di gara menzionate nella documentazione di GNU Info -T?

Risposte:


29

Il .trucco può essere utilizzato solo quando si copia una directory, non un file. L' -Topzione funziona con directory e file. Se fate:

cp srcfile destfile

e c'è già una directory di nome destfileche verrà copiata destfile/srcfile, che potrebbe non essere prevista. Quindi tu usi

cp -T srcfile destfile

e ricevi correttamente l'errore:

cp: cannot overwrite directory `destfile' with non-directory

Se hai provato a utilizzare il .metodo, la copia non funzionerebbe mai:

cp: cannot stat `srcfile/.`: Not a directory

Il .trucco fa lavoro quando la copia di un file, non solo quando si rinomina il suo nome base allo stesso tempo! cp /path/to/file /target/dir/. Se /target/dir/fileesiste ed è una directory, ottieni la stessa diagnostica! Ma hai mostrato cosa -Tnon può essere fatto senza di esso in un solo passaggio, senza condizioni di competizione: copia un file e modifica il suo nome senza essere deviato in una sottodirectory.
Kaz,

3
Non è lo stesso: il .trucco di cui stai parlando è l'aggiunta /.alla fonte .
Barmar,

21

Il problema con cp/ mv/ lncome sono stati originariamente progettati è che sono due comandi in uno ( copia e copia in ).

cp A B

è la copia da A a B o la copia da A a B ( copia da A a B / A ) a seconda che Besista e sia una directory o meno (e più varianti se B è un link simbolico a una directory).

È negativo perché è ambiguo. Quindi le implementazioni GNU hanno aggiunto opzioni per aggirare questo.

cp -T A B

copia da A a B indipendentemente. Se Besiste ed è una directory, ciò fallirà (a meno che non passi -r). In ogni caso, non si finirà con un Afile all'interno Bquando si intendeva Aessere copiato in B.

E:

cp -t B A

è la copia in .


La filosofia originale di Unix è quella di supporre che tu sappia cosa fai e che ti permetterà felicemente di spararti al piede.
Lenne,

4
@Lenne, ma qui non ti dà modo di evitare di spararti al piede. Se qualcuno crea una directory B o un collegamento simbolico a una directory appena prima di eseguire cp A Bil comando non farà ciò che intendevi. E fare [ -e B ] || [ -L B ] || cp A Bha ancora una condizione di gara che cp -Tn A Bnon ha.
Stéphane Chazelas,

6

Il -Tgrado di fornire un fallimento se una directory esiste in modo non corretto per quello che dovrebbe essere un file di destinazione:

$ mkdir mustbeafile
$ touch afile
$ cp -T afile mustbeafile
cp: cannot overwrite directory `mustbeafile' with non-directory
$ echo $?
1
$ cp afile mustbeafile
$ 

Cioè, invece del successo su inaspettato-copia-a-un-sottodiretto, si verifica un avviso e uno stato di uscita non buono, che potrebbe quindi causare l'interruzione di uno script e ispezione umana perché esiste una directory in cui non dovrebbe esserci Sii uno.


0

L'uso di un flag è anche molto più chiaro e presenta un rischio minore di effetti indesiderati, quando il comando viene utilizzato in uno script anziché immesso manualmente. L'applicazione di punti su percorsi in una sceneggiatura potrebbe finire in tutti i tipi di inaspettati dispetti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.