How to write bash script for creating user on multiple Linux hosts?

getent is available on Linux, Solaris, BSD.
Not HP-UX, don't know about AIX.

Like the p-tools (pgrep, pkill, ptree, pargs, pfiles, ...),
getent simplifies debugging and shell scripting.

Seems nicer than niscat/ypcat !

BTW in the passwd|group|hosts-change case there is one reason for not using getent:
name service cache (nscd etc.) can obscure things. E.g. if an add-user script is re-run within the passwd cache time.
However, in the "files" case, nscd can see changes faster than the cache time...

Here is what I get if I put that modificatin of yours

RUID=`ssh $i  awk -F: '\$3=="'$UNIQUE'"' /etc/passwd` 
[root@GPGLNX02 test]# ./useradd.sh
awk: ==
awk: ^ syntax error

I even run it manually and it gives me a syntax error and the value that I am looking for

 `ssh HOSTXXX  awk -F: '\$3==2902' /etc/passwd`
awk: ==2902
awk: ^ syntax error

Strange seems to work fine for me on both AIX and Linux:

$ ssh HOSTXX awk -F: '\$3==0' /etc/passwd
root:x:0:0:root:/root:/bin/bash

Could the host system be Solaris? If so you may need nawk

My hosts are all rhel 4 and 5

How about using echo instead of awk?

$ ssh HOSTXX echo -F: '\$3==0' /etc/passwd
-F: $3==0 /etc/passwd

The error happens in `backticks`:

$ echo `ssh HOSTXX echo -F: '\$3==0' /etc/passwd`
-F: ==2902 /etc/passwd

`expression` differs from $(expression) here:

$ echo $(ssh HOSTXX echo -F: '\$3==0' /etc/passwd)
-F: $3==2902 /etc/passwd
1 Like

Is it usual to manage users by number manually across mny machines? People usually care more about the login user name id.

1 Like

Looks like three backslashes if backticks are used then:

RUID=`ssh $i  awk -F: '\\\$3=="'$UNIQUE'"' /etc/passwd`

or

RUID=$(ssh $i  awk -F: '\$3=="'$UNIQUE'"' /etc/passwd)
1 Like

Just a dum question.....

What does it mean by the $ sign infront of that bracket ()

Is that another way of assign the value of ssh..... to RUID

RUID=$(ssh $i  awk -F: '\$3=="'$UNIQUE'"' /etc/passwd)

Yes, most new shell versions support either $(command) or `command` command substitution styles. I feel the newer $() style is easier to read and looks much better when nested.

1 Like

Bang on

This works for me
RUID=$(ssh $i awk -F: '\$3=="'$UNIQUE'"' /etc/passwd)

One more thing is, the home directory still doesn't created remotely by the script

here is the line of useradd in my script.
Could some please have a second look
`ssh $i useradd -u "$UNIQUE" -d "$HOMEPATH" -p $(openssl passwd "$PASSWORD") -c "$ROLE" -m -k /etc/skel/ "$UNAME"`

$UNIQUE-uid
$HOMEPATH-/home/$UNAME
$UNAME-username
$PASSWORD-password in text

The following is the error when I run the script, says
home directory already exists, but I double check remote hosts, nothing exist prior to running script

[root@HOSTXX test]# ./useradd.sh
=====User ID is currently available on HOSTXY, ready to add new user=====
Warning: truncating password to 8 characters
Creating mailbox file: File exists
useradd: warning: the home directory already exists.
Not copying any file from skel directory into it.
==========User1 created==========
=====User ID is currently available on HOSTXZ ready to add new user=====
Warning: truncating password to 8 characters
==========User1 created==========

Yes, the $() is nicer, suggest the actual subshell, nests, and supports vi % end finder and similar GUI IDE tools. Just make your 'case' test entries not "xxx*)" as in old examples, but the perfectly legal and balanced "(xxx*)", so the % and such are not confused.

1 Like

Thank you for all your post

It really means alot to me and it gave me a good bash learning curve

One more thing is, the home directory still doesn't creates remotely by the script

here is the line of useradd in my script.

Could someone review and advise what I did wrong here?

`ssh $i useradd -u "$UNIQUE" -d "$HOMEPATH" -p $(openssl passwd "$PASSWORD") -c "$ROLE" -m -k /etc/skel/ "$UNAME"`

-m ? Man Page for useradd (opensolaris Section 1) - The UNIX and Linux Forums