Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

switch user and execute expect script

Status
Not open for further replies.

woche

Programmer
Jan 16, 2002
25
CH
hi all

i'm trying to write some test driver for our application. i'd like to create scripts which allow me to switch user and from there on talk to the application as the user i've switched to. preferably i logon as every different user (i need several users with different permissions) necessary just once and connect to the application. after that, i send commands to the application as those different users. the problem is the following: i can switch user (su) in my expect script and i can connect to the application in a different script - BUT i cannot switch user and connect as this user in the same script.
hmmm..... must be missing something there...

------------------------------------------
#!/usr/local/bin/expect --

#set environment variables
....

#switch user and connect to application
spawn su - user1
expect "password."
send "my_pwd\r"
expect "user1: "
&quot;connect to application&quot; <- this is the part not working
<- i've tried &quot;source&quot;, &quot;exec&quot;
set user1 $spawn_id

spawn su - user2
expect &quot;password.&quot;
send &quot;my_pwd2\r&quot;
expect &quot;user2: &quot;
etc etc etc....

#later on
set spawn_id user1
&quot;send commands to application as user1&quot;

set spawn_id user2
&quot;send commands to application as user2&quot;
---------------------------------------------
thanks for your help!
woche
 
Try something like this instead:

Code:
#!/usr/bin/tclsh
package require Expect

#exp_internal 1

set prompt &quot;.*@.*&quot;
set re1 &quot;\[Pp\]as.*&quot;
set vrfycmd &quot;echo \$UID\r\n&quot;
set pfile &quot;progname&quot;
set static &quot;arguments to progname&quot;

proc getPasswd {msg} {
           stty -echo          
           send_user &quot;\n$msg&quot;
           set pass [gets stdin]
           stty echo
           return $pass
}


#main()
set timeout 35
        foreach pot {usernames} {
                    spawn -noecho su $pot
 
                    expect {

                             -i $spawn_id -re $re1 {
                                                    send &quot;[getPasswd &quot;Please enter your password for $pot:&quot;]\r&quot;
                                                    expect -re $prompt {
                                                                        send &quot;$vrfycmd\r\n&quot;
                                                                        expect -re $prompt {
                                                                                           send_user &quot;\n$expect_out(buffer)\n&quot;
                                                                                           send_user &quot;\nIs output acceptable(y/n)&quot;
                                                                                           set ans [gets stdin]
                                                                                           if {![string compare $ans &quot;y&quot;] == 0} {close $spawn_id ; continue}
                                                                                           send &quot;$pfile $static\r&quot;
                                                                                           expect -re $prompt {send_user &quot;\n$expect_out(buffer)\n&quot; ; close $spawn_id}                                                                                                                       
                                                                                           }
                                                                         }
                                                     }
                                }
                      };#end expect section

If this doesn't fix it for you then I'll need some more details.

Good Luck.
 
hei marsd

thanks!!
two things:
1. my application somehow doesn't accept my environment variables. it keeps telling me to set variable PCMSDB, even though i'v set it (tried: set env(PCMSDB) my_value; set PCMSDB my_value). retrieving PCMSDB with puts shows that the value is set correctly - nevertheless it doesn't work. i've set PCMSDB after i've switched user - just like it's possible in any other shell.

2. the problem with your approach is the following. different users do different things in a defined order - they depend on the actions taken by the other users and its not that user1 does his things and then he's done. he'll have to wait for user2 and user3 to do a part of their stuff and then its his turn again. i guess it could be done by supplying an input file containing <user> <command> and then loop through that input file and changing spawn_id as needed per user.

thanks a lot
woche
 
The first issue is directly related to the reason
why your original approach with exec failed.
That is, as I'm sure you figured out quickly, the
exec calls and variable changes are only done in
the calling scripts environment and not in the
spawned process.

You will have to manually set your variable by
sending the required command to your su process.
Something like this maybe.
Code:
send &quot;PCMSDB=\&quot;mypathhere\&quot;\r&quot;
send &quot;echo \$PCMSDB\r&quot;
expect -re $prompt {send_user $expect_out(buffer)}

Your second problem is going to require more work.
It seems to me that now you have an issue where you
need the same process instance running for all users
yet the only way to simulate this is by spawning three
different sessions with their own environments.
If the changes that each user commits aren't global
changes, but are session specific, it would be very
difficult, if not impossible, to do this.

OTOH, if changes made are not session specific:
Save the spawn_ids in a list.
Before or after you initialize the application
interface drop into interact and create a procedure
that allows you to switch back and forth between
users as you need to.
Code:
proc switch_me {list_ids} {
global spawn_id
  for {set x 0} {$x < [llength $list_ids]} {incr x} {
      send_user &quot;\nSwitch user to user[expr $x + 1](y\n): &quot;
      set a [gets stdin]
      if {[string compare $a &quot;y&quot;] == 0} {set spawn_id [lindex $list_ids $x]; return}
   }
}

#..and place something like this at the end of 
#your last expect arm.

interact {
            &quot;~XX&quot; {switch_me}
    }

Hope this helps.




 
hi
excellent - thanks!
actually i wasn't aware as quickly as you think (unfortunately) that my variable is only in the calling scripts environment. i thought that the exec would fork a new subshell which in turn would inherit the calling shells settings. well, there must be a reason why this is not so when exec'ing a command.
for the second point: yep, works like this.
finally i did in another way: save su in a spawned process, save spawn_id's and have the different spawn_id's execute the application with one command at a time in batch mode. userid and command to process come from a file taken as input - read in a loop.

thanks for your help!
woche

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top