vlambda博客
学习文章列表

Linux下umask命令详解及C/C++代码实现

在 Linux 和其他类 Unix 操作系统上,新文件是使用一组默认权限创建的。而umask 命令返回或设置系统文件模式创建掩码的值。

umask 命令语法

在这里插入图片描述

用法:

umask [-p] [-S] [mode]

用户文件创建掩码设置为模式。如果 mode 以数字开头,则将其解释为八进制数;否则,它被解释为类似于 chmod接受的符号模式掩码。如果省略模式,则打印掩码的当前值。

-S 选项使掩码以符号形式打印; 默认输出是八进制数。

如果提供了 -p 选项,并且省略了 mode,则输出的格式可以重复用作输入。如果模式已成功更改或未提供模式参数,则返回状态为 0,否则返回 false。

什么是权限,它们是如何工作的?

你可能知道,系统上的每个文件都与一组用于保护文件的权限相关联,文件的权限决定了哪些用户可以访问该文件,以及他们对该文件拥有何种访问权限。

所有基于 Unix 的操作系统都有一组属性,用于定义允许谁读取、写入或执行特定文件或目录。 这些权限适用于三个称为“权限类”的类别,它们的说明如下:

用户(User):默认情况下,用户是文件或文件夹的所有者或创建者。新文件的所有权默认归该用户所有。

组(Group):组是一组用户,它们对文件或文件夹具有相同的访问级别或权限。

 其他(Other):其他组定义为不包括在前两个类别中的任何用户。这些用户没有创建文件或文件夹,也不属于特定的用户组。该组包括未被标识为用户或属于用户组的每个人。

权限如何表示?

有两种方式来表示文件的权限:符号(使用符号,如“r”表示读取,“w”表示写入,“x”表示执行)或使用八进制数值。

例如,当您在命令行中使用 ls 命令列出目录的内容时,如下所示:

Linux下umask命令详解及C/C++代码实现将看到文件权限信息。在这里,它以符号方式表示,如下例所示:

-rw-r--r--

这里有十个符号。第一个破折号(“-”)表示这是一个“常规”文件,换句话说,不是目录(或设备,或任何其他特殊类型的文件)。

其余九个符号代表权限:rw-r--r--。这九个符号实际上是三组,每组三个符号,分别代表各自的具体权限,从左到右:

符号含义

rw- 文件的所有者可以读取、写入,但不能执行此文件作为系统上的进程。r-- 文件组中的任何人都可以读取,但不能执行此文件,不能写入。r-- 任何人都可以读取该文件,但不能写入该文件或将其内容作为进程执行。

为了更好地了解 umask 的工作原理,我们需要了解八进制模式安全设置。三个 rwx 权限 (Read-Write-Execute) 值转换为三位二进制值,并由单个八进制值表示,如下表所示:

权限 八进制值 二进制值 描述
0 000 没有权限
–x 1 001 只有执行权限
-w- 2 010 只有写权限
-wx 3 011 写入和执行权限
r– 4 100 只有阅读权限
r-x 5 101 读取和执行权限
rw- 6 110 读写权限
rwx 7 111 执行所有三项操作的权限,即读取、写入和执行

如何计算umask值?

Linux下umask命令详解及C/C++代码实现

第一个零是特殊许可数字,它是一种特殊的安全功能,可以忽略。三位数字代表文件或目录的 umask 的八进制值。让我们解释一下使用 umask 得到的输出,0002 。

上面的输出 (0 0 2) 显示所有者的访问权限是 0,组成员的访问权限是 0,其他的访问权限是 2。

例子

要将其视为符号表示,请使用 -S 标志:

umask -S

Linux下umask命令详解及C/C++代码实现

它象征性地返回相同的值,例如:

u=rwx,g=rwx,o=rx

其中u代表用户,g代表组,o代表其他。这告诉我们如果我们创建一个新文件,它的默认权限为 664,即 666(文件的默认权限)被 002(我们的 umask 值)屏蔽。

让我们通过使用 touch 命令创建一个新文件来测试一下:

Linux下umask命令详解及C/C++代码实现

正如预期的那样,新文件的权限为 -rw-rw-r-- 或 0664:所有者和组可以读取或写入该文件,而其他人只能读取它。

umask命令C/C++代码实现

int main(int argc, char * * argv)
{
    char * arg;
    char * arg0 = *argv;

    /* 函数指针保存八进制或符号 umask 打印选择:  */
    int (* print_umask)(char * arg0) = print_umask_octal;

    /* 没有任何参数(两个,计算 argv[0]),只需打印 umask:  */
    if(argc < 2)
    {
        if(!arg0)
        {
            arg0 = "";
        }
        return print_umask(arg0);
    }


    argv += 1;

    /* 第一个参数是一个选项(以“-”开头)或 umask:  */
    arg = *argv;

    if(*arg == '-')
    {
        arg += 1;
        if(!strcmp(arg, "-help") || !strcmp(arg, "h"))
        {
            return print_help(arg0);
        }
        if(!strcmp(arg, "-version") || !strcmp(arg, "V"))
        {
            return print_version(arg0);
        }

        if(!strcmp(arg, "-symbolic") || !strcmp(arg, "S"))
        {
            print_umask = print_umask_symbolic;
        }
        else
        /* 如果它*不是*“选项结束”(“--”)“选项”: */
        if(strcmp(arg, "-"))
        {
            return error_bad_option(arg - 1, arg0);
        }
        argv += 1;
        arg = *argv;

        if(!arg)
        {
            return print_umask(arg0);
        }
    }

    /* 现在 arg 应该是 umask。  */

    if(!parse_and_set_umask(arg))
    {
        return error_bad_umask(arg, arg0);
    }

    /* 将 argv 移过 umask,只在 argv 中留下命令: */
    argv += 1;
    arg = *argv;

    if(!arg)
    {
        return print_umask(arg0);
    }
    execvp(arg, argv);
    return error_executing_command(arg, arg0);
}

运行结果:


chmod 和 umask 有什么区别?

umask 命令只能用于新文件,即在创建新文件时,在使用 umask 命令之前创建的任何文件都将无效。chmod 命令必须用于已经存在的文件,它用于更改之前创建的文件的访问权限。

总结

umask 或用户文件创建模式是一个 Linux 命令,用于为新创建的文件夹和文件分配默认文件权限集。术语掩码引用了权限位的分组,每个位都定义了如何为新创建的文件设置相应的权限。可以通过调用 umask 命令更改掩码中的位。