Using Expect for the first time

Hi All,

Using Linux server 18.04

Trying to understand EXPECT, so I created a script to add in new users.

The code below works without expect, and I can manually change the passwords for the new users.
However, if I use EXPECT (which is installed) to set passwords it creates the users but no passwords.

Both scripts are executable.

#!/bin/bash
#
# TP = a file with 3 usernames testa, testb & testc
# EXPECT is the expect script
TP=/home/user/test.txt
EXPECT=/home/user/exp.sh
ID=9050

while read PERSON
do
    useradd -m -d /home/$PERSON -g 1005 -u $ID -c "Test User" -s /bin/bash $PERSON
    $EXPECT
    passwd -f $PERSON
    ID=$((ID + 1))
done < "$TP"

Expect Script

#!/usr/bin/expect -f
#
# this expect script is used to set new users passwords
# the password will be forced to expire immediately after 
#
set timeout -1
spawn $env(SHELL)
expect -exact "Enter new UNIX password: "
send -- "letmein\r"
expect -exact "Retype new UNIX password: "
send -- "letmein\r"
expect eof

Output

# ./test_users.sh
": no such file or directory
passwd: password expiry information changed.
": no such file or directory
passwd: password expiry information changed.
": no such file or directory
passwd: password expiry information changed.

I take it this is something to do with expect, maybe I have not understood it correctly, maybe I am picking the wrong spawn... I am not sure, as I have never used it before, but what I have read seems I have most of it correct.

Could someone point me in the right direction?

Hi,

I do this using two quickly hacked together scripts as follows - please bear in mind that these scripts are running on Solaris 11 and things are done this way to avoid a problem. But the scripts should be easily adaptable.

Script 1

for USER in `cat $DATADIR/name_list.txt | awk -F: '{ print $1 }'`
        do
if [ ! -d /export/home/${USER} ]
        then
                echo "The home directory for ${USER} does not exist - create."
                mkdir -p /export/home/${USER}
                if [[ $? -eq "0" ]]
                then
                        useradd -c"XXX Support User" -d/export/home/${USER} ${USER}
                        if [[ $? -eq "0" ]]
                        then
                                echo "Account for user ${USER} Created."
                        else
                                echo "Accounr for user ${USER} could not be created."
                        fi
                else
                        echo "The Account for ${USER} either already exists or could not be setup."
                fi

                echo "Setting the ownership for /export/home/${USER}"
                chown ${USER}:staff /export/home/${USER}
                if [[ $? -eq "0" ]]
                then
                        echo "The ownership of /export/home/${USER} wasx successfully set."
                else
                        echo "There was a problem setting the ownership on /export/home/${USER}"
                fi
                echo "Setting the password for ${USER}"
                echo ${USER} >> $DATADIR/added_users.txt
                ${BINDIR}/set_pw.sh ${USER} Ch4ng3me
        else
                echo "The user ${USER} already exists."
fi
done

Script 2

#!/usr/bin/expect

set username [lindex $argv 0];
set newpass [lindex $argv 1];


# opem shell
spawn $env(SHELL)
# send passwd command
send "passwd $username\n"
expect "New Password:"
send "$newpass\n"
expect "Re-enter new Password:"
send "$newpass\n"
expect eof"
expect "# "
send "exit\n"

I would suggest that you modify the expect script to suit your environment and call it from your main script passing the variables as I do - it's easier that way I think.

Regards

Gull04

1 Like

Hi Gull04,

in your main script I see that this is calling the expect script, with username & password

${BINDIR}/set_pw.sh ${USER} Ch4ng3me

And looking at your expect code
it is taking the username and password from the args you passed from your script to the expect script.

so amending my expect script then running my users script... I still get

 ": no such file or directory

but looking at your expect script I see a random " at the eof, is this meant to be there without a closing "???

Hi,

Having a quick look, if you use the -f switch. Then I think that /usr/bin/expect -f ${expect_commands_file} is what is expected.

If you create an expect script starting #!/usr/bin/expect containing the code - think that you'll get on better - also I'd be tempted to make an explicit call to it and to put some error checking in the control script.

Regards

Gull04

1 Like

Tried changing this, and i now get an error:

./test_users.sh: /home/user/exp.sh: /usr/bin/expect^M: bad interpreter: No such file or directory

All files are in /home/user/ directory.

I have removed the shebang line on exp.sh and recreated it, but to no avail.

I have also added in echo lines in the main script and these show fine before the expect and after the expect... so it must be this that is wrong

Hi,

I'm afraid I have to go offline shortly for about six hours, but you can try the following and see how it goes.

If you modify my expect script, with your system returns then execute the script against a manually created user account - passing it the username and a password. You will be able to tell if the expect code is correct, you can also check the path to expect with which expect .

Where are you editing the files as ^M suggests notepad or similar.

Regards

Gull04

Hi Gull04,

Being offline is fine... I will e going to site now anyway then not back until monday.

I copied the file from windows to Linux, but then I created a new one in vi on linux server.
I will create your expect file and test that on Monday.

thanks for your help.