Expect redirect stdin

10,056

You need to send the script you read on stdin to the remote host:

while {[gets stdin line] != -1} {
    send "$line\r"
}

# then you may have to send ctrl-D to signal end of stdin
send \004
Share:
10,056
multiholle
Author by

multiholle

Updated on September 18, 2022

Comments

  • multiholle
    multiholle over 1 year

    I'm running a script on a remote server like using this command:

    ssh root@host 'bash -s' < script.sh
    

    Now I'm trying to use expect to handle the password prompt. This is the script:

    #!/usr/bin/expect
    set cmd [lindex $argv 0]
    
    spawn -noecho ssh root@host $cmd
    
    expect {
      "password:" {
         send "password\r"
       }
    }
    

    If I run the script, it gives no output:

    ./ssh.exp 'bash -s' < script.sh
    

    I know that's not the way to use ssh without password, but this is not the question right here.


    UPDATE I tried the idea of glenn jackman with a simple script but it's not working. This is the script I'm using:

    #!/usr/bin/expect
    spawn ssh xxx@xxx
    
    expect "*?assword:*"
    send "pwd\r"
    
    send "echo hello world"
    

    This is the output I get:

    [xxx@xxx bin]$ expect -d my.exp
    expect version 5.43.0
    argv[0] = expect  argv[1] = -d  argv[2] = my.exp
    set argc 0
    set argv0 "my.exp"
    set argv ""
    executing commands from command file my.exp
    spawn ssh xxx@xxx
    parent: waiting for sync byte
    parent: telling child to go ahead
    parent: now unsynchronized from child
    spawn: returns {7599}
    
    expect: does "" (spawn_id exp6) match glob pattern "*?assword:*"? no
    xxx@xxx's password:
    expect: does "xxx@xxx's password: " (spawn_id exp6) match glob pattern "*?assword:*"? yes
    expect: set expect_out(0,string) "xxx@xxx's password: "
    expect: set expect_out(spawn_id) "exp6"
    expect: set expect_out(buffer) "xxx@xxx's password: "
    send: sending "pwd" to { exp6 }
    send: sending "echo hello world" to { exp6 }
    write() failed to write anything - will sleep(1) and retry...
    


    UPDATE I managed it to get my script to run. This is the result which works:

    #!/usr/bin/expect
    
    set user [lindex $argv 0]
    set host [lindex $argv 1]
    set pwd  [lindex $argv 2]
    
    spawn ssh $user@$host bash -s
    
    expect {
      "?asswor?: " {
        send "$pwd\n"
      }
    }
    
    while {[gets stdin line] != -1} {
        send "$line\n"
    }
    send \004
    
    expect {
      "END_TOKEN_OF_SCRIPT" {
        exit 0
      }
      default {
        exit 1
      }
    }