2009-11-13 8 views

risposta

26

È possibile creare il nuovo collegamento con un nome diverso, quindi spostarlo per sostituire il vecchio collegamento.

ln -s /location/to/link linkname 

seguito

ln -s /location/to/link2 newlink 
mv newlink linkname 

Se newlink e linkname sono sullo stesso dispositivo fisico mv dovrebbe essere atomica.

+1

@Andrew - http://en.wikipedia.org/wiki/Atomic_operation –

+0

FYI, sono sicuro che questo funziona su alcuni sistemi operativi ma questo non ha funzionato per me, l'operazione di spostamento ha appena rimosso il collegamento 'nuovo' invece di sostituendo il vecchio. dovevo ancora prima di tutto. – pstanton

+0

@pstanton Significa che 'mv newlink linkname' ha causato l'eliminazione del file' newlink', ma non sovrascrive il file 'linkname'? Lo ha fatto in silenzio? Sembra estremamente misterioso. –

5

No. La chiamata di sistema symlink restituirà EEXIST se newpath esiste già. È possibile collegare solo da un nuovo nodo nel filesystem. Qual è il requisito qui? Se sei preoccupato per una gara a causa della non atomicità delle chiamate unlink/symlink, potresti voler ripensare un po 'l'architettura per fornire la sincronizzazione altrove. Ci sono stati alcuni errori di sicurezza spaventosi introdotti da questo genere di cose.

19

Prova ln -sf new_destination linkname.

+1

Questo non è atomico, però. Vedi la mia risposta per i dettagli. Non sono chiaro se questa sia la preoccupazione del poster o no. –

+10

Anche questo non funzionerà con collegamenti simbolici che puntano a directory. Creerà solo un nuovo link simbolico all'interno della vecchia directory di destinazione. – samxli

+10

Utilizzare l'opzione -n ​​(--no-dereference) per risolvere questo problema. –

3

Come altri hanno già accennato, è necessario eliminare innanzitutto il collegamento simbolico, manualmente o passando il flag -f nell'utilità ln.

Anni fa, ho dovuto apportare piccole modifiche ai collegamenti simbolici piuttosto frequentemente, così ho scritto una semplice utility basata su readline (edln) per rendere meno fastidioso questo. Nel caso in cui qualcun altro lo trovi utile, l'ho messo online allo https://github.com/jjlin/edln/.

edln visualizza la destinazione del collegamento simbolico originale; puoi quindi utilizzare i tasti freccia, i tasti di sequenza standard (M-b, M-f, C-d, ecc.) per spostarti e modificare il target.

4

catena i comandi come questo:

rm currentlink && ln -s /path/to/link currentlink 

Il primo comando elimina quella esistente e il 2 ° subito crea di nuovo.

13

Se le destinazioni dei collegamenti simbolici sono directory, è necessario aggiungere il flag -T al comando mv, altrimenti sposta il nuovo collegamento simbolico nella directory di destinazione del vecchio collegamento simbolico.

Esempio di atomicamente passare un sito web per una nuova versione:

originale di installazione - sito web è memorizzato in www1 directory, vhost indicando www link simbolico:

ln -s www1 www 

Sfoglia per sito web, vedere vecchia versione.

Inserire i nuovi file del sito Web nella nuova directory www2.

Impostare nuovo collegamento simbolico al nuovo sito web:

ln -s www_new www2 

Sposta www collegamento simbolico alla directory del nuovo sito web:

mv -T www_new www 

Sfoglia per sito web, consultare subito nuova versione.

+0

Quindi apparentemente la versione di mv sul mio microkernel NAS non supporta l'argomento -T. Qualche suggerimento alternativo per farlo atomicamente? – OcularProgrammer

+0

Prova a creare il link simbolico con il flag -f (forza). Sembra funzionare. Vedere la risposta qui sotto: 'ln -sf new_destination linkname' –

6

su OSX, la pagina man per ln dice che si può fare in questo modo

ln -shf /location/to/link link name 

Dalla pagina man:

The options are as follows: 
-F If the target file already exists and is a directory, then remove it so that the link may occur. The -F 
     option should be used with either -f or -i options. If none is specified, -f is implied. The -F option is 
     a no-op unless -s option is specified. 

-h If the target_file or target_dir is a symbolic link, do not follow it. This is most useful with the -f 
     option, to replace a symlink which may point to a directory. 

-f If the target file already exists, then unlink it so that the link may occur. (The -f option overrides any 
     previous -i options.) 

-i Cause ln to write a prompt to standard error if the target file exists. If the response from the standard 
     input begins with the character `y' or `Y', then unlink the target file so that the link may occur. Other- 
     wise, do not attempt the link. (The -i option overrides any previous -f options.) 

-n Same as -h, for compatibility with other ln implementations. 

-s Create a symbolic link. 

-v Cause ln to be verbose, showing files as they are processed. 
7

Per le directory, si vuole da fare: ln -sfT/location/a/new/target old_linkname

+0

questa è una soluzione molto migliore di dover chiamare un secondo comando – dsymquen

0

Proprio su google, non ha trovato buona risposta e dovuto risolvere me stesso:

ln -f -s -T `readlink SomeLibrary | sed 's/version.old/version.new/'` SomeLibrary 

Montaggio di definizione non significa ricreare da zero, ma cambiando in parte. Qualsiasi risposta che richieda di memorizzare un percorso, magari lungo o con simboli strani, è decisamente negativa.

6

Basta cambiare il bersaglio link simbolico:

# ln -sfT /path/to/new/target linkname

Questo è un istante, cambiamento atomica.

Problemi correlati