通常,我可以使用后面跟着expect
的机制。然而,对于的交互式 shell,这不起作用,我必须使用.expect
send
git
puts
有什么技巧可以恢复shell的正常使用吗?或者这可能是 Mac 上的跨平台问题,而如果我在 Linux 机器上则不会存在?
#!/usr/bin/expect
# get the expected count
set ct [exec git status | grep -e {deleted by us:} | awk {END{print NR}}]
puts "expect count = $ct"
spawn bash
send "git mergetool\r"
for {set i 0} {$i < $ct} {incr i} {
expect -re "^.*local.: (.*)$"
set choice $expect_out(1,string)
set choice_letter [string index $choice 0]
expect -re ".*Use.*\?.*" { puts "$choice_letter\r" } # here I have to use puts, weird
}
这是一些奇怪的 mac 事情,还是我已经学会了正常的、常规的期望行为并且正确使用puts
而不是send
在这个自动脚本中?
答案1
我最终通过录制了一个期望宏autoexpect
。尽管结果autoexpect
非常字面化且脆弱,但我认为它会使发送机制正确。
#!/usr/bin/expect
# get the expected count
set ct [exec git status | awk {BEGIN{count=0} /deleted by us:|added by them:/{count++} END{print count}}]
if { $ct < 1 } { exit 0 }
# set write mode on all of the files
exec git status | grep -e {deleted by us:} -e {added by them:} | cut -d: -f 2 | xargs -n 1 chmod +w
set favor local
puts "favor: $favor"
puts "Deleted file count = $ct"
spawn bash
send "git mergetool\r"
for {set i 0} {$i < $ct} {incr i} {
expect -re "^.*$favor.: (\[a-z\]+)" {
set choice $expect_out(1,string) ;
set choice_letter [string index $choice 0] ;
}
expect -re "Use.*\? "
send "d\r"
expect "d\r"
}
expect -re ".*"
send -- "^D"
expect eof
新添加的内容在最后:
...
expect -re "Use.*\? "
send "d\r"
# this line caused things to start working
expect "d\r"
}
expect -re ".*". # expect the prompt here.
# The lack of specificity introduces a rare bug,
# ...but it is also simple and mostly works.
# this was in the autoexpect recording, and I left it in
# ...probably unnecessary
send -- "^D"
# this was also in autoexpect recording; might be important
expect eof
我的猜测是 git CLI 能够将操作限制在最后一秒,如果托管它的终端关闭,则操作实际上不会发生。因此,通过额外的调用等待结果expect
可能会确保操作发生。
在极少数情况下(我正在重新调整大约 2000 个与主分支历史记录断开的提交,因此大约 1/200),git 有一些替代输出,它会附加在其合并提示符的末尾,从而破坏自动化。
这是由于(.*)
下一行提示的预期匹配。