【问题标题】:check owner permissions from file (multiple paths results) in bash script在 bash 脚本中检查文件的所有者权限(多路径结果)
【发布时间】:2020-06-02 11:43:42
【问题描述】:

朋友们, 我的脚本有问题。我试图找到 /bin/openssl 的完整路径,然后将结果保存到文件中并从文件路径中读取并检查权限和所有者。 但是在结果文件 /tmp/lista.txt 中,我有多个路径。如何制作一个脚本来读取和检查文件结果中的每个路径。 有什么想法吗?

#!/bin/sh


module_id="AV.1.8.2.1"
echo " === $module_id module === "

#MODULE BODY
find / -wholename "*bin/openssl" -print > /tmp/list.txt

file="/tmp/list.txt"
path=$(cat /tmp/list.txt)
os=$(uname)
permission_other_good=0



if [ -e $path ]
then
    if [ $os = "Linux" ]
    then
        gid_min=$(grep ^GID_MIN /etc/login.defs)
        gid_min_value=$(echo $gid_min | cut -d " " -f2)
        uid_min=$(grep ^UID_MIN /etc/login.defs)
        uid_min_value=$(echo $uid_min | cut -d " " -f2)
        sys_gid_max=$(grep ^SYS_GID_MAX /etc/login.defs)
        sys_gid_max_value=$(echo $sys_gid_max | cut -d " " -f2)
        sys_uid_max=$(grep ^SYS_UID_MAX /etc/login.defs)
        sys_uid_max_value=$(echo $sys_uid_max | cut -d " " -f2)
        user_uid=$(stat -c %u $path)
        user=$(stat -c %U $path)
        group_gid=$(stat -c %g $path)
        group=$(stat -c %G $path)
        permission_other=$(stat -c %A $path | cut -b 8-10)

        if [ -z $gid_min_value ]
        then
            gid_min_value=1000
        fi

        if [ -z $uid_min_value ]
        then
            uid_min_value=1000
        fi

        if [ -z $sys_gid_max_value ]
        then
            sys_gid_max_value=$((gid_min_value-1))
        fi 

        if [ -z $sys_uid_max_value ]
        then
            sys_uid_max_value=$((uid_min_value-1))
        fi
    fi        

    if [ $os = "AIX" ]
    then
        gid_min_value=$(cat /etc/security/.ids | cut -d " " -f4)
        sys_gid_max_value=$((gid_min_value-1))
        uid_min_value=$(cat /etc/security/.ids | cut -d " " -f2)
        sys_uid_max_value=$((uid_min_value-1))
        user_uid=$(istat $path | awk -F " " 'NR==3{print $2}' | cut -d "(" -f1)
        user=$(istat $path | awk -F " " 'NR==3{print $2}' | cut -d "(" -f2 | cut -d ")" -f1)
        group_gid=$(istat $path | awk -F " " 'NR==3{print $4}' | cut -d "(" -f1)
        group=$(istat $path | awk -F " " 'NR==3{print $4}' | cut -d "(" -f2 | cut -d ")" -f1)
        permission_other=$(istat $path | awk -F " " 'NR==2{print $2}' | cut -b 7-9)
    fi    

    if [ $permission_other = "r-x" ] || [ $permission_other = "r--" ] || [ $permission_other = "--x" ] || [ $permission_other = "---" ]
    then
        permission_other_good=1  
    fi

    if [ $user_uid -le $sys_uid_max_value ] && [ $group_gid -le $sys_gid_max_value ] && [ $permission_other_good -eq 1 ]
    then
        compliant="Yes"
        actual_value="user = $user group = $group permission = $permission_other"
    else
        compliant="No"
        actual_value="user = $user group = $group permission = $permission_other"
    fi
else
    compliant="N/A"
    actual_value="File $file does not exist"
fi

# SCRIPT RESULT

echo :::$module_id:::$compliant:::$actual_value:::
echo " === End of $module_id module === "

【问题讨论】:

    标签: linux bash scripting permissions


    【解决方案1】:

    由于您使用的是 bash,我建议您不要使用临时文件,因为它有很多由于文件系统而引起的警告(如果您的磁盘已满会发生什么?如果文件存在会发生什么?如果不存在会发生什么?对基目录有写权限?等等),并且由于将文件名存储在基于行的文本文件中的限制(尽管这不应该是查找 openssl 的问题)。

    如果要解析文件列表,这是一种常见且安全的方法:

    find / -wholename "*bin/openssl" -print0 | while IFS= read -r -d '' path
    do
      # Write your code here using the 'path' variable
    done
    

    但是因为您将变量存储在内部 for 循环中,由于findwhile 之间的管道操作,它们将被限制在循环的范围内。您可以改用进程替换来规避此问题:

    while IFS= read -r -d '' path
    do
      # Write your code here using the 'path' variable
    done < <(find / -wholename "*bin/openssl" -print0)
    

    这与前面的代码基本相同,只是变量范围不限于循环。

    PS。您将不得不在多个 openssl 路径上处理变量的分配。如果您只是在 for 循环中复制/粘贴代码,compliantactual_value 的值将保留循环中最后一条路径的信息,这可能不是您想要的。

    【讨论】:

      【解决方案2】:

      这就是在 bash 中逐行读取文件的方式

      #!/bin/bash
      inputfile="/tmp/list.txt"
      while IFS= read -r line
      do
        echo "do your stuff with $line"
      done < "$inputfile"
      

      【讨论】:

        【解决方案3】:

        最好的解决办法是把结果放到一个数组中,然后for

        declare -a my_paths
        
        my_paths=($(find / -wholename "*bin/openssl" -print 2>/dev/null))
        
        for my_path in "${my_paths[@]}"; do
        
        done
        

        【讨论】:

          猜你喜欢
          • 2011-12-16
          • 2010-11-11
          • 1970-01-01
          • 2022-10-13
          • 2015-12-02
          • 2016-06-05
          • 2021-05-31
          • 1970-01-01
          • 2018-02-19
          相关资源
          最近更新 更多