【发布时间】:2013-01-10 01:33:50
【问题描述】:
我正在尝试在我的程序开始时创建一个日志文件。
如果/log 目录没有创建目录,我需要检查它是否存在,然后继续创建日志文件。
好吧,我尝试使用os.Mkdir(以及os.MkdirAll),但无论我在第二个参数中输入什么值,我都会得到一个没有权限的锁定文件夹。为了获得用户文件夹的读/写,这应该是什么值?我以为是0x700,但它似乎不起作用。
谢谢!
【问题讨论】:
我正在尝试在我的程序开始时创建一个日志文件。
如果/log 目录没有创建目录,我需要检查它是否存在,然后继续创建日志文件。
好吧,我尝试使用os.Mkdir(以及os.MkdirAll),但无论我在第二个参数中输入什么值,我都会得到一个没有权限的锁定文件夹。为了获得用户文件夹的读/写,这应该是什么值?我以为是0x700,但它似乎不起作用。
谢谢!
【问题讨论】:
你可以直接使用八进制:
os.Mkdir("dirname", 0700)
权限位
+-----+---+--------------------------+
| rwx | 7 | Read, write and execute |
| rw- | 6 | Read, write |
| r-x | 5 | Read, and execute |
| r-- | 4 | Read, |
| -wx | 3 | Write and execute |
| -w- | 2 | Write |
| --x | 1 | Execute |
| --- | 0 | no permissions |
+------------------------------------+
+------------+------+-------+
| Permission | Octal| Field |
+------------+------+-------+
| rwx------ | 0700 | User |
| ---rwx--- | 0070 | Group |
| ------rwx | 0007 | Other |
+------------+------+-------+
A Unix Permission Primer
常见权限用法
0755 常用于网络服务器。所有者可以读、写、执行。其他人都可以读取和执行,但不能修改文件。
0777 每个人都可以读写和执行。在 Web 服务器上,不建议对您的文件和文件夹使用“777”权限,因为它允许任何人向您的服务器添加恶意代码。
0644 只有所有者才能读写。其他人只能阅读。没有人可以执行该文件。
0655 只有拥有者可以读写,不能执行文件。其他人都可以读取和执行,但不能修改文件。
www.maketecheasier.com/file-permissions-what-does-chmod-777-means/
Linux 上的目录权限
在 Linux 上对目录应用权限时,权限位的含义与常规文件不同。 (source)
读取位用户可以读取目录中包含的文件名。
写入位用户可以{添加、重命名、删除}文件名,如果执行位也设置了。
执行位用户可以进入目录并访问里面的文件。
https://unix.stackexchange.com/a/21252
权限计算器
【讨论】:
/tmp,但设置了sticky 位,因此它不一样),否则您永远不需要。如果您需要上传东西,则将目录的用户设置为运行网络服务器或PHP的用户。够了。无需随机用户或 MTA 或任何能够写入此目录的东西
php或网络服务器的用户),并将其设置为755,以便只有该用户可以写入。跨度>
0 的要求视而不见。有人可以谈谈并将其添加到答案中吗?
@Daniel 在他的回答中的陈述并不正确,而且它谈到了一个十进制数,然后使用了一个八进制数,正如@SashaCrofter 在他的评论中正确指出的那样。
实际上,无论您的权限值是什么形式,只要它代表合理的 Unix 权限即可。
由于 POSIX 文件系统上的权限位是由三位组成的——三位用于所有者、组和其他人的访问权限,加上三位修饰符(例如粘性位)——习惯上使用八进制数来表示每个位的权限八进制数中的digit表示三位值。
因此,当你在 Go 代码中使用 0700 时,前导 0 会被去除,仅用于告诉解析器它看到一个八进制数字文字,以下三个字母代表所有者、组和其他权限,在此命令。如果您还想设置组粘性位以及使文件系统对象组可读和可执行,您可以指定 02750 等等。
请注意,文件系统对象获得的实际权限进一步受到创建该对象的进程的活动umask 的调节。
要更深入地了解这些主题,最好阅读chmod 手册页和有关类 Unix 操作系统的一般文献。
【讨论】:
您可以将 umask 重置为 0。我会将此称为主文件中的第一件事
syscall.Umask(0)
例子
_ = os.MkdirAll("/tmp/dirs/1", 0664)
syscall.Umask(0)
_ = os.MkdirAll("/tmp/dirs/2", 0664)
结果
/tmp/dirs$ stat -c '%A %a %n' *
drw-r--r-- 644 1
drw-rw-r-- 664 2
【讨论】:
除了其他答案,请记住,在 Unix 和 Linux 风格的操作系统上,所有程序都使用 umask 设置运行。 umask 在许多情况下默认为 022 或有时为 002,是系统将从文件和目录创建请求中自动删除的一组权限。
这意味着大多数程序——这个规则有几个例外——应该使用模式0666创建文件和模式0777创建目录。 用户的配置,记录在运行的进程中,说明这些权限中的哪一个拿走。如果用户的设置是022,我们创建一个模式为0666的文件,我们得到的实际设置是rw-r--r--:用户读写,组只读,其他人只读.
如果用户希望将可写性扩展到他们的组,他们只需将他们的 umask 设置为2:现在他们取消了其他人的写权限,但将其留给了他们的组。现在使用模式rw-rw-r-- 创建新文件。 程序 没有改变:它仍然使用0666 作为其模式。但是文件是用0664模式创建的。
同样,如果您使用0777 调用os.Mkdir 或os.MkdirAll,umask 将带走不需要的权限,让您拥有正确的权限。
但我提到了有例外。其中包括复制仅供用户使用的敏感信息的程序:这些通常应使用模式0700 用于目录,0600 用于文件。它们可能包括长期运行的服务器,它们充当系统用户而不是任何个人......尽管这些服务器可以使用正确的 umask 运行,在这种情况下, 0777 或 0666 都可以。
你必须在这里应用一些判断。对安全特别敏感的程序(例如 ssh 或类似程序)可能希望使用有限的权限,甚至可能希望检查(使用os.Lstat 或类似的)重要目录的权限是否适当。
(请注意,umask 不适用于 os.Chmod 调用。这里你直接选择模式。)
【讨论】:
确保您设置所需权限的一种方法是使用包os 中非常方便的FileMode 常量,而不用计算出复杂的八进制计算:
https://golang.org/pkg/os/#FileMode
我通常将os.ModePerm(实际上编码为0777)用于完全许可的目录,例如缓存或临时文件所需的目录,但您的里程可能会有所不同。要设置额外的位(粘性等),正如@kostix 所指出的那样,必须处理 Go 中标志的八进制表示问题,您总是可以使用类似的东西:
if err := os.MkdirAll("my/tmp/dir", os.ModeSticky|os.ModePerm); err != nil {
... handle error ...
}
与往常一样,值得一提的是再次这些权限被设置为umask 的任何“过滤”。
【讨论】: