cp --no-target-directory spiegato


10

Domanda: ho bisogno di un semplice esempio di come usare cp --no-target-directory.

Ho delle difficoltà a capire cp --no-target-directory. Capisco la spiegazionemv --no-target-directory , ma non riesco davvero a immaginare un modo per usarla cp.

Ad esempio, quando il comando ha mv /tmp/source /tmp/destesito positivo, non vi è alcuna garanzia che sia /tmp/sourcestato rinominato /tmp/dest: avrebbe potuto essere rinominato /tmp/dest/sourceinvece, se qualche altro processo creato /tmp/destcome directory. Tuttavia, se mv -T /tmp/source /tmp/destriesce, non c'è dubbio che /tmp/source was renamed to/ tmp / dest`. ( fonte )

Risposte:


15

Per impostazione predefinita, cpverifica se il suo ultimo argomento è una directory esistente. In tal caso, cpcrea un collegamento all'interno di quella directory, con il nome di base della fonte. Cioè, dato il comando

cp foo/bar wibble

se wibbleè una directory esistente, cpcopia l'origine in wibble/bar. Se wibblenon esiste, cpcollega la fonte a wibble.

Se vuoi essere sicuro che la copia sia sempre wibble, puoi specificare l' opzione --no-target-directory(alias -T). In questo modo, se ha cpesito positivo, puoi essere certo che la copia viene chiamata wibble. Se wibbleesiste già come directory, allora cpfallirà.

In forma tabellare:

The target is …             Without -T               With -T
existing directory          copy in the directory    error
existing file (not dir)     overwrite                overwrite
does not exist              create                   create

L'unica differenza è che con -T, nel caso in cui la destinazione sia una directory esistente, il comando restituisce un errore. Ciò è utile quando ci si aspetta che la directory non esista: viene visualizzato un messaggio di errore invece che accada qualcosa di non previsto.

Lo stesso vale per mve ln. Se la destinazione è una directory esistente, con -T, segnalano un errore anziché fare in silenzio qualcosa di diverso.

Con cp, c'è un caso diverso. Se si esegue una copia ricorsiva e l'origine è una directory, quindi cp -Tcopia il contenuto dell'origine nella destinazione, anziché copiare l'origine stessa. Cioè, dato

$ tree source destination 
source
└── foo
destination
└── bar

poi

$ cp -rv source destination
`source' -> `destination/source'
`source/foo' -> `destination/source/foo'

mentre

% cp -rvT source destination
`source/foo' -> `destination/foo'

8

Si potrebbe usare --no-target-directoryse non si vuole una directory di origine copiato sotto una directory di destinazione esistente, si desidera che la directory di origine copiato sulla directory di destinazione.

Ecco un esempio di una copia della directory con e senza --no-target-directory:

$ mkdir a
$ touch a/b a/c
$ find
.
./a
./a/c
./a/b
$ cp -r a b       # b does not exist; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r a b       # b already exists; a is copied *underneath* it
$ find
.
./b
./b/a
./b/a/b
./b/a/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r --no-target-directory a b     # b already exists; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b

Puoi ottenere qualcosa dello stesso effetto aggiungendo un suffisso al nome o ai nomi della directory di origine con slash-dot /.come in: cp -r a/. bche copia la directory di origine a su b e non al di sotto b .

Nessuno dei due metodi sopra descritti equivale a dire "copia solo il contenuto della directory di origine nella destinazione esistente" poiché, se chiedi di conservare il tempo e le autorizzazioni, la directory di destinazione esistente acquisirà il tempo e le autorizzazioni della directory di origine. Un esempio (modificato per rimuovere informazioni non necessarie):

$ find . -ls
drwx------   Oct 13 13:31 ./b         # note date and permissions
drwxr-xr-x   Jan  1  2013 ./a         # note date and permissions
-rw-r--r--   Oct 13 13:23 ./a/c
-rw-r--r--   Oct 13 13:23 ./a/b
$ cp -rp --no-target-directory a b    # preserve mode and timestamps
$ find . -ls
drwxr-xr-x   Jan  1  2013 ./b         # note copied date and permissions
-rw-r--r--   Oct 13 13:23 ./b/b
-rw-r--r--   Oct 13 13:23 ./b/c
drwxr-xr-x   Jan  1  2013 ./a
-rw-r--r--   Oct 13 13:23 ./a/c
-rw-r--r--   Oct 13 13:23 ./a/b

Una copia di solo contenuto non trasferisce la modalità o i timestamp della directory di origine nella directory di destinazione.


2

Che ne dici di quanto segue?

$ cp -rvT Dir_1 Dir_2
‘Dir_1/File_3.txt’ -> ‘Dir_2/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/File_2.txt’
$ cp -rv Dir_1 Dir_2
‘Dir_1’ -> ‘Dir_2/Dir_1’
‘Dir_1/File_3.txt’ -> ‘Dir_2/Dir_1/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/Dir_1/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/Dir_1/File_2.txt’

Come tale, è solo un modo diverso di scrivere cp Dir_1/* Dir_2/. Tuttavia, rileva i file nascosti nella directory principale di Dir_1 che verrebbero persi da un semplice cp *.

$ touch Dir_1/.Hidden_File_{1,2,3}.txt
$ cp -rv Dir_1/* Dir_2
cp: No match.
$ cp -rvT Dir_1 Dir_2
‘Dir_1/.Hidden_File_2.txt’ -> ‘Dir_2/.Hidden_File_2.txt’
‘Dir_1/.Hidden_File_3.txt’ -> ‘Dir_2/.Hidden_File_3.txt’
‘Dir_1/.Hidden_File_1.txt’ -> ‘Dir_2/.Hidden_File_1.txt’

funziona per me con l' --no-target-directoryopzione [out] : finché uso --recursive, tutto va bene [con coreutils 8.12sotto GNU / Linux]. La differenza principale sembra essere quella con --no-target-directoryil contenuto ma non la directory stessa viene copiata [ricerca ancora in corso]
erch
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.