代替戦略を使用せずにGitインタラクティブCLIでExpectをどのように使用できますか?

代替戦略を使用せずにGitインタラクティブCLIでExpectをどのように使用できますか?

expect通常、次のメカニズムを使用できます。しかし、対話型シェルではこれは機能しないので。expectsendgitputs

シェルの通常の使用を復元する方法はありますか?それとも、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にはマージプロンプトの末尾に追加される代替出力があり、自動化が中断されます。

(.*)これは、次のヒント行の予想一致によるものです。

関連情報