Home > Software engineering >  os.MkdirAll() fails when creating nested directories
os.MkdirAll() fails when creating nested directories

Time:11-15

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.

  •  Tags:  
  • go
  • Related