0

How can I control bash with Expect? My Expect script looks like this:

#!/usr/bin/expect

# ENABLE DEBUGGING
exp_internal 1


set timeout 10
log_user 0

spawn bash -i
sleep 5
send "ls -1 db*\r"
expect {
  -re "^db.*$" {
    puts $expect_out(0,string)
  }

  timeout {
    send_error "Script has reached the 'timeout' branch\n"
  } 
}

But I always get this output which is caused by time out:

parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {4740}
send: sending "ls -1 db*\r" to { exp4 }
Gate keeper glob pattern for '^db.*$' is 'db*'. Activating booster.

expect: does "" (spawn_id exp4) match regular expression "^db.*$"? Gate "db*"? gate=no

expect: does "Agent pid 6228\r\nIdentity added: /home/wakatana/.ssh/id_rsa (/home/wakatana/.ssh/id_rsa)\r\n\u001b[?1034h\u001b]0;~/scripts\u0007\r\r\n\u001b[32mwakatana@ANTARES \u001b[33m~/scripts\u001b[0m\r\r\n$ ls -1 db*\r\n" (spawn_id exp4) match regular expression "^db.*$"? Gate "db*"? gate=yes re=no

expect: does "Agent pid 6228\r\nIdentity added: /home/wakatana/.ssh/id_rsa (/home/wakatana/.ssh/id_rsa)\r\n\u001b[?1034h\u001b]0;~/scripts\u0007\r\r\n\u001b[32mwakatana@ANTARES \u001b[33m~/scripts\u001b[0m\r\r\n$ ls -1 db*\r\ndbupgrade.log\r\n" (spawn_id exp4) match regular expression "^db.*$"? Gate "db*"? gate=yes re=no

expect: does "Agent pid 6228\r\nIdentity added: /home/wakatana/.ssh/id_rsa (/home/wakatana/.ssh/id_rsa)\r\n\u001b[?1034h\u001b]0;~/scripts\u0007\r\r\n\u001b[32mwakatana@ANTARES \u001b[33m~/scripts\u001b[0m\r\r\n$ ls -1 db*\r\ndbupgrade.log\r\n\u001b]0;~/scripts\u0007\r\r\n\u001b[32mwakatana@ANTARES \u001b[33m~/scripts\u001b[0m\r\r\n$ " (spawn_id exp4) match regular expression "^db.*$"? Gate "db*"? gate=yes re=no
expect: timed out
Script has reached the 'timeout' branch

File that I am trying to ls exists:

$ ls -1 db*
dbupgrade.log

PS: This was inspired by this question

Community
  • 1
  • 1
Wakan Tanka
  • 7,542
  • 16
  • 69
  • 122

1 Answers1

2

In Expect, the ^ and $ mean very differently:

Note that in many editors, the ^ and $ match the beginning and end of lines respectively. However, because expect is not line oriented, these characters match the beginning and end of the data (as opposed to lines) currently in the expect matching buffer.

You can do like this:

[STEP 101] # cat foo.exp
spawn bash --noprofile --norc
sleep 1
send "ls -1 db*\r"
expect {
    -re {[\r\n]+(db.*?)[\r\n]+} {
        send_user "\n>>> $expect_out(1,string) <<<\n"
    }
}
[STEP 102] # ls -1 dbupgrade.log
dbupgrade.log
[STEP 103] # expect foo.exp
spawn bash --noprofile --norc
bash-4.3# ls -1 db*
dbupgrade.log

>>> dbupgrade.log <<<
[STEP 104] #
pynexj
  • 19,215
  • 5
  • 38
  • 56
  • It _might_ work if you were to use this RE (here in Tcl-quoted form): `{(?n)^db.*$}` — the leading `(?n)` enables newline-sensitive matching. – Donal Fellows Feb 02 '15 at 15:16
  • 1
    @DonalFellows: Just tried `{(?n)^(db.*?)$}`. It almost worked but the result would include the `\r` char. So seems like `$` only considers `\n` chars. By the way I cannot easily remember this kind of advanced RE syntax. Usually I only use the simple RE syntax. :) – pynexj Feb 02 '15 at 15:21