2015-10-16 66 views
2

我想遞歸地創建一個目錄併爲創建的文件夾及其父項分配一個所有者和組。遞歸地創建一個具有特定所有者和組的目錄

例如,假設/var存在,我想創建/var/test1/test2/test3

我能夠使用os.MkdirAll("/var/test1/test2/test3", 0600)來做到這一點。

不過,我也想設置test1test2test3uiduser1giduser1

使用os.Chown可以這樣做,但這需要大量的手動工作。我需要在創建文件夾鏈之前構建不存在的文件夾及其父項的樹,然後在創建後在每個文件夾上使用os.Chown

有沒有更簡單的方法?

+1

我不認爲有這樣的事情可用。你可能最好複製'MkdirAll'源文件並添加一個合適的'Chown'調用來做你想做的事(IIRC沒有辦法自動創建一個非默認所有者的目錄)。 –

+1

我認爲這是目前最好的選擇,儘管它感覺像是一種代碼味道。 – F21

回答

2

這樣ChownR() type of function了一下,這個想法會過濾步行路程,CHOWN只適用於它們

參數(這裏"/var/test1/test2/test3)所經過的路徑的一部分,無需過濾的文件夾:

func ChownR(path string, uid, gid int) error { 
    return filepath.Walk(path, func(name string, info os.FileInfo, err error) error { 
     if err == nil { 
      err = os.Chown(name, uid, gid) 
     } 
     return err 
    }) 
} 

換句話說,與filepath.Walk(),這裏不應該有太多的「手動工作」。

+0

我認爲'filepath.Walk()'是一個好主意,但我仍然需要複製'mkdirall'的內部來確定鏈中哪些文件夾不存在,請調用'mkdirall'來創建文件夾並然後使用'filepath.Walk()'遍歷鏈並篩選第一個文件夾中收集的文件夾列表並調用'chown'。我認爲與此相比,製作'mkdirall'的副本並添加一行來調用'chown'更加簡單和容易理解。 – F21

+0

@ F21不,步行只適用於chown,而不是創建文件夾。你所要做的就是檢查當前路徑是否是一個文件夾,並且是'/ var/test1/test2/test3'的前綴:如果是,chown。如果不是,繼續走。 – VonC

+0

作爲另一個例子,假設'/ etc/lib /'已經存在,我想創建'/ etc/lib/test1/test2'。'test1'和'test2'也需​​要修改'uid'和'gid',但是我想離開'/ etc/lib'。在所有這些情況下,我不需要做一些處理來查看尚不存在的文件夾,請調用'mkdirall'來創建它們,然後使用'filepath.Walk()'的第一步中的信息來改變他們的'uid'和'gid'?否則,如果沒有這些信息,我會更改已存在的父文件夾的所有者和組。 – F21

0

將mkdir進程切換到您希望爲其創建目錄的用戶。這具有在單個命令中創建具有正確權限和所有權的目錄的優點,而不是創建循環或背靠背運行多個命令。

實施例:

import "os/exec" 
import "syscall" 

func main() { 
    // The command here can use flags to create all of the dirs at once 
    cmd := exec.Command('mkdir', '-p', '/var/test1/test2/test3/') 

    _ = syscall.Umask(0077) // Set umask for this process 

    cmd.SysProcAttr = &syscall.SysProcAttr{} 
    cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid} 

    cmd.Run() 

} 

由於子「MKDIR」運行作爲由uid指定的用戶時,文件夾將已經具有正確的所有者。如果你獲得了正確的umask部分,每個目錄也將具有正確的權限。

一個警告:這不是一個非常便攜的解決方案。如果您確定您的代碼只能在特定的操作系統上執行,那麼使用系統調用應該只是您的解決方案。

相關問題