"상태 비저장 토큰"을 사용하여 데이터 소비를 반복할 수 있는 간단한 서버 API를 고려하면 다음과 같습니다 rQAAMTQ2MzU4MDA1MjgxM3x8fC9wZXJtaWQub3JnfHx8
.
curl -v "http://ws.foo.bar/_consume?position=rQAAMTQ2MzU4MDA1MjgxM3x8fC9wZXJtaWQub3JnfHx8"
* Connected to ws.foo.bar (12.34.56.78) port 80 (#0)
> GET /_consume?position=rQAAMTQ2MzU4MDA1MjgxM3x8fC9wZXJtaWQub3JnfHx8 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: ws.foo.bar
> Accept: */*
>
< HTTP/1.1 200 OK
... many irrelevant headers
< X-POSITION: qwAAMTQ2MzU4MDA1MTIxOHx8fC9wZXJtaWQub3JnfHx8
< Connection: close
< Date: Wed, 01 Jun 2016 15:02:42 GMT
{ datadatadatadatadatadatadata... }
데이터를 stdout으로 출력하고 헤더(및 기타 세부 정보)를 stderr로 출력합니다. 헤더 중 하나는 X-POSITION
다음 데이터 청크에 대한 쿼리 매개변수로 제공해야 하는 다음 위치를 저장하는 것입니다. 버튼을 클릭하고 다시 실행하여 다음 데이터 덩어리를 검색할 수 있는 간단한 방법을 고안하려고 합니다.
나는 다음을 시도했습니다 (초기 위치를 가정 1foo2BAR3baz4QUUX5blah
:):
$ POS=1foo2BAR3baz4QUUX5blah
$ POS=$( curl -v "http://ws.foo.bar/_consume?position=$POS" 2>&1 | grep X-POSITION | awk '{print $3}' )
당연히 데이터를 삼키기 때문에 화면에 데이터가 인쇄되지 않으며 grep
, 게다가 POS
한 번만 변경되고 다시 사용할 수 없습니다. 두 번째 호출에서 컬은 다음과 같이 불평합니다.
* Illegal characters found in URL
* Closing connection -1
curl: (3) Illegal characters found in URL
POS는 새로운 가치를 얻은 것처럼 보이지만,
$ echo $POS
rQAAMTQ2MzU4MDA1MjgxM3x8fC9wZXJtaWQub3JnfHx8
아마 EOF일 것 같은데요?
어쨌든, 문제를 해결하더라도 여전히 stdout을 무시하고 싶지 않습니다. 시험을 마친이 솔루션:
$ POS=`( curl -v "http://ws.foo.bar/_consume?position=$POS" 3>&1 1>&2- 2>&3- ) | grep X-POSITION | awk '{print $3}'`
하지만 그것도 작동하지 않는 것 같습니다.
답변1
이것"결함 있는"매개변수의 문자는 $POS
EOL입니다. HTTP는 CRLF를 줄 종결자로 사용합니다. 예를 들어:
< X-POSITION: xxxxxxxx\r\n
그러면 필드 3 awk
이 xxxxxxxx\r
.
print
in을 사용하면 awk
마지막 개행 문자를 다시 도입할 수도 있지만 \n
표현식이 인용되지 않으므로 손실됩니다.
다음을 수행하여 이를 확인할 수 있습니다.
curl -v "http://ws.foo.bar/_consume?position=$POS" 2>&1 | cat -v
^M
줄 끝의 s는 을 나타냅니다 \r
.
또는:
printf "%s" "$pos" | xxd
00000000: 7251 4141 4d54 5132 4d7a 5534 4d44 4131 rQAAMTQ2MzU4MDA1
00000010: 4d6a 6778 4d33 7838 6643 3977 5a58 4a74 MjgxM3x8fC9wZXJt
00000020: 6157 5175 6233 4a6e 6648 7838 0d aWQub3JnfHx8.
마지막은 0d
CR입니다. (선택적으로 ascii
명령 프롬프트에서 실행할 수 있습니다.)
수학 자체만으로도 괜찮기 때문에 혼합할 필요도 없습니다 grep
.awk
awk
올바른 방향으로 나아가려면 다음이 시작일 수 있습니다.
pos=$(curl -v "http://foo.x/pos=$pos" 2>&1 | awk -vRS="\r\n" '/^< X-POSITION:/{printf "%s", $3}')
여기서 RS
또는 레코드 구분 기호는 awk
CRLF로 설정되어 있습니다.
...하지만 이는 콘텐츠가 아닌 토큰만 제공합니다.
실제로 내용을 화면에 인쇄할 필요는 없지만 내용을 파일에 저장하는 한 가지 방법은 다음과 같습니다.
pos=$(curl -sD - -o "$pos.out" "http://foo.x/?position=$pos" | awk -vRS="\r\n" '/^X-POSITION:/{printf "%s", $2}')
여기서는 헤더 데이터를 stdout
by 로 리디렉션 -D -
하고 내용을 file by로 저장합니다 -o "$pos.out"
.
이것의 또 다른 장점은 헤더 데이터만 구문 분석하면 된다는 것입니다.