移動當前目錄時,我得到“mv:無法移動‘。’到“../dir/.”:設備或資源繁忙”

移動當前目錄時,我得到“mv:無法移動‘。’到“../dir/.”:設備或資源繁忙”
$ mv . ../general/
mv: cannot move `.' to `../general/.': Device or resource busy

這是否意味著當前目錄是繁忙的設備或資源,並且無法移除?為什麼?

答案1

您無法移動目前所在的目錄。

相反,請上一級並命名先前的當前目錄以將其移至目標。

答案2

移動一個點是不可能的.。該點與目前目錄名稱不同。您可以將其視為.指向目錄的指針,但不是目錄本身,因此,

$ pwd && echo $PWD && realpath .
/home/jimmij/tmp
/home/jimmij/tmp
/home/jimmij/tmp
$ mkdir tmp1 tmp2
$ mv tmp1/. tmp2/
mv: cannot move ‘tmp1/.’ to ‘tmp2/.’: Device or resource busy

不起作用,但是

cd tmp1
mv ../tmp1 ../tmp2

工作正常,所以實際上你移動當前目錄,儘管此操作後某些命令可能會混淆:

$ pwd && echo $PWD && realpath .
/home/jimmij/tmp/tmp1
/home/jimmij/tmp/tmp1
/home/jimmij/tmp/tmp2/tmp1
$ cd .
$ pwd && echo $PWD && realpath .
/home/jimmij/tmp/tmp2/tmp1
/home/jimmij/tmp/tmp2/tmp1
/home/jimmij/tmp/tmp2/tmp1

類似的故事..,即父親目錄。

換句話說,每個目錄必須至少包含兩個元素:...。您無法移動或刪除它們。

答案3

您收到該訊息的原因:

mv:無法移動.' to../general/。

是由於怎樣的.,以及..工作以外的mv。當您在 Unix 中移動某些內容時,該mv命令會嘗試取消連結所有引用您嘗試移動的項目的 inode 的連結。在這種情況下,這將是所引用的目錄的.索引節點。

「符號/連結」...連結到索引節點,並且在某種意義上是特殊的。您可以在 U&L 問答中了解他們的歷史,標題為:為什麼新目錄在添加任何內容之前其硬連結計數為 2?如果您曾經查看過新建立的目錄,您會注意到它總是以連結計數 2開頭...

$ mkdir adir

$ ls -l | grep adir
drwxrwxr-x. 2 saml saml 4096 Oct  5 08:02 adir

$ ls -la adir/
total 8
drwxrwxr-x. 2 saml saml 4096 Oct  5 08:02 .
drwxrwxr-x. 3 saml saml 4096 Oct  5 08:02 ..

筆記:ls如果您不清楚,請參閱此 U&L 問答中的輸出參考,標題為:ls -al 輸出中的欄位是什麼意思?

因此它們不是實際目錄的名稱,而是連結到它們的“符號/連結”。因此,在能夠之前必須先斷開它們的連結mv

好吧,由於您的命令正在使用.,因此該命令無法取消鏈接mv,因此訊息:“設備或資源繁忙”。

參考

答案4

Linux 禁止重新命名以元件.或結尾的任何路徑..,回傳錯誤 EBUSY;以下也會失敗:

$ mkdir a a/aa
$ mv a/aa/.. b
mv: cannot move ‘a/aa/..’ to ‘b/..’: Device or resource busy

其代碼位於namei.c::renameat.當傳遞給各種函數時,路徑名的最後一個組成部分必須是 類型LAST_NORM,而不是LAST_DOTLAST_DOTDOT

FreeBSD 在每種情況下都會傳回錯誤 EINVAL。


我們只能猜測為什麼會有這個限制。

如果出現以下情況,則 rename() 函數將失敗:
...
[EBUSY] 由舊或新命名的目錄目前正在由系統或其他程序使用,並且實作認為這是錯誤。

人們可以考慮.當前正在被該進程使用。但請注意,Linux 允許以下操作,因此目錄僅被某個進程使用並不足以導致rename失敗:

$ mkdir /tmp/t
$ cd /tmp/t
$ mv /tmp/t /tmp/t1
$ /bin/pwd
/tmp/t1

.禁止重命名和 的原因..可能是「減少使用者的困惑」。

  • .通常是指向其父目錄中目錄條目的硬鏈接,並且有些特殊,因為進程始終可以打開.以訪問其當前工作目錄。能夠重命名它會適得其反。
  • ..通常是到目錄父目錄的硬鏈接,並且有些特殊,因為打開的進程..將獲取父目錄(或目錄本身,如果它是安裝點)。能夠重命名它會適得其反。

Linux 也禁止最後一個元件為(ENOTEMPTY) 或(EINVAL)rmdir的路徑。 FreeBSD 對其中每一個都傳回錯誤 EINVAL。這...rmdir 的 POSIX 標準有這個:

如果出現以下情況,rmdir() 函數將會失敗:
...
[EINVAL] 路徑參數包含最後一個組成部分,即點。

相關內容