如何在bash中测试数组元素是否全部相等?

huangapple go评论60阅读模式
英文:

How to test if array elements are all equal in bash?

问题

我编写了一个脚本,用于检查轮组用户是否在允许用户列表中,如果是true,则将值0写入列表result,如果为false,则写入1。然后我找到了一段代码,用于检查结果列表中的所有值是否相同。我的问题是,当列表中没有用户时,它们都会得到1,这使得测试通过,但实际上应该失败。

我需要什么?需要代码审查帮助,以使测试适用于以下情况:

result=(所有成员都为0) 测试通过

result=(至少有一个成员为1) 测试失败

result=(所有成员都为1) 测试失败

#!/bin/bash
source ./colorama.conf

message="验证轮组成员"
wheel_members_list=(
    "username_01"
    "username_02"
    "username_03"
)

output=$(getent group wheel | awk -F: '{print $4}' | tr , '\n')
result=()

for username in $output; do
    if [[ ${wheel_members_list[@]} =~ (^|[[:space:]])$username($|[[:space:]]) ]]; then
        result+=(0)
    else
        result+=(1)
    fi
done

echo 状态: ${result[@]}

if [ "${#result[@]}" -gt 0 ] && [ $(printf "%s
#!/bin/bash
source ./colorama.conf

message="验证轮组成员"
wheel_members_list=(
    "username_01"
    "username_02"
    "username_03"
)

output=$(getent group wheel | awk -F: '{print $4}' | tr , '\n')
result=()

for username in $output; do
    if [[ ${wheel_members_list[@]} =~ (^|[[:space:]])$username($|[[:space:]]) ]]; then
        result+=(0)
    else
        result+=(1)
    fi
done

echo 状态: ${result[@]}

if [ "${#result[@]}" -gt 0 ] && [ $(printf "%s\000" "${result[@]}" | LC_ALL=C sort -z -u | grep -z -c .) -eq 1 ]; then
    echo 通过
    exit 0
else
    echo 失败
    exit 1
fi
0"
"${result[@]}" | LC_ALL=C sort -z -u | grep -z -c .) -eq 1 ]; then
echo 通过 exit 0 else echo 失败 exit 1 fi

编辑:目前我通过if条件解决了这个问题,但我会感激第一个版本的帮助。

for state in ${result[@]}; do
    if [ $state -eq 1 ]; then
        exit 1
    fi
done
exit 0

如果您有任何其他问题,请随时提出。

英文:

I wrote a script that checks if the user of the wheel group is on the list of allowed users, if true then writes the value 0 in the list result, if false then 1. Then I found a piece of code that checks if all values in the result list are the same. My problem is that when none of the users are on the list they all get 1 and this makes the test pass and it should fail

What do I need? Help with code review to make the test work for cases:

result=(all members are 0) test pass

result=(minimum one member has 1) test fail

result=(all members are 1) test fail

#!/bin/bash
source ./colorama.conf

message="verify group wheel members"
wheel_members_list=(
    "username_01"
    "username_02"
    "username_03"
    )
#echo ${wheel_members_list[@]}

output=`getent group wheel | awk -F: '{print $4}' | tr , '\n'`
#echo $output

result=()

for username in $output;do
    if [[ ${wheel_members_list[@]} =~ (^|[[:space:]])$username($|[[:space:]]) ]];then
        result+=(0)
    else
        result+=(1)
    fi
done

echo state: ${result[@]}

if [ "${#result[@]}" -gt 0 ] && [ $(printf "%s
#!/bin/bash
source ./colorama.conf
message="verify group wheel members"
wheel_members_list=(
"username_01"
"username_02"
"username_03"
)
#echo ${wheel_members_list[@]}
output=`getent group wheel | awk -F: '{print $4}' | tr , '\n'`
#echo $output
result=()
for username in $output;do
if [[ ${wheel_members_list[@]} =~ (^|[[:space:]])$username($|[[:space:]]) ]];then
result+=(0)
else
result+=(1)
fi
done
echo state: ${result[@]}
if [ "${#result[@]}" -gt 0 ] && [ $(printf "%s\000" "${result[@]}" | 
LC_ALL=C sort -z -u |
grep -z -c .) -eq 1 ] ; then
echo pass
exit 0
else
echo fail
exit 1
fi
0" "${result[@]}" | LC_ALL=C sort -z -u | grep -z -c .) -eq 1 ] ; then echo pass exit 0 else echo fail exit 1 fi

EDIT: for the moment i solved it with if condition, but i will appreciate help with the first version

for state in ${result[@]}; do
    if [ $state -eq 1 ]; then
        exit 1
    fi
done
exit 0

答案1

得分: 2

Since result is an array of only 0's and 1's, you can do this most efficiently by using pure bash:

if [[ "${result[*]}" =~ 1 ]]; then
    echo fail
else
    echo pass
fi

This way is less efficient but more in line with what you were trying, you just gotta use the fact that grep fails if it finds no match:

if printf "%s
if printf "%s\0" "${result[@]}" | grep -zq 1; then
    echo fail
else
    echo pass
fi
"
"${result[@]}" | grep -zq 1; then
echo fail else echo pass fi
英文:

Since result is an array of only 0's and 1's, you can do this most efficiently by using pure bash:

if [[ "${result[*]}" =~ 1 ]]; then
    echo fail
else
    echo pass
fi

This way is less efficient but more in line with what you were trying, you just gotta use the fact that grep fails if it finds no match:

if printf "%s
if printf "%s\0" "${result[@]}" |  grep -zq 1; then
echo fail
else
echo pass
fi
" "${result[@]}" | grep -zq 1; then echo fail else echo pass fi

huangapple
  • 本文由 发表于 2023年6月27日 18:32:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76563966.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定