3

简短背景:我需要使用 ZABBIX 监视 unix 文件(目录)的权限,以查看它们是否/何时更改。ZABBIX 没有像 vfs.file.mode[xxxx] 这样的内置函数,所以我必须使用数字类型滚动我自己的 UserParameter。

到目前为止,我所做的是ls -l | cut -c 2-10用来获取rwxr-xr-x零件,然后sed用来将字母转换为它们的“重量”,并awk总结substr起来,得到数字755或任何值。

这目前在 Solaris 上,我没有 GNU coreutilsstat命令,我希望它是可移植的和高效的,并且只使用始终可用的标准 unix 工具。(恕我直言,perl 并不总是可用)。

我的第一次尝试(根目录的示例):

ls -ld / | \
cut -c 2-10 | \
sed -e 's%-%0%g' -e 's%r%4%g' -e 's%w%2%g' -e 's%x%1%g' | \
awk '{print (100 * ((substr($0,1,1)) + (substr($0,2,1)) + (substr($0,3,1))) + \
     (10 * ((substr($0,4,1) + (substr($0,5,1)) + (substr($0,6,1)) ))) + \
     ( (substr($0,7,1)) + (substr($0,8,1)) + (substr($0,9,1)) ) );}'

如您所见,我不关心 setuid 位或文件以外的任何内容,但始终欢迎纯粹的回应!

当然必须有一个更优雅的解决方案。也许是我没有想到的标准 unix 工具。

大约一周前,我“偶然”发现了这个地方,我真的很喜欢它!在一个地方看到这么多知识、技能和友善,真是太棒了!这是我的第一个问题,所以我很高兴看到我是否得到任何回应!:-) 非常感谢!

4

6 回答 6

4

如果你可以使用find,那么这看起来更好:

find FILENAME -prune -printf '%m\n'

这里找到

于 2010-07-07T17:42:32.323 回答
1

我不相信这比你自己的版本更优雅/高效,但我会提出它,以防任何技术对改进你自己的技术有用。这显然可以用脚本更简单/优雅地完成

基本前提是使用 tr 将 rwx 转换为相关的八进制数,然后使用 sed 分成 3 个加号组,然后生成一个 awk 命令字符串,将其传递给 awk 以将它们相加。

ls -ld / | \
cut -c2-10 | \
tr 'rwx-t' '42100' | \
sed -E -e 's/(...)(...)(...)/\1 \2 \3/g' \
-e 's/([0-9])([0-9])([0-9])/\1+\2+\3/g' \
-e 's/^(.*)$/BEGIN {print \1}/g'|\
awk -f -`
于 2010-07-07T22:50:56.537 回答
1

如果您的系统具有bash, 并ls -l显示文件权限 (rwxrwxrwx),您可以通过以下示例完成您正在寻找的内容:

#!/bin/sh
[ ! -d $1 ] && echo "Error: "$1" is not a directory" && exit 1 
set -- `ls -ld $1`;P=${1:1:9};P=${P//r/4 };P=${P//w/2 };P=${P//x/1 };P=${P//-/0 }
set -- $P; echo $((($1+$2)+$3))$((($4+$5)+$6))$((($7+$8)+$9))

优点是不需要其他实用程序,例如 awk 或 sed。

于 2015-01-12T02:11:48.277 回答
0

stat应该有你要找的东西。尝试其中之一:

stat -c "%a" <filename>

或者

stat --printf="%a" <filename>
于 2010-07-07T14:38:01.577 回答
0

这是冗长的,但我认为它比你的更易于维护。你可以这样称呼它:ls -ld / | cut -c 2-10 | ./perm.awk.

#!/usr/bin/gawk -f
# OR: #!/usr/bin/nawk -f

function conv(num, len, i, val) {
    # converts binary string to decimal (or octal if fed 3 "bits" at a time)
    # call with num as argument, others are local variables
    len = length(num)
    for(i = len; i > 0; i--) {
        if (substr(num, i, 1) == 1) {
            val = val + 2 ^ (len - i)
        }
    }
    return val
}

# main loop
{
    # TODO: handle [sStT]
    gsub("[rwx]", 1)    # make it look binary
    gsub("-", 0)
    for(i = 0; i < 3; i++) {
        perm = perm conv(substr($0, i * 3 + 1, 3))    # convert the "bits" 3 at a time
    }
}

END {
    print perm
}
于 2010-07-08T01:09:03.807 回答
0

不同的实现ls,所以你ls也不是真正可移植的。

我会使用在任何 ANSI 标准 C 平台上编译的Lua以及应该在任何 POSIX 平台上开箱即用的Lua POSIX library来解决这个问题。在那里,您可以stat直接拨打电话并编写清晰的简单代码来进行算术运算。Lua 中的 Lua编程的精彩介绍可在线免费获得(适用于 Lua 的早期版本)。最后,如果您关心效率,结果将非常高效,部分原因是 Lua 速度很快,但主要是因为您可以在只 fork 一个进程(即 Lua 解释器)的情况下完成所有工作。

于 2010-07-08T01:32:47.070 回答