-1

I am using below code to ssh to different nodes and find if an user exists or not. If the user doesn't exist it will create it.

The script works fine if I don't do ssh but it fails if I do ssh.

How can I go through different nodes using this script?

for node in `nodes.txt`
usr=root

ssh $usr@$node 
do
if [ $(id -u) -eq 0 ]; then
    read -p "Enter username : " username
    read -s -p "Enter password : " password
    egrep "^$username" /etc/passwd >/dev/null
    if [ $? -eq 0 ]; then
        echo "$username exists!"
        exit 1
    else
        pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
        useradd -m -p $pass $username
        [ $? -eq 0 ] && echo "User has been added to system!" || echo "F
ailed to add a user!"
    fi
else
    echo "Only root may add a user to the system"
    exit 2
fi
done
1
  • Why are you adding the user without home folder? Try to create the user without -m flag in the useradd command. Commented Mar 13, 2017 at 12:43

2 Answers 2

1

Your script has grave syntax errors. I guess the for loop at the beginning is what you attempted to add but you totally broke the script in the process.

The syntax for looping over lines in a file is

while read -r line; do
    .... # loop over "$line"
done <nodes.txt

(or marginally for line in $(cat nodes.txt); do ... but this has multiple issues; see http://mywiki.wooledge.org/DontReadLinesWithFor for details).

If the intent is to actually run the remainder of the script in the ssh you need to pass it to the ssh command. Something like this:

while read -r node; do
   read -p "Enter user name: " username
   read -p -s "Enter password: "
   ssh root@"$node" "
       # Note addition of -q option and trailing :
       egrep -q '^$username:' /etc/passwd ||
       useradd -m -p \"\$(perl -e 'print crypt(\$ARGV[0], \"password\")' \"$password\")" '$username'" </dev/null
done <nodes.txt

Granted, the command you pass to ssh can be arbitrarily complex, but you will want to avoid doing interactive I/O inside a root-privileged remote script, and generally make sure the remote command is as quiet and robust as possible.

The anti-pattern command; if [ $? -eq 0 ]; then ... is clumsy but very common. The purpose of if is to run a command and examine its result code, so this is better and more idiomatically written if command; then ... (which can be even more succinctly written command && ... or ! command || ... if you only need the then or the else part, respectively, of the full long-hand if/then/else structure).

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your reply. issue is not with the loop. issue is i am not able to ssh on diff nodes and perform the task that were written in the script.
Then your question is unclear/too broad. Editing the question significantly at this point may be inadvisable; perhaps simply post a new question with a proper minimal reproducible example, though it's likely to be a duplicate of an existing question.
See the Stack Overflow bash tag wiki for some common FAQs.
0

Maybe you should only do the remote tasks via ssh. All the rest runs local.

ssh $user@$node egrep "^$username" /etc/passwd >/dev/null

and

ssh $user@$node useradd -m -p $pass $username

It might also be better to ask for username and password outside of the loop if you want to create the same user on all nodes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.