亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何覆蓋 Go 中的符號鏈接?

如何覆蓋 Go 中的符號鏈接?

Go
慕萊塢森 2022-01-10 17:32:24
我想用 Go 覆蓋一個符號鏈接,但我找不到怎么做。如果我嘗試創建符號鏈接并且它已經存在,則會返回錯誤。我的代碼:err := os.Symlink(filePath, symlinkPath)if err != nil {    fmt.Println(err)}我猜必須刪除符號鏈接,然后重新創建。是對的嗎?如果是這樣,我該如何取消鏈接符號鏈接?
查看完整描述

3 回答

?
寶慕林4294392

TA貢獻2021條經驗 獲得超8個贊

只需檢查符號鏈接是否存在并在創建新鏈接之前將其刪除


if _, err := os.Lstat(symlinkPath); err == nil {

  os.Remove(symlinkPath)

}


查看完整回答
反對 回復 2022-01-10
?
BIG陽

TA貢獻1859條經驗 獲得超6個贊

這里的其他答案是正確的......但有兩個小問題:

  • 有一個微小的數據競爭,新的符號鏈接將在此處之前但在刪除之后的其他地方創建,使其處于潛在的不一致狀態。

  • 如果程序在創建符號鏈接之前死亡/崩潰,但在刪除前一個符號鏈接之后,它可能會再次使事情處于不一致的狀態。

處理這個問題的更原子的方法是創建一個臨時符號鏈接,然后將其重命名為原始符號鏈接:

symlinkPathTmp := symlinkPath + ".tmp"

if err := os.Remove(symlinkPathTmp); err != nil && !os.IsNotExist(err) {

  return err

}


if err := os.Symlink(filePath, symlinkPathTmp); err != nil {

  return err

}


if err := os.Rename(symlinkPathTmp, symlinkPath); err != nil {

  return err

}

在刪除臨時鏈接和重新創建它之間仍然存在小競爭,但它不會冒使主要鏈接處于不一致狀態的風險。理想情況下,我們可以通過為臨時鏈接使用隨機名稱來解決這個問題,但是 Go 的 TempFile 總是會創建一個新文件,因此它不是很有用。(您可以調用 TempFile,然后刪除文件名并重新使用該名稱,這會比僅附加一個常量.tmp后綴更危險但更安全。)


然而,即使有那場比賽,你仍然可以獲得原子性,任何中斷都不會導致丟失鏈接。


請注意,這取決于 Posix 行為,并且可能無法在 Windows 上運行(為什么還要在 Windows 上使用符號鏈接?),但它是許多需要原子符號鏈接替換的 macOS/Linux 工具共享的技術。


查看完整回答
反對 回復 2022-01-10
?
MYYA

TA貢獻1868條經驗 獲得超4個贊

請注意,@Vadyus 的答案在運行 lstat 時隱藏了實際的文件系統錯誤。例如,如果您的磁盤損壞并且 Lstat 失敗,您仍然會運行 os.Remove 并忽略它的錯誤(危險,除非您喜歡調試幾個小時)。


以下片段正確檢查文件是否存在和其他錯誤:


if _, err := os.Lstat(symlinkPath); err == nil {

  if err := os.Remove(symlinkPath); err != nil {

      return fmt.Errorf("failed to unlink: %+v", err)

  }

} else if os.IsNotExist(err) {

    return fmt.Errorf("failed to check symlink: %+v", err)

}


查看完整回答
反對 回復 2022-01-10
  • 3 回答
  • 0 關注
  • 179 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號