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に出力します。ヘッダーの1つは、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一度だけ変更され、再利用できません。 2番目の呼び出しでは、カールは次のように文句を言います。

* 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

その後、フィールド3awkxxxxxxxx\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コマンドプロンプトから実行できます。)

数学自体だけでも大丈夫なので、混合する必要もありませんgrepawkawk

正しい方向に進むには、次のものが始まります。

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

ここでRS、またはレコード区切り文字はawkCRLFに設定されています。

...しかし、これはコンテンツではなくトークンのみを提供します。

実際にコンテンツを画面に印刷する必要はありませんが、コンテンツをファイルに保存する1つの方法は次のとおりです。

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

ここでは、ヘッダーデータをstdoutbyにリダイレクト-D -し、内容をファイルbyとして保存します-o "$pos.out"

これのもう一つの利点は、ヘッダーデータを解析するだけです。

関連情報