[Cygwin]如何在 Cygwin 上存取其它目錄的檔案

有 Unix 經驗的人,應該在安裝好 Cygwin 後的第一個問題應該是:Cygwin 的根目錄,實際上對映到的是 Windows 上的哪一個目錄?

在之前我寫的 介紹 Cygwin 那篇文章中,在討論安裝步驟時,我曾經有提到過,Cygwin 的根目錄是在你安裝 Cygwin 所在的目錄,比如說 C:\Cygwin。所以你可以在這個目錄下建立新目錄,全都可以對映到 Cygwin 下的目錄。有興趣的人可以再跳到該篇看一下。

除此之外,每個使用者都有其家目錄 (Home directory),比如,aaa 的家目錄就是 /home/aaa。這個家目錄就像在其它的 Unix 一樣,當你登入時,系統會自動讓你進入這個目錄,因此你個人的所有設定值,比如像 $PATH,皆可寫到這個目錄下的 .bashrc (假設你用的 shell 是 bash) 中。

其實,Cygwin 還提供了一套機制,叫做 cygdrive,cygdrive 的機制,就好像是你的 Windows 的真正根目錄。利用這個 cygdrive,你可以參照到你的 C: D: E: ...這些磁碟。比如說,/cygdrive/c/ 是你的 C:\ 碟,/cygdrive/d/ 是你的 D:\ 碟,以此類推。

因此,你可以很輕易地使用 cron 和 cygdrive 去自動執行你的 Windows 上的程式,當然先決條件是這個程式是純文字介面的,而不是 GUI,比如說,像 PostgreSQL 的 pg_dump 或 MySQL 的 mysqldump 搭配 tar,可以自動 on-line backup。

可能你還想做一些其它的事,比如說,若你打算要讓某一個目錄掛載 (mount) 到你的家目錄下,這時候你第一個會想要利用像一般 Unix 下的 mount 指令。但是,Cygwin 上有 mount 嗎?有,Cygwin 也提供 mount/umount 指令,只是 Cygwin 版的 mount 和一般正統的 Unix 下的 mount 指令,在用法上還是有一點差異。所以,我特別在此要對 Cygwin 的 mount 稍微說明一下。

mount 指令如果沒有設定參數時,會把目前掛載點全部列出來。我來借用一下 Cygwin 線上手冊的例子。

~ $ mount
c:\cygwin\bin on /usr/bin type system (binmode)
c:\cygwin\lib on /usr/lib type system (binmode)
c:\cygwin on / type system (binmode)
c:\ on /c type user (binmode,noumount)
d:\ on /d type user (binmode,noumount)

這裏列出的有五個目錄,舉一個例子來說明。Windows 下的 C:\cygwin\bin 目錄,在 Cygwin 中是掛在 /usr/bin。也就是說,當你在 Cygwin 中,cd 進入 /usr/bin 時,相當於進入 Windows 下的 C:\cygwin\bin 目錄。

你甚至可以掛上網路上的芳鄰中,別台機器分享出來的目錄。如果你的 Cygwin 有安裝 NFS,也可掛上別台 Unix 上 NFS 分享出來的目錄。比如說:

~ $ ls /data
ls: /data: No such file or directory

~ $ mount \\pollux\home\joe\data /data
mount: warning - /data does not exist!

~ $ mount
\\pollux\home\joe\data on /data type sytem (binmode)
c:cygwinbin on /usr/bin type system (binmode)
c:cygwinlib on /usr/lib type system (binmode)
c:cygwin on / type system (binmode)
c: on /c type user (binmode,noumount)
d: on /d type user (binmode,noumount)

這個例子是把 \\pollux 這台機器分享出來的 /home/joe/data 掛到 /data 這個掛載點上,不論它是 Windows SMB 的分享 (也就是 Windows 上的「網路上的芳鄰」啦,這個例子就是),或是 NFS 分享出來的目錄資源。注意,由於實體上,根目錄下不存在 /data 這個目錄,因此,當你下達 mount 指令時,會出現警告訊息,而且如果你在根目錄下,下達 ls 指令時,會看不到 /data 這個目錄的存在,但是從根目錄下輸入 cd /data,還是可以進入這個目錄,宛若是一個隱形目錄一般。想要不出現這種狀況,方法是在掛載前先在根目錄下建立一個空白的 /data 目錄,以供掛載之用。當然,Windows 下的任何目錄可以用這種方法掛上。比如說,你可以用 mount C:\temp /tmp,把 C:\ 碟中的 temp 目錄掛到 /tmp 上。對了,對 Unix 不熟的朋友們要注意,如果你在 /data 目錄下有放什麼檔,當你下達 mount 指令後,這些檔的 inode 會看不見,無法存取,所以請留意,一定要讓 /data 中保持淨空。

剛剛提到 Cygwin 中的 mount 有幾點和一般 Unix 上的 mount 有一點出入,現在開始來說明一下。

首先先說明一般的使用。在其它的 Unix 下,mount 是暫時性的,也就是說,當你的機器重新啟動時,原先你掛載的目錄的掛載點會全清除掉,除非在一些檔案中先設定,比如在 FreeBSD上的 /etc/fstab,系統在開機時會自動參考這個檔,會自動把這些目錄掛載進來。但是在 Cygwin,卻沒有這樣的機制,而當你一旦用 mount 掛載某一目錄後,除非你使用 umount 把它卸除,否則會一直掛著。 那是因為 Cygwin 的 mount 指令會把掛載點登錄在 Windows 的 Registry 中,這一點是最要注意的。

其次要注意是 cygdrive 無法卸除,而且是預設值。mount 的參數中有一項 --change-cygdrive-prefix (或是簡單一點,-c,我個人比較喜歡用簡單一點的)。這可以把預設的 cygdrive 改名,比如說 mount -c /ccc,這樣你的 C:\ 碟掛載點改成 /ccc/c。注意一點,更改 cygdrive 的掛載名,一定要像 /ccc 一樣以 / 開頭,不然會出現錯誤。

第三點需要注意的是,如果你是使用 Windows XP,預設帳號通常就是等同 Administrator,隸屬於 Administrators 群組,即使此帳號不是 Administrator。如果這時你使用 mount 新增一個掛載點,那麼它必是屬於 system type,也就是登入的每一位使用者皆可使用。除非是在你下 mount 指令時,特地加上 -u--user 參數,告訴系統這時你所建立的掛載點是屬於 user type,僅供個人使用。

好了, mount 介紹完了,若打算利用 Cygwin、crond 來做一些自動化管理系統的工作,目前就剩下你自己的練習了。

回應

請問Cygwin如何設定資料夾路徑權限?

您好,我是cygwin的新手;感謝您寫這麼好的教學文章

有件事想請教:

小弟用到PVElab這個軟體(請參考:http://nru.dk/downloads/software/ 和 http://www.nru.dk/pveout/)
在Windows XP 平台下,Matlab 7.8.0 (R2009a)執行

她還需要安裝
a. "MriWarp/Brain Warp" (http://neuro.imm.dtu.dk/software/mriwarp/mriwarp.html)
b. "AIR 5"(http://bishopw.loni.ucla.edu/air5/)
兩者是c files;但我要轉成執行檔很不順利。
原作者(丹麥人)很好心的把他轉好的執行檔給我(但未含cygwin1.dll)
我裝了最新版的cygwin,也拷貝了cygwin1.dll到存放bin的資料夾中。

但還是會出現如
alignlinear.c: 146: Unable to parse argument I:\PVEC_new\pve_proj_1\tmp_dir04_02\n04_trnsf2_PET_i16.air, which was expected to begin with a '-'
的錯誤訊息而卡住鬱卒

原作者表示我寄給他的資料檔案在他的電腦跑沒有問題,建議我可以用下列方式調整:

I have heard that someone have had problems with access right to the directory where data flies are placed using the cygwin compiled routines.
Could you please try to "define that everyone should have full access rights to the data directory and all subdirectories to this."

請問這個部份在Cygwin怎麼設定呢?(將資料夾路徑權限設定成每個人都可以用)
我查了mount和cygpath這兩個指令但不是很確定
請問各位大大是要用哪個指令才能達成此目的呢?

你的狀況如果沒在你的機器上是很難抓到真正原因的。我猜原作

你的狀況如果沒在你的機器上是很難抓到真正原因的。
我猜原作者的意思,是要你把整個掛載點以下,權限先全設成 chmod 777 /preout ← 假設你的 mount 點是 /preout,但是不確定。
但是也有可能要你直接從 Windows 下,到檔案總管把那個 folder 的權限改成所有人都可讀取、寫入和執行甚至完全控制......,我也不確定。
因為 Cygwin 仍然是在 Windows 下執行,Windows 的權限和 Unix 的權限管理原則仍然有不少差異。
我的另一個建議可能對你的壓力會大一點,就是直接看原始碼。這樣更能精確的知道原作者的 bug 在哪(也就是他寫程式時忽略掉什麼地方)。
我曾經為了跑一個 PostgreSQL 的分析程式,花了一整年時間慢慢把原始碼(用 C++ 寫成的)看完,然後改成 CentOS 上可以跑,但是再碰到類似的東西,我有把握大概用一週時間就能解決。總之用別人寫的程式時,如果遇到問題,最好可能要了解他的邏輯的方法,就是看完他的程式。
總之,加油吧。再不行,考慮用 VMware 安裝 CentOS 或 Ubuntu 試試看。

感謝您的回應~

很抱歉拖了這麼久才有回應
因為有其他的事情在忙,所以這個題目就先暫停了~
如您所言,這會是一個複雜的問題
所以我決定用另一種方式:改用linux system來跑
這對我也是全新的經驗,目前正在研究CentOS中

再次感謝您~