Linux 初學者:移動文件
在之前的該系列的部分中,你學習了有關目錄和訪問目錄的許可權是如何工作的。你在這些文章中學習的大多數內容都可應用於文件,除了如何讓一個文件變成可執行文件。
因此讓我們在開始之前先解決這個問題。
不需要 .exe 擴展名
在其他操作系統中,一個文件的性質通常由它的後綴決定。如果一個文件有一個 .jpg 擴展,操作系統會認為它是一幅圖像;如果它以 .wav 結尾,它是一個音頻文件;如果它在文件名末尾以 .exe 結尾,它就是一個你可以執行的程序。
這導致了嚴重的問題,比如說木馬可以偽裝成文檔文件。幸運的是,在 Linux 下事物不是這樣運行的。可以確定的是,你可能會看到有些可執行文件是以 .sh 結尾暗示它們是可執行的腳本,但是這大部分是為了便於人眼找到文件,就像你使用 ls --color
將可執行文件的名字以亮綠色顯示的方式相同。
事實上大多數應用根本沒有擴展名。決定一個文件是否是一個真正程序的是 x
(指可執行的)位。你可以通過運行以下命令使任何文件變得可執行,
chmod a+x some_program
而不管它的擴展名是什麼或者是否存在。在上面命令中的 x
設置了 x
位,a
說明你為所有用戶設置它。你同樣可以為一組用戶設置成擁有這個文件(g+x
),或者只為一個用戶——擁有者——設置 (u+x
)。
儘管我們會在該系列之後的部分包含從命令行創建和運行腳本的內容,並學習通過輸入它的路徑並在結尾加上程序名的方式運行一個程序:
path/to/directory/some_program
或者,如果你當前在相同目錄,你可以使用:
./some_program
還有其他方式可以使你的程序在目錄樹的任意位置運行 (提示:查詢 $PATH
環境變數),但是當我們討論 shell 腳本的時候你會讀到這些。
複製、移動、鏈接
明顯地,從命令行修改和處理文件有很多的方式,而不僅僅是處理它們的許可權。當你試圖打開一個不存在的文件是,大多數應用會創建一個新文件。如果 test.txt
當前並不存在,下列命令:
nano test.txt
vim test.txt
(nano 和 vim 是流行的命令行文本編輯器)都將為你創建一個空的 test.txt
文件來編輯。
你可以通過 「觸摸」 (touch
)來創建一個空的文件,
touch test.txt
會創建一個文件,但是不會在任何應用中打開它。
你可以使用 cp
來拷貝一個文件到另一個位置,或者使用一個不同的名字:
cp test.txt copy_of_test.txt
你也可以拷貝一堆文件:
cp *.png /home/images
上面的命令拷貝當前目錄下的所有 PNG 文件到相對你的主目錄下的 images/
目錄。在你嘗試之前 images/
目錄必須存在, 不然 cp
將顯示一個錯誤。同樣的,警惕,當你複製一個文件到一個已經包含相同名字的文件的目錄時,cp
會靜默地用新文件覆蓋老的文件。
你可以使用:
cp -i *.png /home/images
如果你想要 cp
命令在有任何危險時警告你 (-i
選項代表互動式的)。
你同樣可以複製整個目錄,但是為了做到這樣,你需要 -r
選項:
cp -rv directory_a/ directory_b
-r
選項代表遞歸,意味著 cp
會向下探索目錄 directory_a
,複製所有的文件和子目錄下內部包含的。我個人喜歡包含 -v
選項,因為它使 cp
冗長而啰嗦,意味著它會顯示你當前它正在做什麼而不是僅僅靜默的複製然後存在。
mv
命令移動東西。也就是說,它移動文件從一個位置到另一個位置。最簡單的形式,mv
表現的更像 cp
:
mv test.txt new_test.txt
上面的命令使 new_test.txt
出現,test.txt
消失。
mv *.png /home/images
移動當前目錄下所有的 PNG 文件到相對於你的主目錄的 images/
目錄。同樣的你必須小心你沒有意外的覆蓋已存在的文件。使用
mv -i *.png /home/images
如果你想站在安全的角度,你可以使用與 cp
相同的方式。
除了移動與拷貝的不同外,另一個 mv
和 cp
之間的不同是當你移動目錄時:
mv directory_a/ directory_b
不需要添加遞歸的標誌。這是因為你實際做的是重命名一個目錄,與第一個例子相同,你做的是重命名文件。實際上,即使你從一個目錄到另一個目錄 「移動」 一個文件,只要兩個目錄在相同的存儲設備和分區,你就是在重命名文件。
你可以做一個實驗來證明。 time
是一個工具來讓你測量一個命令花費多久來執行。找一個非常大的文件,可以是幾百 MB 甚至 幾 GB (例如一個長視頻),像下方這樣嘗試拷貝到另一個目錄:
$ time cp hefty_file.mkv another_directory/
real 0m3,868s
user 0m0,016s
sys 0m0,887s
下面是 time
的輸出。需要關注的是第一行, real 時間。它花費了幾乎 4 秒來拷貝 355 MB 的 hefty_file.mkv
到 another_directory/
目錄。
現在讓我們嘗試移動它:
$ time mv hefty_file.mkv another_directory/
real 0m0,004s
user 0m0,000s
sys 0m0,003s
移動幾乎是瞬時的!這是違反直覺的,因為看起來 mv
必須複製這個文件然後刪除原來的。這是 mv
對比 cp
命令必須做的兩件事。但是,實際上,mv
快了 1000 倍。
這是因為文件系統結構中,它的所有目錄樹,只為了讓用戶便利而存在。在每個分區的開始,有一個稱作分區表的東西告訴操作系統在實際的物理磁碟上去哪找每個文件。在磁碟上,數據沒有分為目錄甚至是文件。作為替代的是軌道、扇區和簇。當你在相同分區 「移動」 一個文件時,操作系統實際做的僅僅是在分區表中改變了那個文件的入口,但它仍然指向磁碟上相同的簇信息。
是的!移動是一個謊言!至少在相同分區下是。如果你試圖移動一個文件到一個不同的分區或者不同的設備, mv
仍然很快,但可以察覺到它比在相同分區下移動文件慢了。這是因為實際上發生了複製和清除數據。
重命名
有幾個不同的命令行 rename
工具。沒有一個像 cp
和 mv
那樣固定,並且它們工作的方式都有一點不同,相同的一點是它們都被用來改變文件名的部分。
在 Debian 和 Ubuntu 中, 默認的 rename
工具使用 正則表達式(字元組成的字元串模式)來大量的改變目錄中的文件。命令:
rename 's/.JPEG$/.jpg/' *
將改變所有擴展名為 JPEG
的文件為 jpg
。文件 IMG001.JPEG
變成 IMG001.jpg
、 my_pic.JPEG
變成 my_pic.jpg
,等等。
另一個 rename
版本默認在 Manjaro 上可獲得,這是一個 Arch 的衍生版,更簡單,但是可能沒有那麼強大:
rename .JPEG .jpg *
這和你之前看到的上面做相同的重命名操作。在這個版本,.JPEG
是你想改變的字元組成的字元串,.jpg
是你想要改變成為的,*
表示當前目錄下的所有文件。
基本原則是如果你所做的僅僅是重命名一個文件或者目錄,你最好用 mv
,這是因為 mv
在所有分發版上都是可靠一致的。
了解更多
查看 mv
和 cp
的 man 頁面了解更多。運行
man cp
或者 man mv
來閱讀這些命令自帶的所有選項,這些使他們使用起來更強大和安全。
via: https://www.linux.com/blog/2018/8/linux-beginners-moving-things-around
作者:Paul Brown 選題:lujun9972 譯者:warmfrog 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive