我一直在试图了解下面提到的代码中到底发生了什么。但是我听不懂。
$mode = (stat($filename))[2];
printf "Permissions are %04o\n", $mode & 07777;
可以说我的$ mode值为33188
$ mode和07777产生一个值= 420
$ mode值是十进制数字吗?
为什么选择07777,为什么要按位进行运算。我无法理解这里的逻辑。
您问题的模式对应于具有644个权限的常规文件(所有者为只读文件,其他所有人为只读文件),但请不要误解。
$ touch foo
$ chmod 644 foo
$ perl -le'print +(stat“ foo”)[2]'
33188
的值$mode
可以 看作是十进制整数,但是这样做并不是特别有启发性。看到八进制表示形式会使您更加熟悉。
$ perl -e'printf“%o \ n”,(stat“ foo”)[2]'
100644
与07777的按位与运算给出数字二进制表示形式的最后十二位。在Unix模式下,此操作将给出许可或模式位,并丢弃所有类型信息。
$ perl -e'printf“%d \ n”,(stat“ foo”)[2]&07777'#十进制,无用
420
$ perl -e'printf“%o \ n”,(stat“ foo”)[2]&07777'#八进制,尤里卡!
644
下面是一种更好的方法。继续阅读以获取所有详细信息。
从返回的第三个元素stat
(对应于st_mode
in struct stat
)是一个位字段,其中不同的位位置是二进制标志。
例如,st_mode
POSIX名称中的一位S_IWUSR
。设置了该位的模式的文件或目录可由其所有者写。一个相关的位是S_IROTH
,当置位时表示其他用户(
即 所有者或组中的任何一个)都不能读取该特定文件或目录。
在为perlfunc文档stat
提供了常用的模式位的名称。我们可以检查它们的价值。
#! /usr/bin/env perl
use strict;
use warnings;
use Fcntl ':mode';
my $perldoc_f_stat = q(
# Permissions: read, write, execute, for user, group, others.
S_IRWXU S_IRUSR S_IWUSR S_IXUSR
S_IRWXG S_IRGRP S_IWGRP S_IXGRP
S_IRWXO S_IROTH S_IWOTH S_IXOTH
# Setuid/Setgid/Stickiness/SaveText.
# Note that the exact meaning of these is system dependent.
S_ISUID S_ISGID S_ISVTX S_ISTXT
# File types. Not necessarily all are available on your system.
S_IFREG S_IFDIR S_IFLNK S_IFBLK S_IFCHR S_IFIFO S_IFSOCK S_IFWHT S_ENFMT
);
my %mask;
foreach my $sym ($perldoc_f_stat =~ /\b(S_I\w+)\b/g) {
my $val = eval { no strict 'refs'; &$sym() };
if (defined $val) {
$mask{$sym} = $val;
}
else {
printf "%-10s - undefined\n", $sym;
}
}
my @descending = sort { $mask{$b} <=> $mask{$a} } keys %mask;
printf "%-10s - %9o\n", $_, $mask{$_} for @descending;
在Red Hat Enterprise Linux和System V系列中的其他操作系统上,以上程序的输出将为
S_ISTXT-未定义
S_IFWHT-未定义
S_IFSOCK-140000
S_IFLNK-120000
S_IFREG-100000
S_IFBLK-60000
S_IFDIR-40000
S_IFCHR-20000
S_IFIFO-10000
S_ISUID-4000
S_ISGID-2000
S_ISVTX-1000
S_IRWXU-700
S_IRUSR-400
S_IWUSR-200
S_IXUSR-100
S_IRWXG-70
S_IRGRP-40
S_IWGRP-20
S_IXGRP-10
S_IRWXO-7
S_IROTH-4
S_IWOTH-2
S_IXOTH-1
上面的数字是八进制数(以8为底),因此任何给定的数字都必须为0-7,并且具有位置值8 n ,其中 n
是小数点左侧的从零开始的位置数。要查看它们如何映射到位,八进制具有方便的属性,即每个数字对应于三个位。4、2和1都是2的精确幂,因此以二进制形式分别是100、10和1。二进制中的七个(=
4 + 2 +1)是111,因此70 8是111000 2。后一个示例说明了如何来回转换是直接的。
与位域,你不在乎究竟 是什么 在那个位置有点值,但 是否 是零或非零,所以
if ($mode & $mask) {
测试是否设置了$mode
对应的任何位$mask
。举一个简单的例子,给定4位整数1011和掩码0100,它们的按位与为
1011
& 0100
------
0000
因此,该位置上的位是清楚的,而不是0010或1100的掩码。
清除1011的最高有效位看起来像
1011 1011
& ~(1000) = & 0111
------
0011
回想一下,~
在Perl中是按位补码。
为了完整起见,请按如下所示使用按位OR进行设置
$bits |= $mask;
对于Unix权限,八进制数字直接映射到三位非常方便,因为它们以三位一组出现。例如,产生上面输出的程序的权限为
-rwxr-xr-x 1个gbacon用户1096年2月24日20:34 modebits
也就是说,所有者可以读取,写入和执行;但是其他所有人都可以阅读和执行。八进制为755,这是紧凑的缩写形式。根据上表,该模式下的设置位为
S_IRUSR
S_IWUSR
S_IXUSR
S_IRGRP
S_IXGRP
S_IROTH
S_IXOTH
通过在上面的程序中添加几行,我们可以从您的问题中分解模式。
my $mode = 33188;
print "\nBits set in mode $mode:\n";
foreach my $sym (@descending) {
if (($mode & $mask{$sym}) == $mask{$sym}) {
print " - $sym\n";
$mode &= ~$mask{$sym};
}
}
printf "extra bits: %o\n", $mode if $mode;
模式测试必须格外小心,因为某些掩码是多个位的简写形式。当一些位被置位但不是全部被置位时,进行测试以获取准确的掩码返回可以避免误报。
循环还会从所有检测到的命中清除位,因此最后我们可以检查是否已考虑到每个位。输出是
在模式33188中设置的位:
-S_IFREG
-S_IRUSR
-S_IWUSR
-S_IRGRP
-S_IROTH
没有额外的警告,所以我们得到了一切。
将7777 8转换为二进制得到0b111_111_111_111
。回想一下7 8是111
2,四个7对应于4×3。该掩码对于选择最后十二个设置的位很有用。回顾我们之前生成的位掩码
S_ISUID-4000
S_ISGID-2000
S_ISVTX-1000
S_IRWXU-700
S_IRWXG-70
S_IRWXO-7
我们看到最后9位是用户,组和其他用户的权限。在它们之前的三位是setuid,setgroupid,有时也称为粘性位。例如,sendmail
我系统上的完整模式为-rwxr- sr-x
或34285 10。按位与的结果是
(dec) (oct) (bin)
34285 102755 1000010111101101
& 4095 = & 7777 = & 111111111111
------- -------- ------------------
1517 = 2755 = 10111101101
丢弃模式下的高位为S_IFREG
,表明它是一个常规文件。请注意,与十进制或二进制的相同信息相比,八进制表示的模式更清晰。
该stat
文档提到了一个有用的功能。
…的
S_IF*
功能是
S_IMODE($mode)
的部分$mode
包含所述许可位和的setuid / setgid的/粘性位
在中ext/Fcntl/Fcntl.xs
,我们在最后一行找到其实现和一个熟悉的常量。
void
S_IMODE(...)
PREINIT:
dXSTARG;
SV *mode;
PPCODE:
if (items > 0)
mode = ST(0);
else {
mode = &PL_sv_undef;
EXTEND(SP, 1);
}
PUSHu(SvUV(mode) & 07777);
为了避免在源代码中使用幻数的错误做法,请编写
my $permissions = S_IMODE $mode;
使用S_IMODE
Fcntl模块提供的功能和其他功能还隐藏了低级位混乱,并专注于程序所需的域级信息。该文档继续
S_IFMT($mode)
$mode
包含文件类型 的部分,可以使用(例如)S_IFREG
或以下功能进行位与运算# The operators -f, -d, -l, -b, -c, -p, and -S. S_ISREG($mode) S_ISDIR($mode) S_ISLNK($mode) S_ISBLK($mode) S_ISCHR($mode) S_ISFIFO($mode) S_ISSOCK($mode) # No direct -X operator counterpart, but for the first one # the -g operator is often equivalent. The ENFMT stands for # record flocking enforcement, a platform-dependent feature. S_ISENFMT($mode) S_ISWHT($mode)
使用这些常量和函数可以更直接地表达您的意图,从而使您的程序更加清晰。
问题内容: 我使用这种方法获取图像中像素的整数值: 然后,我打印出这些值,然后看到黑色像素对应于“ -16777216”之类的值,蓝色对应于“ -16755216”之类的蓝色,等等。有人可以向我解释该值背后的逻辑吗? 问题答案: 返回位置 (x,y) 处的彩色像素值。 您误解了返回值。 它是二进制格式。就像11 … 11010101一样,它以int值的形式提供给您。 如果要获得该值的RGB(即红色
本文向大家介绍JavaScript函数模式详解,包括了JavaScript函数模式详解的使用技巧和注意事项,需要的朋友参考一下 在javascript中,函数是一类对象,这表示他可以作为参数传递给其他函数;此外,函数还可以提供作用域。 js函数基础部分:javascript学习笔记(四)function函数部分 创建函数的语法 命名函数表达式 函数表达式 函数的声明 在尾随的分号中,函数表达式应总
本文向大家介绍你了解什么是函数式组件吗?相关面试题,主要包含被问及你了解什么是函数式组件吗?时的应答技巧和注意事项,需要的朋友参考一下 函数式组件: 需要提供一个render方法, 接受一个参数(createElement函数), 方法内根据业务逻辑,通过createElement创建vnodes,最后return vnodes createElement函数, 三个参数, 第一个参数是html标
问题内容: 在python中,是没有重复元素的无序集合。但是,我无法理解它如何生成输出。 例如,考虑以下内容: 应该不是的输出是:?我在Python 2.6中尝试了以上两个。 问题答案: 正如您所说,集合是无序的。即使实现集合的一种方法是使用树,也可以使用哈希表来实现(这意味着按排序顺序获取键可能并不那么琐碎)。 如果您想对它们进行排序,则可以执行以下操作: 这将产生一个包含集合元素的排序列表。(
您正尝试解压一个 被加密的 文件或查看加密文件的内容,请输入密码或是取消解压。 在一次解压多个压缩文件时,您可以启用"用于所有压缩文件"选项把输入的密码应用给所有的压缩文件。如果仅处理一个文件则此选项无效。此选项的其它可能的操作是跳过加密的压缩文件。只要输入一个空的字符串作为密码并设置“用于所有压缩文件”您可以使用它对所有压缩文件只输入一次密码。 如果您已经保存了一些密码,您可以使用密码对话框中输