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에는 병합 프롬프트 끝에 추가되는 대체 출력이 있어 자동화가 중단됩니다.
(.*)
이는 다음 힌트 줄의 예상 일치 때문입니다 .