3

I'm writing a script to configure new debian installs while finding the best solution to confirming that a user exists in the script, the best way I found gives me wierd output.

PROBLEM:

id -u $var and id -u $varsome give the same output even though var has a value (the username) and varsome has no value

[19:49:24][username] ~ ~↓↓$↓↓ var=`whoami`
[19:53:38][username] ~ ~↓↓$↓↓ id -u $var
1000
[19:53:42][username] ~ ~↓↓$↓↓ echo $?
0
[19:53:49][username] ~ ~↓↓$↓↓ id -u $varsome
1000
[19:09:56][username] ~ ~↓↓$↓↓ echo $?
0
[20:10:18][username] ~ ~↓↓$↓↓ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
Licens GPLv3+: GNU GPL version 3 eller senere <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[20:27:08][username] ~ ~↓↓$↓↓ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

I got the command from this question on stackoverflow: Check Whether a User Exists

QUESTIONS:

  • What is happening here?
  • Is there a better way you can find to verify a user exist's in a script?
  • Pointers on the script well appreciated
6
  • Try it with a username other than yours. Aug 14 '18 at 20:44
  • 1
    Presumably varsome is empty so id -u $varsome is the same as id -u Aug 14 '18 at 20:46
  • @steeldriver That's sound's very enlightening Aug 14 '18 at 20:51
  • @ikkachu Thank's for the edit, much cleaner like this Aug 14 '18 at 21:14
  • @somethingSomething, yeah, I meant to comment about the cleanup... I think the main thing about id was there in the first part. If you have some particular part of the script you're struggling with, do ask. But it maybe better placed in a separate question.
    – ilkkachu
    Aug 14 '18 at 21:24
9

Since the variable expansion wasn't quoted, the empty word that results from $varsome being expanded is removed completely.

Let's make a function that prints the number of arguments it gets and compare the quoted and non-quoted case:

$ args() { echo "got $# arguments"; }
$ var=""
$ args $var
got 0 arguments    
$ args "$var"
got 1 arguments

The same happens in your case with id: id -u $var is exactly the same as just id -u when var is empty. Since id doesn't see a username, it by default prints the current user's information.

If you quote "$var", the result is different:

$ var=""
$ id -u "$var"
id: ‘’: no such user

With that fixed, you can use id to find if a user exists. (We don't need the outputs here though, so redirect them away.)

check_user() { 
    if id -u "$1" >/dev/null 2>&1; then
        echo "user '$1' exists"
    else
        echo "user '$1' does not exist"
    fi
}
check_user root
check_user asdfghjkl

That would print user 'root' exists and user 'asdfghjkl' does not exist.


This is a bit of the inverse of the usual problems that come from the unexpected word splitting of unquoted variables. But the basic issue is the same and fixed by what half the answers here say: always quote the variable expansions (unless you know you want the unquoted behaviour).

See:

1
  • @ikkachu Thank you so much it was driving me crazy this wierd logic, great answer Aug 14 '18 at 21:21
1

The command id -u will give you the id of the current user. The command id -u user will give you the id of that user.

Now in your example, you use

var=`whoami`
id -u $var

The command whoami returns the current user. So id -u current_user will return the id of the current user, and id -u will also return the id of the current user.

Edit

Note that backticks are deprecated an it is recommended to write $(whoami) instead, for example:

var=$(whoami)
id -u $var
2
  • @RalfFriedl Thank you for the answer, yes this is true, but nothing new here, my point was that the variable that had no value was giving the same output Aug 14 '18 at 21:08
  • @somethingSomething Yes, and I explained why it gives the same output inyour case. If you already knew that, then what was the question?
    – RalfFriedl
    Aug 14 '18 at 21:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.