TCL/Expect - 如何生成 bash 并控制它或者为什么 expect clausule 看不到发送的 clausule 结果

TCL/Expect - How to spawn bash and control it OR why expect clausule does not see send clausule results

如何使用 Expect 控制 bash?我的 Expect 脚本如下所示:

#!/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"
  } 
}

但我总是得到这个由超时引起的输出:

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

我正在尝试 ls 的文件存在:

$ ls -1 db*
dbupgrade.log

PS:这是受this问题

的启发

Expect中,^$的意思非常不同:

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.

你可以这样做:

[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] #