대체 전략을 사용하지 않고 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에는 병합 프롬프트 끝에 추가되는 대체 출력이 있어 자동화가 중단됩니다.

(.*)이는 다음 힌트 줄의 예상 일치 때문입니다 .

관련 정보