Search code examples
linuxbashsolaris

BASH syntax error at line 1: `then' unmatched


eval: syntax error at line 1: `then' unexpected

Hi, I am having issues with this particular loop and couldn't find a solution to it, any ideas why?

getent passwd | cut -f1 -d":" | sort -n | uniq -c |\ while read x ; do [ -z "${x}" ] && break set - $x if [ $1 -gt 1 ]; then gids=`getent passwd |\ nawk -F: '($1 == n) { print $3 }' n=$2 | xargs`     echo "Duplicate Group Name ($2): ${gids}" fi done

Solution

  • If you run the code through shellcheck and correct the errors which it shows (except for one problematic warning), the code will become:

    getent passwd | cut -f1 -d":" | sort -n | uniq -c |
    while read -r x ; do
      [ -z "${x}" ] && break
      set - $x
      if [ "$1" -gt 1 ]; then
        gids=$(getent passwd | nawk -F: '($1 == n) { print $3 }' n="$2" | xargs)
        echo "Duplicate Group Name ($2): ${gids}"
      fi
    done
    

    The code still seems to have issues, one of which is that it looks for duplicate user names but the print out claims that it found duplicate group names.

    I would suggest replacing the above with:

    getent passwd | awk -F: '{c[$1]++; uids[$1]=uids[$1]" "$3} END{for (name in c) if (c[name]>1) printf "Duplicate User Name (%s):%s\n",name, uids[name]}'
    

    How the awk code works

    In the output of getent passwd, the user name will be in field 1 and the user ID will be in field 3.

    • c[$1]++; uids[$1]=uids[$1]" "$3

      This counts the number of times that user name $1 occurs and saves the count in array c. It also saves the user ID, $3, associated with each name in array uids.

    • END{for (name in c) if (c[name]>1) printf "Duplicate User Name (%s):%s\n",name, uids[name]}

      After we have finished processing getent's output, this looks for user names for which the count is greater than 1 and prints the info.

    Multiline version of suggested code

    getent passwd | awk -F: '
        {
            c[$1]++
            uids[$1] = uids[$1] " " $3
        } 
    
        END{
            for (name in c) 
               if (c[name]>1) 
                   printf "Duplicate User Name (%s):%s\n", name, uids[name]
        }'