access(2)vs stat(2)检查文件是否可执行

时间:2016-03-23 23:06:25

标签: python linux bash permissions

我发现使用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

1 个答案:

答案 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应该提出一个新问题,并将此信息作为背景信息。

进一步阅读: