I have an output/
directory. When the directory to be created is
prefix := "output/2021-11-12.19.51.50.047614/2011-12"
os.MkdirAll(prefix, 0644)
fails. When it is
prefix := "output/2021-11-12.19.51.50.047614"
it works.
Why can't os.MkdirAll()
create nested directories? That's its purpose. Is this a bug?
CodePudding user response:
The mode
argument to os.MkdirAll
must include some executable (111
) bits.
In general, the mode
argument to os.MkdirAll
should be 0777
, at least on Unix-like systems. In some cases, it should be 0700
. (For the same reason, newly created files should be made with 0666
, not 0644
; sometimes 0600
is appropriate.)
The Go runtime passes the mode down to the OS-level calls. On Unix-like systems, where the permissions actually make sense,1 the bits that you provide are then modified by clearing any bits set in the current umask setting. It's this umask that should take away group and other write permissions, resulting in the eventual 0755
permissions—unless, that is, the user wants to take away more permissions (resulting in, say, 0750
or 0700
) or fewer (resulting in, say, 0775
).
Remember that the three groups of three bits represent read (r
), write (w
), and execute (x
) permissions: 7
is rwx
, 6
is rw-
, 5
is r-x
, and so on. So 0777
represents rwxrwxrwx
.
Unix-like systems require execute permission to name a file within a directory, so if you don't give yourself execute permission, you can no longer work with the directory.
1On systems with ACLs, user permissions make some sense and "other" might be reasonable as the default, but "group" is ill-defined. Systems that do offer ACLs usually have a lot finer granularity than the simple rwx
controls anyway, though.