2009-08-06 15 views
19

Qual è il modo più semplice in Linux di "copiare" una gerarchia di directory in modo che venga creata una nuova gerarchia di directory mentre tutti i "file" sono solo collegamenti simbolici ai file effettivi nella gerarchia di origine?symlink-copia di una gerarchia di directory

cp -s non funziona in modo ricorsivo.

+0

Vedere anche http://unix.stackexchange.com/q/196537/10047. – user905686

risposta

1

Ho cercato un po 'su google e ho trovato un comando chiamato lns, disponibile da here.

+0

Questo strumento funziona alla grande per me. Grazie per segnalarlo! –

+0

Perché raccomandi uno strumento di terze parti se cp con alcune (2) opzioni fa il trucco. Sembra un rischio per la sicurezza per me. – Nikodemus

+0

Perché non conoscevo l'opzione -s otto anni fa quando scrissi la risposta. Sentiti libero di votare/downvotare se pensi che la risposta sia buona/cattiva. – JesperE

11

Partendo da sopra le originali & nuove directory, credo che questo paio di find(1) comandi farà quello che vi serve:

find original -type d -exec mkdir new/{} \; 
find original -type f -exec ln -s {} new/{} \; 

La prima istanza imposta la struttura di directory trovando solo le directory nella struttura originale e ricreandoli nel nuovo albero. Il secondo crea i collegamenti simbolici ai file originali nel nuovo albero.

+0

Questo funziona molto bene per me (come scritto sopra, cp -as o -Rs non funzionerà su Mac OS X). Potrebbe essere una buona idea '(cd origParentDir; trovare origDir ..; find origDir ..)' per ottenere il percorso relativo come parametro sia per mkdir che per ln -s. Usa le parestes per avviare un '(' sottoshell') 'perché l'esecuzione di cd in una subshell sarà solo temporanea imposta CWD; CWD viene ripristinato quando viene interrotta la subshell. Per esempio. se stai 'clonando'/src/binutils-2.24' a '$ {HOME}/sorgente', allora non vuoi che la cartella 'src' sia creata. –

+0

Strano che 'ln' non abbia un'opzione ricorsiva ... come' ln -s -R orig/dir dest/dir'. – jiggunjer

26

Ho appena eseguito un test rapido su una casella Linux e cp -sR /orig /dest fa esattamente ciò che hai descritto: crea una gerarchia di directory con collegamenti simbolici per non-directory di nuovo all'originale.

+0

Funziona solo sul primo livello di directory. Per ogni file in sottodirectory ricevo "xyz-file: può fare collegamenti simbolici relativi solo nella directory corrente". (su Ubuntu 8.10, cp versione 6.10) –

+24

Il motivo per cui si ottiene "file xyz: può creare collegamenti simbolici relativi solo nella directory corrente" è perché per la directory di origine è stato specificato un percorso relativo. Funzionerà come vuoi se specifichi un percorso assoluto per l'origine, in questo modo: "cp -sR/root/absolute/percorso/nome dest". – PonyEars

+3

Nel caso in cui sia necessario/si desidera rendere tutti i relativi collegamenti simbolici è possibile utilizzare [symlink] (http://www.linuxcommand.org/man_pages/symlinks8.html) in questo modo: 'cp -sR/orig/dest && symlinks - rc/dest' –

0

So che la domanda riguardava la shell, ma dato che è possibile chiamare perl dalla shell, ho scritto uno strumento per fare qualcosa di molto simile a questo, e posted it su perlmonks alcuni anni fa. Nel mio caso, in genere volevo che le directory rimangano link finché non decido diversamente. Sarebbe un cambiamento abbastanza banale farlo automaticamente e in modo ricorsivo.

7

C'è anche l'utilità "lndir" (da X) che fa una cosa del genere; L'ho trovato menzionato qui: Debian Bug report #301030: can we move lndir to coreutils or debianutils?, e ora lo uso felicemente.

+2

Ho avuto il problema esatto dell'interrogante originale e, dopo aver iniziato a codificare uno script di shell, ho trovato questa risposta e ho scoperto che Linds era già installato. Funziona esattamente come ne ho bisogno. – shmuelp

13
cp -as /root/absolute/path/name dest_dir 

farà quello che vuoi. Si noti che il nome sorgente deve essere un percorso assoluto, non può essere relativo. Altrimenti, riceverai questo errore: "xyz-file: può fare collegamenti simbolici relativi solo nella directory corrente."

Inoltre, fare attenzione su ciò che si sta copiando: se DEST_DIR esiste già, si dovrà fare qualcosa di simile:

cp -as /root/absolute/path/name/* dest_dir/ 
cp -as /root/absolute/path/name/.* dest_dir/ 
1

Se avete voglia di sporcarsi le mani Ecco un trucco ciò creerà automaticamente la cartella di destinazione, le sottocartelle e collegherà in modo simbolico tutti i file in modo ricorsivo.

Nella cartella in cui i file che si vogliono link simbolico e sottocartelle sono:

  1. creare un guscio di file.sh:

    nano shell.sh

  2. copia e incolla questo incantatore:

#!/bin/bash

export DESTINATION=/your/destination/folder/ 
export TARGET=/your/target/folder/ 

find . -type d -print0 | xargs -0 bash -c 'for DIR in "[email protected]"; 
do 
    echo "${DESTINATION}${DIR}" 
    mkdir -p "${DESTINATION}${DIR}"   
    done' - 


find . -type f -print0 | xargs -0 bash -c 'for file in "[email protected]"; 
do 
    ln -s "${TARGET}${file}" "${DESTINATION}${file}" 
    done' - 
  1. salvare il file ctrl+O
  2. chiudere il file ctrl+X
  3. Fai il tuo script eseguibile chmod 777 shell.sh

  4. eseguire lo script ./shell.sh

Felice l'hacking!

Problemi correlati