Linux

為什麼find -type d -exec rmdir {} ;命令會產生“沒有這樣的文件或目錄消息”

  • August 20, 2019

出於測試目的,我創建了以下目錄。

user@linux:~$ mkdir dir0{1..3}

user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei  31 10:45 dir01
drwxr-xr-x 2 user user 4.0K Mei  31 10:45 dir02
drwxr-xr-x 2 user user 4.0K Mei  31 10:45 dir03
user@linux:~$ 

然後,我用find -exec

user@linux:~$ find -type d -exec rmdir {} \;
rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory
find: ‘./dir01’: No such file or directory
find: ‘./dir03’: No such file or directory
user@linux:~$ 

目錄已刪除,我驗證了它。

user@linux:~$ ls -l
total 0
user@linux:~$ 

我的問題是:

1)我不明白為什麼這些消息在那裡。知道為什麼嗎?

rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory

我沒有看到這種錯誤rmdir

user@linux:~$ mkdir dir0{1..3}
user@linux:~$ 

user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei  31 22:58 dir01
drwxr-xr-x 2 user user 4.0K Mei  31 22:58 dir02
drwxr-xr-x 2 user user 4.0K Mei  31 22:58 dir03
user@linux:~$ 

user@linux:~$ rmdir *
user@linux:~$ 

user@linux:~$ ls -l
total 0
user@linux:~$ 

2)是否可以刪除這些消息?

大概會發生的是,使用該-exec ... \;構造, find 一步一步地完成它的工作:

  • 遍歷目錄樹,找到匹配的條目-type d,以及
  • 找到此類條目後立即執行rmdir

這意味著,在您的範例中, find 將查看dir01,並將其作為稍後輸入的目錄,然後rmdir在其上執行,然後,當嘗試遞歸到 時dir01,失敗,因為它不再存在。

在這種情況下執行 with-exec rmdir {} +應該會有所幫助:rmdir dir01 dir02 dir03將發出一次呼叫。這消除了最後三個錯誤消息。

關於的錯誤資訊.是因為,嗯,.目前目錄確實是一個目錄,但不是rmdir可以刪除的,因為它不是空的。使用-min-depth停止考慮它,發出命令:

find -mindepth 1 -type d -exec rmdir {} +

這並不完美。嵌套目錄或大量匹配目錄仍可能導致列印錯誤消息,但這應該適用於問題的簡單情況。

你會得到那些“沒有這樣的文件或目錄”錯誤,find因為find它試圖進入它剛剛刪除的目錄。預設情況下,它會將​​其操作應用於目前正在訪問的目錄中的所有匹配內容,然後再繼續進入子目錄。

添加到make-depth的呼叫對其搜尋路徑進行深度優先搜尋,這反過來意味著如果您在目錄上執行,它將已經訪問過它並且不會再次嘗試訪問它。find``find``rmdir

出於這個原因使用時,該-depth選項是隱含的(在that has的實現中)。-delete``find``-delete

find . -depth -type d -exec rmdir {} \;

-depthfind實用程序的標準選項。

請注意,rmdir僅適用於空目錄。如果你有很多非空目錄,上面的命令會產生很多錯誤資訊。

相反,如果您find支持它,請使用-empty

find . -type d -empty -delete

這將刪除空目錄。

使用 a findthat 沒有非標準的-deletenor -emtpy

find . -depth -type d -exec sh -c '
   for dirpath do
       set -- "$dirpath"/*
       [ ! -e "$1" ] && rmdir "$dirpath"
   done' sh {} +

這將測試找到的目錄是否為空,如果是,則將其刪除。

這是一段很長的程式碼,可以避免由於目錄非空而看到一些錯誤消息,但是產生的任何錯誤消息希望看起來更有趣,因為它們可能是“權限被拒絕”錯誤。將錯誤重定向到頂部/dev/null的第一個命令會隱藏此類錯誤。find

引用自:https://unix.stackexchange.com/questions/522173