1

I am trying to write a shell script to list all the users who have id 101

       #!/bin/bash
       who="$(who | cut -d ' ' -f 1 | sort -u )";                                 
       #Save the output of who
       for user in ${who}; do                          # Iterate over $@
          if [ $(echo id -g $user) ==  "101" ] ; then
             echo "Got it";
          fi
       done;

when i execute my script I get this error "line 4: [: too many arguments". I am not sure where I made mistake.

3
  • 2
    Did you try $(id -g $user)? Not sure why you need the echo there. The result of the command should be sufficient, I think.
    – KevinO
    Apr 16, 2018 at 15:45
  • 1
    another thing is don't use commands as Variable's name who=... Apr 16, 2018 at 15:47
  • For that specific script, you're missing the ; to close the for loop after the fi
    – tachomi
    Apr 16, 2018 at 16:11

4 Answers 4

1

Why not look directly at /etc/group?

awk -F: '$3==101 { print $4 }'

If getent is available on your host, you can do this to get a list pulled from /etc/passwd which is then chewed on:

awf -F: '{print $1}' <(getent group 101)
5
  • Or gentent group...
    – Jeff Schaller
    Apr 16, 2018 at 16:00
  • getent may not always be available on all POSIXes (e. g. MacOS), while /etc/group is easily parseable and should nearly always exist.
    – DopeGhoti
    Apr 16, 2018 at 16:03
  • count AIX in there with not having getent, either. Just wanted to round out your answer.
    – Jeff Schaller
    Apr 16, 2018 at 16:04
  • Thanks but for some reason, it did not work. I got it work now
    – Samun
    Apr 16, 2018 at 16:12
  • On macOS, /etc/group isn't the "real" groups list, just a stub that's used during boot and in single-user mode; the real list is in /var/db/dslocal/nodes/Default/groups/*.plist (and maybe in an LDAP server if it's bound to a domain, etc). So I really can't recommend using /etc/group if you're looking for compatibility. Apr 16, 2018 at 18:57
1

The error comes from the fact that $( echo id -g $user ) will be expanded into the words id -g username. This can not be compared to 101 since the expansion is unquoted.

To compare the output of id -g "$user" (note the double quotes), use

if [ "$( id -g "$user" )" = "101" ]

Within [ ... ] you should use a single = to do string comparison. In shells that have [[ ... ]] you may use ==:

if [[ $( id -g "$user" ) == "101" ]]

Here, the quoting of the command substitution is not required, but it is if you use [ ... ].


The idiomatic way to do this sort of task is not to store the output of the who pipeline in a variable, but to pass it directly to the loop:

who | awk '{ print $1 }' | sort -u |
while read user; do
    if [ "$( id -g "$user" )" = "101" ]; then
        echo 'Got it'
    fi
done
0

I believe changing the line to be:

if [ $(id -g $user) == "101" ]; then

will solve the issue. The original command had an echo in the output, which I believe is not needed.

0

Use getent to query the password database:

getent passwd 101

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .