다음 대화형 스크립트를 고려해보세요.
#!/usr/bin/env bash
set -eu
while true; do
read -p '> '
if [ "$REPLY" == quit ]; then
break
fi
echo "'$REPLY'"
done
expect
이제 나는 그것과 상호 작용 하고 싶습니다 :
#!/usr/bin/env bash
set -eu
echo '
spawn ./1.sh
expect >
send cmd1\n
expect {\n> }
send quit\n
' | expect -d
하지만 실행하면 다음과 같이 표시됩니다.
...
expect: does " cmd1\r\n'cmd1'\r\n> " (spawn_id exp6) match glob pattern "\n> "? no
expect: timed out
send: sending "quit\n" to { exp6 }
왜 일치하지 않습니까? 새로운 프롬프트(명령 완성)의 출현을 어떻게 감지하나요?
답변1
언어에서는 expect
tcl
문자열을 사용하는 것과 인용하는 것에는 차이가 있습니다. 다음 두 가지 예에서 이를 확인할 수 있습니다.""
{}
$ expect -c 'puts "a\nb"'
a
b
~ $ expect -c 'puts {a\nb}'
a\nb
glob 패턴은 {\n> }
일치하지만 \n
특별히 이스케이프된 것으로 해석되지 않는 4개의 문자로 구성됩니다. 패턴을 사용하면 "\n> "
일치 항목이 작동합니다. 또는 기본 glob 패턴 대신 플래그를 사용할 수 -re
있으며 두 문자는 정규식 코드에 의해 이스케이프 문자로 해석됩니다 -re {\n> }
.
답변2
너무 길어요.로고를 추가하세요 -ex
.
여기서 중요한 것은expect
일을 더 쉽게 만들어라일부 명령( expect
/ interact
)에 복잡한 매개변수를 전달합니다.
단일 목록에 포함된 인수(변형 및 상호 작용 예상)를 허용하는 명령은 경험적 방법을 사용하여 목록이 실제로 하나의 인수인지 여러 인수인지를 결정합니다. 목록이 실제로 단일 인수를 나타내고 해당 인수 사이에 공백이 아닌 문자가 포함된 \n이 여러 개 포함된 경우에만 경험적 방법이 실패합니다. 그럴 것 같지는 않지만 "-nobrace" 매개변수를 사용하면 개별 인수를 단일 인수로 처리하도록 강제할 수 있습니다. 아마도 이것은 기계 생성된 Expect 코드와 함께 사용될 수 있을 것입니다. 마찬가지로 -brace는 단일 인수가 여러 모드/작업으로 처리되도록 강제합니다.
(expect 명령 설명에서) 전체 Expect 문의 매개변수에 두 줄 이상이 필요한 경우, 각 줄이 백슬래시로 끝나는 것을 방지하기 위해 모든 매개변수를 한 줄로 "중괄호"로 묶을 수 있습니다. 이 경우 중괄호에도 불구하고 일반적인 Tcl 대체가 여전히 발생합니다.
여기에 예를 들어 보겠습니다.
#!/usr/bin/env bash
set -eu
f() {
echo line 1
sleep 1
echo line 2
}
export -f f
echo '
spawn bash -c f
expect {
{line 1} {puts 1}
{line 2} {puts 2}
}
expect \
{line 1} {puts 1} \
{line 2} {puts 2}
' | expect
산출:
spawn bash -c f
line 1
1
line 2
2
내가 찾은 저장소에서,경험적최신 커밋(2014년 5월)에서는 다음과 같습니다.다음과 같이: 인수가 전달되고 첫 번째 비공백 문자 앞에 개행 문자가 있는 경우 인수는 하나로 묶인 여러 인수로 간주됩니다.