stdout을 수정하지 않고 stderr 출력을 변수에 저장하고 이 작업을 반복합니다.

stdout을 수정하지 않고 stderr 출력을 변수에 저장하고 이 작업을 반복합니다.

"상태 비저장 토큰"을 사용하여 데이터 소비를 반복할 수 있는 간단한 서버 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

이것"결함 있는"매개변수의 문자는 $POSEOL입니다. HTTP는 CRLF를 줄 종결자로 사용합니다. 예를 들어:

< X-POSITION: xxxxxxxx\r\n

그러면 필드 3 awkxxxxxxxx\r.

printin을 사용하면 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.

마지막은 0dCR입니다. (선택적으로 ascii명령 프롬프트에서 실행할 수 있습니다.)

수학 자체만으로도 괜찮기 때문에 혼합할 필요도 없습니다 grep.awkawk

올바른 방향으로 나아가려면 다음이 시작일 수 있습니다.

pos=$(curl -v "http://foo.x/pos=$pos" 2>&1 | awk -vRS="\r\n" '/^< X-POSITION:/{printf "%s", $3}')

여기서 RS또는 레코드 구분 기호는 awkCRLF로 설정되어 있습니다.

...하지만 이는 콘텐츠가 아닌 토큰만 제공합니다.

실제로 내용을 화면에 인쇄할 필요는 없지만 내용을 파일에 저장하는 한 가지 방법은 다음과 같습니다.

pos=$(curl -sD - -o "$pos.out" "http://foo.x/?position=$pos" | awk -vRS="\r\n" '/^X-POSITION:/{printf "%s", $2}')

여기서는 헤더 데이터를 stdoutby 로 리디렉션 -D -하고 내용을 file by로 저장합니다 -o "$pos.out".

이것의 또 다른 장점은 헤더 데이터만 구문 분석하면 된다는 것입니다.

관련 정보