无法在 expect 脚本中正确获取 "ps" 命令的输出
Not able to get output of "ps" command properly in expect script
我已经在下面复制了我的脚本。对于变量 "userName" 我没有在正确的地方得到预期的输出。预期的输出是 "pload",它在最后。对此有何正确建议?
脚本:
#!/usr/bin/expect
exp_internal 1
set timeout 30
set prompt {[$]}
spawn ssh -o StrictHostKeyChecking=no $username@$server.com
expect "assword"
send $password\r
expect "$prompt"
expect *
send "ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq\r"
expect -re "(.*)\n"
sleep 20
set userName $expect_out(buffer)
puts "buffer:$userName end"
if { $userName eq "pload" } {
send "sudo su - pload\r"
} else {
send "sudo su - pdev\r"
}
expect "assword"
send $password\r
expect "$prompt"
日志如下:
.
.
3997@fd0441a2:~\u0007\u001b[?1034h[f5103997@fd0441a2 ~]$"
expect: does " " (spawn_id exp4) match glob pattern "*"? yes
expect: set expect_out(0,string) " "
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) " "
send: sending "ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq\r" to { exp4 }
Gate keeper glob pattern for '(.*)
' is '*
'. Activating booster.
expect: does "" (spawn_id exp4) match regular expression "(.*)\n"? Gate "*\n"? gate=no
ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq
expect: does "ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq\r\n" (spawn_id exp4) match regular expression "(.*)\n"? Gate "*\n"? gate=yes re=yes
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq\r\n"
buffer:ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq
end
send: sending "sudo su - pdev\r" to { exp4 }
expect: does "" (spawn_id exp4) match glob pattern "assword"? no
pload
[f5103997@fd0441a2 ~]$
expect: does "pload\r\n\u001b]0;f5103997@fd0441a2:~\u0007[f5103997@fd0441a2 ~]$ " (spawn_id exp4) match glob pattern "assword"? no
sudo su - pdev
我建议对预期代码进行一些修改:
- 使用
expect -re
并使用模式。例如,提示设置为 [f5103997@fd0441a2 ~]$
,但要匹配的模式是 [$]
。 expect -re {.*$]\s*}
更好,IMO。
在第一次登录后立即将默认提示更改为已知值(没有任何 TCL 特殊字符(如 $
和 [
)。应该执行下一组命令顺利。我试过了,这是一个片段:
expect -re {.*[pP]assword}
send $password\r
expect -re "$prompt"
set newPrompt {MY_NEW_PROMPT> }
send "export PS1=\"$newPrompt\"\r"
expect -re ".*$newPrompt"
send "\r"
after 2000 ;# flush out the MOTD, etc.
expect -re ".*$newPrompt"
send "pwd\r"
expect -re ".*$newPrompt"
puts -->$expect_out(buffer)
send "exit\r"
输出:
sharad@sharad:~$ expect sharad.expect
spawn ssh -o StrictHostKeyChecking=no sharad@localhost
sharad@localhost's password:
export PS1="MY_NEW_PROMPT> "
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-53-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
175 packages can be updated.
4 updates are security updates.
export PS1="MY_NEW_PROMPT> "
Last login: Fri Dec 23 23:02:22 2016 from 127.0.0.1
sharad@sharad:~$ export PS1="MY_NEW_PROMPT> "
MY_NEW_PROMPT>
MY_NEW_PROMPT> pwd
/home/sharad
MY_NEW_PROMPT> -->pwd
/home/sharad
MY_NEW_PROMPT>
sharad@sharad:~$
我通常会在命令的输出周围放置一些特殊字符,这样编写 expect RE 会更容易一些。所以像这样尝试:
send "echo ==\">$(ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq)<\"==\r"
expect -re "==>(.*)<=="
set userName $expect_out(1,string)
# ^^^^^^^^
expect "$prompt"
我已经在下面复制了我的脚本。对于变量 "userName" 我没有在正确的地方得到预期的输出。预期的输出是 "pload",它在最后。对此有何正确建议?
脚本:
#!/usr/bin/expect
exp_internal 1
set timeout 30
set prompt {[$]}
spawn ssh -o StrictHostKeyChecking=no $username@$server.com
expect "assword"
send $password\r
expect "$prompt"
expect *
send "ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq\r"
expect -re "(.*)\n"
sleep 20
set userName $expect_out(buffer)
puts "buffer:$userName end"
if { $userName eq "pload" } {
send "sudo su - pload\r"
} else {
send "sudo su - pdev\r"
}
expect "assword"
send $password\r
expect "$prompt"
日志如下:
.
.
3997@fd0441a2:~\u0007\u001b[?1034h[f5103997@fd0441a2 ~]$"
expect: does " " (spawn_id exp4) match glob pattern "*"? yes
expect: set expect_out(0,string) " "
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) " "
send: sending "ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq\r" to { exp4 }
Gate keeper glob pattern for '(.*)
' is '*
'. Activating booster.
expect: does "" (spawn_id exp4) match regular expression "(.*)\n"? Gate "*\n"? gate=no
ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq
expect: does "ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq\r\n" (spawn_id exp4) match regular expression "(.*)\n"? Gate "*\n"? gate=yes re=yes
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq\r\n"
buffer:ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq
end
send: sending "sudo su - pdev\r" to { exp4 }
expect: does "" (spawn_id exp4) match glob pattern "assword"? no
pload
[f5103997@fd0441a2 ~]$
expect: does "pload\r\n\u001b]0;f5103997@fd0441a2:~\u0007[f5103997@fd0441a2 ~]$ " (spawn_id exp4) match glob pattern "assword"? no
sudo su - pdev
我建议对预期代码进行一些修改:
- 使用
expect -re
并使用模式。例如,提示设置为[f5103997@fd0441a2 ~]$
,但要匹配的模式是[$]
。expect -re {.*$]\s*}
更好,IMO。 在第一次登录后立即将默认提示更改为已知值(没有任何 TCL 特殊字符(如
$
和[
)。应该执行下一组命令顺利。我试过了,这是一个片段:expect -re {.*[pP]assword} send $password\r expect -re "$prompt" set newPrompt {MY_NEW_PROMPT> } send "export PS1=\"$newPrompt\"\r" expect -re ".*$newPrompt" send "\r" after 2000 ;# flush out the MOTD, etc. expect -re ".*$newPrompt" send "pwd\r" expect -re ".*$newPrompt" puts -->$expect_out(buffer) send "exit\r"
输出:
sharad@sharad:~$ expect sharad.expect
spawn ssh -o StrictHostKeyChecking=no sharad@localhost
sharad@localhost's password:
export PS1="MY_NEW_PROMPT> "
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-53-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
175 packages can be updated.
4 updates are security updates.
export PS1="MY_NEW_PROMPT> "
Last login: Fri Dec 23 23:02:22 2016 from 127.0.0.1
sharad@sharad:~$ export PS1="MY_NEW_PROMPT> "
MY_NEW_PROMPT>
MY_NEW_PROMPT> pwd
/home/sharad
MY_NEW_PROMPT> -->pwd
/home/sharad
MY_NEW_PROMPT>
sharad@sharad:~$
我通常会在命令的输出周围放置一些特殊字符,这样编写 expect RE 会更容易一些。所以像这样尝试:
send "echo ==\">$(ps aux | grep -v grep | tr ' ' '\n' | grep pload | uniq)<\"==\r"
expect -re "==>(.*)<=="
set userName $expect_out(1,string)
# ^^^^^^^^
expect "$prompt"