expect
通常、次のメカニズムを使用できます。しかし、対話型シェルではこれは機能しないので。expect
send
git
puts
シェルの通常の使用を復元する方法はありますか?それとも、Linuxシステムでは存在しないMacのクロスプラットフォームの問題かもしれませんか?
#!/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
私はExpectマクロを記録しました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にはマージプロンプトの末尾に追加される代替出力があり、自動化が中断されます。
(.*)
これは、次のヒント行の予想一致によるものです。