2009-11-13 77 views
48

所以我創建了一個符號鏈接:有沒有辦法編輯一個符號鏈接而不先刪除它?

ln -s /location/to/link linkname 

現在我想改變位置的符號鏈接的鏈接。我怎麼做?有沒有辦法做到這一點,而不是先刪除它?

+1

我想你會在這裏得到更好的迴應:http://serverfault.com/ – 2009-11-13 05:31:58

回答

26

您可以使用不同的名稱創建新鏈接,然後將其移動以替換舊鏈接。

ln -s /location/to/link linkname 

後來

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

如果newlinklinkname是同一個物理設備的mv應該是原子上。

+1

@Andrew - http://en.wikipedia.org/wiki/Atomic_operation – 2009-11-15 08:42:40

+0

僅供參考,我確定這可以在某些操作系統上運行,但這對我並不起作用,移動操作只是刪除了「新」鏈接,而不是取代舊的。我仍然必須先聽。 – pstanton 2013-07-07 23:21:36

+0

@pstanton你的意思是'mv newlink linkname'導致'newlink'文件被刪除,但沒有覆蓋'linkname'文件?它是否默默地這樣做?這似乎非常神祕。 – 2013-11-15 21:26:49

5

否如果新路徑已存在,則symlink系統調用將返回EEXIST。您只能從文件系統中的新節點進行鏈接。這裏有什麼要求?如果您擔心由於unlink/symlink調用的非原子性而導致競爭,那麼您可能需要重新考慮該體系結構以便在別處提供同步。這種事情引發了一些可怕的安全漏洞。

19

嘗試ln -sf new_destination linkname

+1

這是非原子的,但。詳情請參閱我的回答。我不清楚這是否是海報的擔憂。 – 2009-11-13 05:34:57

+10

這也不適用於指向目錄的符號鏈接。它只會在舊的目標目錄中創建一個新的符號鏈接。 – samxli 2011-07-28 09:26:08

+10

使用-n(--no-dereference)開關來解決這個問題。 – 2014-12-04 10:19:50

3

正如其他人所說的,您必須首先刪除符號鏈接,無論是手動還是將-f標誌傳遞給ln實用程序。

幾年前,我不得不很頻繁地對符號鏈接進行小的編輯,所以我編寫了一個簡單的基於readline的實用程序(edln),以減少煩人。如果其他人發現它很有用,我已經把它放在網上https://github.com/jjlin/edln/

edln將顯示原始符號鏈接目標;然後可以使用箭頭鍵或標準readline擊鍵(M-bM-f,C-d等)四處移動並編輯目標。

4

鏈這樣的命令:

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

第一個命令刪除現有的一個和所述第二立即再次創建它。

13

如果符號鏈接目標是目錄,則需要將-T標誌添加到mv命令中,否則它會將新符號鏈接移動到舊符號鏈接的目標目錄中。

的原子交換一個網站,一個新的版本示例:

原始設置 - 網站存儲在www1目錄,虛擬主機指着www符號鏈接:

ln -s www1 www 

瀏覽網站,看到舊版本。

將新的網站文件放在新的www2目錄中。

建立新的符號鏈接到新網站:

ln -s www_new www2 

移動www符號鏈接到新網站的目錄:

mv -T www_new www 

瀏覽網站,馬上看到新版本。

+0

顯然,我NAS的微內核上的mv版本不支持-T參數。任何替代建議做這個原子? – OcularProgrammer 2014-03-27 23:16:00

+0

嘗試使用-f(強制)標誌創建符號鏈接。這似乎工作。請參閱下面的答案: 'ln -sf new_destination linkname' – 2014-03-27 23:46:10

6

在OSX,ln命令的手冊頁說,你可以做這樣的

ln -shf /location/to/link link name 

從手冊頁:

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

對於目錄,你想要做: ln -sfT/location/to/new/target old_linkname

+0

這是一個好得多的解決方案,而不必調用第二個命令 – dsymquen 2014-07-07 14:16:51

0

只是google搜索,發現沒有很好的答案,必須解決自己:

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

編輯的定義是指而不是從頭開始重建,但部分地改變。任何需要記住路徑的答案,可能很長或帶有奇怪的符號,肯定是不好的。

6

只要改變鏈接目標:

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

這是一個瞬間,原子變化。

相關問題