bash/expect 스크립트에서 "상호작용"이 예상대로 작동하지 않습니다.

bash/expect 스크립트에서 "상호작용"이 예상대로 작동하지 않습니다.

내장 장치를 구성하려면(예: 플래시 메모리에 이미지 쓰기) 부팅 단계에서 잘 알려진 일련의 명령을 입력해야 합니다. 알고리즘은 다음과 유사합니다.

  • 시작하는 동안 아무 키나 입력하여 부트로더 셸을 캡처하세요.
  • 플래시 이미지 A
  • 플래시 이미지 B
  • ...
  • 계속 부팅(새 이미지 사용)

부팅 중 어느 시점에서 먼저 부트로더 셸을 캡처해야 하기 때문에 expect스크립트를 적용하면 이 문제가 잘 해결될 것이라고 생각합니다. 나반품연결할 장치 노드 등에 대한 논리를 구현하기 위해 다른 bash 명령을 혼합하고 싶습니다. 내가 생각해낸 것은 (예상되는 부분만) 다음과 같습니다.

#!/bin/bash
DEVICE=...
FLASH_CMD_A=...
#Other bash stuff

expect <<SCRIPT
    set timeout 5
    spawn plink -serial -sercfg 115200,8,n,1 $DEVICE 

    expect "Hit any key to stop autoboot"
        sleep 1
        send "\r"

    expect "=>"
        sleep 1
        send "$FLASH_CMD_A\n"

    interact   
SCRIPT

echo "Done!"

내가 관찰한 것은 첫 번째 예상 줄이 올바르게 캡처되고 절전 모드가 작동하며 줄 바꿈이 전송되는 것으로 보입니다. 다음 기대(힌트 잡기)와 이에 상응하는 수면도 작동하는 것 같습니다. send 명령($FLASH_CMD_A)은 단어 사이에 많은 공백이 포함되어 터미널에 인쇄되지만 작동하는 것 같습니다.

가장 큰 문제는 그들이 interact아무것도 하지 않는 것 같다는 것입니다. 두 번째 기대/전송이 실행되면 bash 쉘로 돌아가서 "Done!"이 stdout에 인쇄되는 것을 전혀 볼 수 없습니다. 또한 대화형 구문을 사용해 보았습니다.

interact {
    "=>"{
        send "\r"
        exp_continue
    }
}

하지만 소용없어별말씀을요. 프롬프트는 포착되지 않으며 마치 해당 interact명령문이 존재하지 않은 것처럼 스크립트가 즉시 종료됩니다. 내가 뭘 잘못하고 있는지에 대한 아이디어가 있습니까? 나는 가지고있다:

expect -v
expect version 5.45

비록 주문은~인 것 같다장치에 전달되는지 알 수 없습니다. bash 셸로 돌아가면 이 명령을 따르는 장치의 모든 출력이 손실됩니다. 그러나 스크립트를 두 번째로 실행하면 예상 텍스트 버퍼( expect_out?)가 덤프되고 즉시 종료되는 것 같습니다. 흥미롭게도 이전에 보낸 명령의 출력이 이 버퍼 덤프에 포함될 것으로 예상했습니다.

참고: 가상 머신 환경에서 동일한 스크립트를 시도했지만 "예상된" 문 중 어느 것도 포착되지 않았습니다. 모든 입력이 stdout으로 인쇄되어 전달되었습니다.

답변1

이 문제를 해결하려면 표준 입력 대신 파일에서 Expect 스크립트를 실행하세요.

#!/bin/sh

BLAH='echo hi'

ESCRIPT=`mktemp runner.XXXXXXXXXX` || exit 1

# nope
#expect -d - <<SCRIPT
cat >$ESCRIPT <<SCRIPT
  set timeout 5
  spawn $SHELL
  # FIXME whatever your prompt looks like
  expect -ex "% "
  send -raw "\r"
  expect -ex "% "
  send -- "$BLAH\n"
  expect -ex "% "
  interact
SCRIPT

expect -d $ESCRIPT

echo alas poor $SHELL I knew him well a man of infinit

# and probably also `trap` in the event this code gets whapped with an INT
# or something...
rm $ESCRIPT

관련 정보