简体   繁体   English

用于循环的 shell 脚本中的多个条件

[英]Multiple conditions in a shell script for loop

I'm trying to loop through 2 groups on macOS and remove users in the admin group if they don't exist in another group.我正在尝试遍历 macOS 上的 2 个组,并删除 admin 组中的用户,如果他们不存在于另一个组中。

newadmins=$(dscl . -read Groups/newadmin GroupMembership | cut -c 18-)
adminUsers=$(dscl . -read Groups/admin GroupMembership | cut -c 18-)

for (user in $adminUsers && ! user in $newadmins)
do
        dseditgroup -o edit -d $user -t user admin
        if [ $? = 0 ]; then echo "Removed user $user from admin group"; fi
    else
        echo "Admin user $user left alone"
    fi
done

The above didn't work.以上没有奏效。 I think I'm confusing shell with other languages.我想我将 shell 与其他语言混淆了。 Any help would be appreciated.任何帮助,将不胜感激。 Thank!谢谢!

I would consider doing something like this:我会考虑做这样的事情:

#!/usr/bin/env bash

set -eu

NEW_ADMIN_USERS=$(dscl . -read Groups/newadmin GroupMembership | cut -d ' ' -f 2-)
ADMIN_USERS=$(dscl . -read Groups/admin GroupMembership | cut -d ' ' -f 2-)

DEFUNCT_ADMIN_USERS=$(grep -vxFf <(echo ${NEW_ADMIN_USERS} | tr ' ' '\n') <(echo ${ADMIN_USERS} | tr ' ' '\n'))

for DEFUNCT_ADMIN_USER in ${DEFUNCT_ADMIN_USERS}
do
  if dseditgroup -o edit -d ${DEFUNCT_ADMIN_USER} -t user admin
  then
    echo "Removed user ${DEFUNCT_ADMIN_USER} from admin group"
  else
    echo "Admin user ${DEFUNCT_ADMIN_USER} left alone"
  fi  
done

The main thrust of this is using the grep command put forward by @Jetchisel with process substitution ( <() ) to prepare a list of admin users in the ADMIN_USERS variable but not in the NEW_ADMIN_USERS variable, then iterating over that variable.其主要推动力是使用@Jetchisel 提出的grep命令和进程替换( <() ) 在ADMIN_USERS变量中准备一个管理员用户列表,但不在NEW_ADMIN_USERS变量中,然后迭代该变量。

This departs from your approach in a number of ways:这在很多方面都与您的方法不同:

  • setting the errexit and nounset options which will cause the script to exit on any error code from a command, including use of unset variables ( set -eu ) 设置errexitnounset选项,这将导致脚本在命令中出现任何错误代码时退出,包括使用未设置的变量( set -eu
  • using the field argument of cut with delimiter set to space when parsing the output of dscl ( cut -d ' ' -f 2- )在解析dscl的输出时使用cutfield参数,分隔符设置为空格( cut -d ' ' -f 2-
  • subsequently splitting the list of users into lines with tr ( tr ' ' '\\n' )随后将用户列表分成带有tr ( tr ' ' '\\n' ) 的行
  • passing the list through to for as appropriate (using ( was a syntax error, as I suspect the use of ! would be)适当地将列表传递给for (使用(是语法错误,因为我怀疑使用!将是)
  • evaluating the return code of dseditgroup directly as that is what if is testing for直接评估dseditgroup的返回码,因为这就是if测试的结果
  • removing the trailing fi for the first if command, as it's not needed when you have the else (and would cause a syntax error due to an apparent floating else )删除第一个if命令的尾随fi ,因为当你有else时不需要它(并且由于明显的浮动else会导致语法错误)

Please test thoroughly, preferably with a dummy command instead of dseditgroup before you're 100% happy that this works as expected, and consider setting the xtrace option ( set -x which will echo all the commands as they are executed), while developing.请彻底测试,最好使用虚拟命令而不是dseditgroup然后您才能 100% 满意它按预期工作,并考虑在开发时设置xtrace选项( set -x将在执行时回显所有命令)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM