我发现使用stat和access检查文件是否可执行可能会产生不同的结果。任何人都可以向我解释这两种方法的区别吗?
使用C:
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h> /* Definition of AT_* constants */
#include <assert.h>
int main(){
const int access_ret = access("start.r",X_OK);
const int eaccess_ret = eaccess("start.r",X_OK);
const int faccessat_ret=faccessat(AT_FDCWD,"start.r",X_OK,AT_EACCESS);
printf("%d,\t%d,\t%d",access_ret, eaccess_ret, faccessat_ret);
}
使用bash:
$ stat start.r
File: 'start.r'
Size: 2769 Blocks: 8 IO Block: 4096 regular file
Device: 29h/41d Inode: 58066679 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ ci) Gid: ( 100/ users)
Access: 2016-03-22 22:29:31.234892605 -0400
Modify: 2010-08-06 03:40:03.000000000 -0400
Change: 2016-02-28 20:39:10.244094828 -0500
Birth: -
$ [[ -x start.r ]]; echo $?
0
使用python:
$ python3 -c '
> import os
> print(oct(os.stat("start.r").st_mode))
> print(os.access("start.r",os.X_OK,effective_ids=False))
> print(os.access("start.r",os.X_OK,effective_ids=True))
> '
0o100644
True
True
答案 0 :(得分:0)
如果您的应用程序使用setuid或setgid权限运行,您会注意到不同之处。 access(2)
手册页告诉我们:
使用调用进程的真实UID和GID完成检查, 而不是实际尝试时所做的有效ID 对文件的操作(例如,打开(2))。同样,对于root用户, 检查使用允许的功能集而不是集 有效的能力;对于非root用户,检查使用 空集的能力。
stat(2)
调用不受影响,仅提供实际的文件系统权限。
这两个例子是等价的:它们都返回一个“成功”代码。 0
中的$?
退出状态是成功的,而python的True
也反映成功。
但是示例中有一些不明确的内容:文件的权限没有执行:
Access: (0644/-rw-r--r--)
也许该文件有一些ACL应用于它,这产生了这个结果。如果是这样,您将能够使用getfacl查看此内容。 OP应该提出一个新问题,并将此信息作为背景信息。
进一步阅读: