[Linux] 用 cp 指令複製目錄到別的目錄下,結果目錄少了一層?
今天把專案程式裡的 Google Protocol Buffer 升級,
結果踩到 cp 指令的一個雷,
模組的路徑錯誤,讓程式整個都不會動啦~
來看一下這個雷是什麼吧…
Google Protocol Buffer 的 python 版本,
從目錄結構上來說,會有 google/protobuf 這樣的目錄,
我希望把 google 目錄放在我們的 <專案>/tool/proto 下,
也就是最後會變成 <專案>/tool/proto/google/protobuf。
因此,在編譯完 Google Protocol Buffer 後,
會用下面的 cp 指令,把 google 目錄複製到我們的專案目錄下:
cp -R python/build/google /myproject/tool/proto/
這個指令看起來很簡單,在我的機器上測試結果也很正常,
但是在 QA 的機器上,Google Protocol Buffer 的目錄卻錯了,
比預期的路徑少了一層目錄:
- 預期路徑:/myproject/tool/proto/google/protobuf
- 錯誤路徑:/myproject/tool/proto/protobuf
因為這個錯誤,導致專案找不到 Google Protocol Buffer 的模組。
但,為什麼 cp 會弄出那個錯誤的路徑呢?
研究了半天終於發現,
/myproject/tool/proto 這目錄是否已經存在,對 cp 的結果有很大影響~
如果 tool/proto 目錄已經存在的話:
=> cp 就會好好的把 google 目錄複製到 proto 目錄下。
但如果 tool/proto 目錄不存在的話:
=> cp 會以為要把 google 目錄複製到 tool 目錄下,「並且改名」為 proto!!
這就是為什麼最後 google 目錄會不見,
變成 /myproject/tool/proto/protobuf 的原因了~
這其實是 cp 的標準動作,但我的心魔卻是以為如果目標目錄下加一個 /,
cp 就會認為是要複製到那目標目錄「下面」了…
來做個實驗吧~
我們現在有個目錄 a/b/c,也有一個 tool 目錄,
我打算把 a 目錄複製到 tool/proto 目錄下。
情境 #1: tool/proto 目錄存在,cp 目標目錄後面加 /
結果很正常,最後會出現 tool/proto/a/b/c:
testuser@localhost ~ $ cp -R a tool/proto/ testuser@localhost ~ $ tree tool tool └── proto └── a └── b └── c
情境 #2: tool/proto 目錄存在,cp 目標目錄後面不加 /
結果和情境 #1 一樣,目標目錄後面有沒有加 / 沒有影響:
testuser@localhost ~ $ cp -R a tool/proto testuser@localhost ~ $ tree tool tool └── proto └── a └── b └── c
情境 #3: tool/proto 目錄不存在,cp 目標目錄後面加 /
結果是 a 被更名為 proto,因此最後是 tool/proto/b/c:
testuser@localhost ~ $ cp -R a tool/proto/ testuser@localhost ~ $ tree tool tool └── proto └── b └── c
情境 #4: tool/proto 目錄不存在,cp 目標目錄後面不加 /
結果和情境 #3 一樣,目標目錄後面有沒有加 / 沒有影響:
testuser@localhost ~ $ cp -R a tool/proto testuser@localhost ~ $ tree tool tool └── proto └── b └── c
解決的方法就是在 cp 之前,要確定目標目錄已經存在,例如:
mkdir -p /myproject/tool/proto
希望以後不要再踩到這種雷了啊…