在不使用 mv 命令的情況下移動文件
不起眼的 mv
命令是在你見過的每個 POSIX 系統中都能找到的有用工具之一。它的作用是明確定義的,並且做得很好:將文件從文件系統中的一個位置移動到另一個位置。但是 Linux 非常靈活,還有其他移動文件的辦法。使用不同的工具可以完美匹配一些特殊用例,這算一個小優勢。
在遠離 mv
之前,先看看這個命令的默認結果。首先,創建一個目錄並生成一些許可權為 777 的文件:
$ mkdir example
$ touch example/{foo,bar,baz}
$ for i in example/*; do ls /bin > "${i}"; done
$ chmod 777 example/*
你可能不會這麼認為,但是文件在一個文件系統中作為條目存在,稱為索引節點(通常稱為 inode),你可以使用 ls 命令及其 --inode
選項查看一個文件佔用的 inode:
$ ls --inode example/foo
7476868 example/foo
作為測試,將文件從示例目錄移動到當前目錄,然後查看文件的屬性:
$ mv example/foo .
$ ls -l -G -g --inode
7476868 -rwxrwxrwx. 1 29545 Aug 2 07:28 foo
如你所見,原始文件及許可權已經被「移動」,但它的 inode 沒有變化。
這就是 mv
工具用來移動的方式:保持 inode 不變(除非文件被移動到不同的文件系統),並保留其所有權和許可權。
其他工具提供了不同的選項。
複製和刪除
在某些系統上,移動操作是真的在做移動:比特從文件系統中的某個位置刪除並重新分配給另一個位置。這種行為在很大程度上已經失寵。現在,移動操作要麼是屬性重新分配(inode 現在指向文件組織中的不同位置),要麼是複製和刪除操作的組合。這種設計的哲學意圖是確保在移動失敗時,文件不會碎片化。
與 mv
不同,cp
命令會在文件系統中創建一個全新的數據對象,它有一個新的 inode 位置,並取決於 umask。你可以使用 cp
和 rm
(如果有的話,或者 trash —— LCTT 譯註:它是一個命令行回收站工具)命令來模仿 mv
命令。
$ cp example/foo .
$ ls -l -G -g --inode
7476869 -rwxrwxr-x. 29545 Aug 2 11:58 foo
$ trash example/foo
示例中的新 foo
文件獲得了 755 許可權,因為此處的 umask 明確排除了寫入許可權。
$ umask
0002
有關 umask 的更多信息,閱讀 Alex Juarez 這篇關於文件許可權的文章。
查看和刪除
與複製和刪除類似,使用 cat(或 tac
)命令在創建「移動」文件時分配不同的許可權。假設當前目錄中是一個沒有 foo
的新測試環境:
$ cat example/foo > foo
$ ls -l -G -g --inode
7476869 -rw-rw-r--. 29545 Aug 8 12:21 foo
$ trash example/foo
這次,創建了一個沒有事先設置許可權的新文件,所以文件最終許可權完全取決於 umask 設置,它不會阻止用戶和組的許可權位(無論 umask 是什麼,都不會為新文件授予可執行許可權),但它會阻止其他人的寫入(值為 2)。所以結果是一個許可權是 664 的文件。
Rsync
rsync
命令是一個強大的多功能工具,用於在主機和文件系統位置之間發送文件。此命令有許多可用選項,包括使其目標鏡像成為源。
你可以使用帶有 --remove-source-files
選項的 rsync
複製,然後刪除文件,並可以帶上你選擇執行同步的任何其他選項(常見的通用選項是 --archive
):
$ rsync --archive --remove-source-files example/foo .
$ ls example
bar baz
$ ls -lGgi
7476870 -rwxrwxrwx. 1 seth users 29545 Aug 8 12:23 foo
在這裡,你可以看到保留了文件許可權和所有權,只是更新了時間戳,並刪除了源文件。
警告:不要將此選項與 --delete
混淆,後者會從目標目錄中刪除(源目錄中不存在的)文件。誤用 --delete
會清除很多數據,建議你不要使用此選項,除非是在測試環境中。
你可以覆蓋其中一些默認值,更改許可權和修改設置:
$ rsync --chmod=666 --times
--remove-source-files example/foo .
$ ls example
bar baz
$ ls -lGgi
7476871 -rw-rw-r--. 1 seth users 29545 Aug 8 12:55 foo
這裡,目標的 umask 會生效,因此 --chmod=666
選項會產生一個許可權為 644 的文件。
好處不僅僅是許可權,與簡單的 mv
命令相比,rsync
命令有很多有用的選項(其中最重要的是 --exclude
選項,這樣你可以在一個大型移動操作中排除某些項目),這使它成為一個更強大的工具。例如,要在移動文件集合時排除所有備份文件:
$ rsync --chmod=666 --times
--exclude '*~'
--remove-source-files example/foo .
使用 install 設置許可權
install
命令是一個專門面向開發人員的複製命令,主要是作為軟體編譯安裝常式的一部分調用。它並不為用戶所知(我經常想知道為什麼它有這麼一個直觀的名字,而剩下的包管理器卻只能使用縮寫和昵稱),但是 install
實際上是一種將文件放在你想要地方的有用方法。
install
命令有很多選項,包括 --backup
和 --compare
命令(以避免更新文件的新副本)。
與 cp
和 cat
命令不同,但與 mv
完全相同,install
命令可以在複製文件的同時而保留其時間戳:
$ install --preserve-timestamp example/foo .
$ ls -l -G -g --inode
7476869 -rwxr-xr-x. 1 29545 Aug 2 07:28 foo
$ trash example/foo
在這裡,文件被複制到一個新的 inode,但它的 mtime(修改時間)沒有改變。但許可權被設置為 install
的默認值 755
。
你可以使用 install
來設置文件的許可權,所有者和組:
$ install --preserve-timestamp
--owner=skenlon
--group=dialout
--mode=666 example/foo .
$ ls -li
7476869 -rw-rw-rw-. 1 skenlon dialout 29545 Aug 2 07:28 foo
$ trash example/foo
移動、複製和刪除
文件包含數據,而真正重要的文件包含你的數據。學會聰明地管理它們是很重要的,現在你有了確保以你想要的方式來處理數據的工具包。
你是否有不同的數據管理方式?在評論中告訴我們你的想法。
via: https://opensource.com/article/19/8/moving-files-linux-without-mv
作者:Seth Kenlon 選題:lujun9972 譯者:MjSeven 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive