0

I need to run this cmd with an expect script:

    echo users.1.password=`grep %user% /etc/passwd | awk -F: '{print $2}'` >> /tmp/system.cfg.new

But it errors out because of the $2 in it. How do I fix this? I need the variable to only be visible to the device I am sending the cmd to.

Here is the full script for password change on UBNT equipment via script (works via ssh, but not as script because of $2):

    #!/usr/bin/expect
    set timeout 30
    #Edit for User
    set user user
    #Edit for Old Password
    set old oldpassword
    #Edit for New Password
    set new newpassword
    #get IP List from iplist.txt
    set f [open "/iplist.txt"]
    set data [read $f]
    close $f

     foreach line [split $data \n] {
            if {$line eq {}} continue
            spawn ssh $user@$line
            expect {
                    "assword:" {
                            send "$old\r"
                            expect {
                                    "assword:" {
                                                    close
                                                    continue
                                                    }}
                            expect {
                                    "*" {
                                            send "passwd $user\r"
                                            expect "assword:"
                                            send "$new\r"
                                            expect "assword:"
                                            send "$new\r"
                                            expect "*"
                                            send "grep -v users.1.password= /tmp/system.cfg > /tmp/system.cfg.new\r"
                                            expect "*"
                                            send "echo users.1.password=`grep $user /etc/passwd | awk -F: '{print $2}'` >> /tmp/system.cfg.new\r"
                                            expect "*"
                                            send "cp /tmp/system.cfg.new /tmp/system.cfg\r"
                                            expect "*"
                                            send "save && reboot\r"
                                            close
                                            continue
                                            }}}}
            expect {
                    "*" {
                            close
                            continue
                            }}
            expect eof
     }
Dinesh
  • 16,014
  • 23
  • 80
  • 122
Shane Becker
  • 41
  • 1
  • 1
  • 11
  • After login to SSH, are you trying to execute this command in the remote shell? – Dinesh Mar 06 '16 at 02:13
  • Correct. The %user% is actually replaced with $user as a expect variable, but I need the print $2 to only be visible to the remote shell. Been working on this script all day and this is the only thing (at least I think that is until I get a new error message) that is preventing me from having it work. – Shane Becker Mar 06 '16 at 02:24
  • I added the full code – Shane Becker Mar 06 '16 at 02:35

1 Answers1

0

You just have to escape the dollar sign with backslash.

send "echo users.1.password=`grep $user /etc/passwd | awk -F: '{print \$2}'` >> /tmp/system.cfg.new\r"

By the way, using expect * might be dangerous and not a recommended one unless a read need of it.

You could use the a generalized approach for the matching the prompt as,

set prompt "#|%|>|\\\$ $"

Here, we have escaped the literal dollar sign with backslash and the last dollar is meant for the end-of-line regular expression.

After sending any commands to the remote shell, you can expect for the pattern as

expect -re $prompt
Community
  • 1
  • 1
Dinesh
  • 16,014
  • 23
  • 80
  • 122
  • That fixed the error message. I was using "*" to force a timeout since sleep didn't seem to do the trick. The script works perfect (edited of course) for Mikrotiks, but still seems to get to Retype password: and closes the connection. You have any ideas on that? – Shane Becker Mar 06 '16 at 03:22
  • I am still at a loss for what is wrong with the script after the /$2 thing. It moves on to the new IP in the iplist.txt when prompted for New password: which expect "assword:" should handle. Even changing all expects to sleeps doesn't do it. Can you tell me what else is wrong with my code? – Shane Becker Mar 06 '16 at 04:17
  • I deselected as solution only because the it still errors out at this line. It fixes the first error, but doesn't actually allow the remote shell to use it. The cmd works fine if I actually ssh into the device and run it manually without expect script. I did some checking and this is still the line that errors out just with a different error. It does everything above this line so something is still wrong with grabbing the variable in the remote shell. – Shane Becker Mar 06 '16 at 15:06
  • Add `exp_internal 1` to your code and post the debug output. – Dinesh Mar 06 '16 at 16:25
  • Answer is right for this one. It goes through that line just fine. Issue is at send "save && reboot\r". Have another thread on this so we can just call this one answered and work in that one. – Shane Becker Mar 06 '16 at 17:14