배경: 저는 AMCE.sh와 관리되는 네트워크 스위치 사이를 연결하기 위해 Expect를 사용하고 있습니다. 스위치에 SSH를 통해 로그인하고 명령을 실행할 수 있지만 스위치가 SSL 인증서를 관리하는 방식 때문에 매번 새 CSR을 생성해야 합니다. 명령을 실행하면 CSR이 다운로드 가능한 파일이 아닌 터미널에 나타납니다. ACME.sh에 공급할 수 있도록 CSR을 파일로 저장해야 합니다.
실제 문제:
Expect 스크립트에는 다음이 포함되어 있습니다. 그 목적은 스위치가 CSR을 파일로 내보낼 때 출력을 캡처 $csr
하고 마지막 줄이 들어올 때 캡처를 중지하는 것입니다.
send -- "command to generate CSR"
send -- "\r"
log_file -noappend $csr
expect -- "-----END CERTIFICATE REQUEST-----"
log_file
잘 작동하고 파일을 얻었습니다. 문제는 터미널에서 추가 쓰레기 더미를 얻는다는 것입니다(아래 잘린 예, 일반적으로 약 KB의 추가 쓰레기). 나는 grep`을 통해 이것을 공급하려고 시도했지만 sedz or
그들은 내가 추출하려는 것의 여러 줄 특성을 처리할 수 없는 것 같습니다.
^[[68;33Hc^[[68;33H^[[?25h^[~~~~~~*SNIP*~~~~~~[[?25h^[[68;1H^[[1;68r^[[68;1H-----BEGIN CERTIFICATE REQUEST-----^M
MIICoDCCAYgCAQAwWzEfMB0GA1UEAxMWc3dpdGNoMS5ob21lLmdvc3NldC51azENM^M
AsGA1UECxMEaG9tZTEPMA0GA1UECh~~~~~~*SNIP*~~~~~~3lsRknVNg/ZAATDaRC^M
KR3EIZFS3izUZ/+3wYzni84QZcp6s6HmDaB2moRRarVThXnbcF0a5nvGQtU8j7jP1^M
J/RPoWPRQa7vsfnEgN+gjQj6EYHeD/uMKzYPWeKEyQ4VPmw7K/VLySbMg==^M
-----END CERTIFICATE REQUEST-----^M
^[[1;68r^[[68;1H^[[68;1H^[[2K^[[68;1H^[[?25h^[[68;1H^[[68;1Hswitch1.home.domain.uk(config)# ^[[68;1H^[[68;33H^[[68;1H^[[?25h^[[68;33H
실행하면 cat test.csr
대부분의 파일을 깔끔하게 얻을 수 있지만 를 사용하여 필요한 것을 추출하려고 하면 sed
필요한 것과 일치하도록 얻을 수 없습니다. 내가 시도한 것의 예sed -E 's/([\s\S]*)(-----BEGIN CERTIFICATE REQUEST-----[\s\S]*-----END CERTIFICATE REQUEST-----)([\s\S]*)/\2/m;t;d' test.csr
[68;33Hc {end of command to generate CSR}
-----BEGIN CERTIFICATE REQUEST-----
MIICoDCCAYgCAQAwWzEfMB0GA1UEAxMWc3dpdGNoMS5ob21lLmdvc3NldC51azENM
AsGA1UECxMEaG9tZTE~~~~~~*SNIP*~~~~~~moRRarVThXnbcF0a5nvGQtU8j7jP1
J/RPoWPRQa7vsfnEgN+gjQj6EYHeD/uMKzYPWeKEyQ4VPmw7K/VLySbMg==
-----END CERTIFICATE REQUEST-----
간단히 말해서, 필요한 깔끔한 출력을 어떻게 얻을 수 있는지, 또는 sed
사후에 정리할 수 있는 다른 도구를 구하거나 다른 도구를 얻을 수 있는 방법은 무엇입니까?
답변1
정규식을 사용하여 원하는 패턴에 필요한 데이터를 캡처합니다.
send -- "command to generate CSR"
send -- "\r"
expect -re "(-+BEGIN CERTIFICATE REQUEST-+.+-+END CERTIFICATE REQUEST-+)"
그런 다음 캡처된 텍스트를 파일에 쓰고 캐리지 리턴을 제거합니다.
set csr_text [regsub -all {\r\n} $expect_out(1,string) {\n}]
set fh [open $csr w]
puts $fh $csr_text
close $fh
답변2
답변이 있기를 바라지 expect
만 그렇지 않은 경우 사후 처리에 awk를 사용할 수 있습니다.
$ awk '
BEGIN {
beg = "-----BEGIN CERTIFICATE REQUEST-----"
end = "-----END CERTIFICATE REQUEST-----"
}
{ sub(/\r$/,"") }
sub(".*"beg,beg),sub(end".*",end)
' file
-----BEGIN CERTIFICATE REQUEST-----
MIICoDCCAYgCAQAwWzEfMB0GA1UEAxMWc3dpdGNoMS5ob21lLmdvc3NldC51azENM
AsGA1UECxMEaG9tZTEPMA0GA1UECh~~~~~~*SNIP*~~~~~~3lsRknVNg/ZAATDaRC
KR3EIZFS3izUZ/+3wYzni84QZcp6s6HmDaB2moRRarVThXnbcF0a5nvGQtU8j7jP
J/RPoWPRQa7vsfnEgN+gjQj6EYHeD/uMKzYPWeKEyQ4VPmw7K/VLySbMg==
-----END CERTIFICATE REQUEST-----
나는 항상 플래그를 지원하기 위해 범위 표현식을 사용하지 말 것을 권장합니다(참조:https://stackoverflow.com/q/23934486/1745001) 하지만 다른 용도로는 절대 사용하지 않을 것이기 때문에 대체 무엇인지 알아냈습니다.