Httpie: Option zum Ignorieren von stdin-Daten hinzugefügt

Erstellt am 23. Juli 2013  ·  15Kommentare  ·  Quelle: httpie/httpie

http: error: Request body (from stdin or a file) and request data (key=value) cannot be mixed.

Dieser Fehler ist eher kryptisch. Ich schreibe ein Shell-Skript, um mit einer Rest-API zu interagieren, und ich mache das:

http --output subnet --pretty format --form post "${URLHOST}subnets" "cidr=${cidr}" "name=${name}" "description=${name}" "availabilityZoneId=${az}" "networkId=${VPCid}" "$ACCESSKEY" "$SECRETKEY" "$ACCOUNTID" "_providerId=aws" "_regionId=${REGION}"

Was erzeugt (wenn 'echo' vorangestellt ist, ein Befehl, der perfekt funktioniert. Diese Version gibt jedoch den Fehler im Betreff an.

Bin ich dumm, oder ist das etwas anderes?

FYI: Das Ergebnis des Obigen ist wie folgt (leicht saniert)

http --output subnet --pretty format --form post https://test.grid.domain.com/subnets cidr=10.124.33.128/25 name=Load_balancers description=Load_balancers availabilityZoneId=us-east-1c networkId=vpc-31433e7e x-gridauth-accesskey:DOYOUNEEDTOKNOW x-gridauth-secretaccesskey:WHATISWITHALLTHEQUESTIONS x-gridauth-accountid:11223344556677 _providerId=aws _regionId=us-east-1
feature planned

Hilfreichster Kommentar

Als zukünftige Referenz gibt es jetzt ein CLI-Argument --ignore-stdin , das verwendet werden kann, um HTTPie explizit mitzuteilen, dass Anforderungsdaten (Schlüssel=Wert) gegenüber dem Anforderungstext (von stdin) bevorzugt werden sollen.

http --ignore-stdin http://… lorem=ipsum dolor=sit

Vgl. https://httpie.org/docs#redirected -input

Alle 15 Kommentare

Dieser Fehler tritt auf, wenn STDIN HTTPie umgeleitet wird und gleichzeitig auch Daten in den Argumenten angegeben werden:

$ echo 'data' | http POST example.org more=data   # This is invalid

Ich leite STDIN überhaupt nicht um. Hier ist ein bisschen mehr Kontext im Skript:

cat keyfile  | while read name az route cidr subnetid rest ; do
    http --output subnet --pretty format --form post \
    "${URLHOST}subnets" \
    "cidr=${cidr}" \
    "name=${name}" \
    "description=${name}"\
    "availabilityZoneId=${az}" \
    "networkId=${VPCid}"\
    "$ACCESSKEY" \
    "$SECRETKEY"\
    "$ACCOUNTID" \
    "_providerId=aws" "_regionId=${REGION}"

(und dann parse ich die 'subnet'-Datei und mache andere Dinge)

Was ich tun KÖNNTE, ist das Mischen von Formularfeldern mit http-Headern. Allerdings konnte ich das auch nicht richtig zum Laufen bringen (eine Kombination aus dem Pushen der Formulardaten durch STDIN und Header als Parameter ... oder als Header und Formulardaten durch STDIN oder was auch immer).

Ich sehe, das Problem ist, dass HTTPie im Schleifenkontext sein STDIN erbt (das umgeleitet wird).

Sie sollten in der Lage sein, dies zu umgehen, indem Sie HTTPies STDIN zurück in die Terminaleingabe ( < /dev/tty ) ändern:

cat file | while read line; do 
    http POST example.org  a="$line" < /dev/tty
done

Beeindruckend. Das funktioniert. Ich hatte KEINE Ahnung, dass die inneren Anweisungen einer Shell-Schleife die Standardeingabe der umgebenden Schleife erben.

Vielen Dank für die Hilfe ... Ich bin mir nicht sicher, ob ich das alleine gefunden hätte.

(Jetzt bin ich neugierig, warum (ich gehe davon aus, dass alle von SH abgeleiteten Schalen) diese Designentscheidung getroffen haben ...)

Ich denke, es sollte eine Option geben, um das Lesen von STDIN zu deaktivieren, die überall funktionieren würde, also lasse ich diese offen und markiere sie als Feature.

Das ist sehr verwirrend und widerspricht der Möglichkeit, dass httpie überall arbeiten kann. Die Verwendung eines solchen Befehls innerhalb einer Bash-Schleife ist eine sehr häufige Anwendung. Httpie sollte sich nicht beschweren, wenn Schlüssel/Wert angegeben wird und es stdin erhält: Stattdessen Schlüssel/Wert dominieren lassen.

Httpie sollte sich nicht beschweren, wenn Schlüssel/Wert angegeben wird und es stdin erhält: Stattdessen Schlüssel/Wert dominieren lassen.

Das ist für Sie vielleicht intuitiv, aber für viele andere ist das genaue Gegenteil viel intuitiver. Da die Werkzeuge nicht versuchen sollten zu raten, ist es viel besser, einen Fehler zu melden und Ihnen eine Notausstiegsluke zu bieten, wenn Sie glauben, dass Sie es besser wissen, was dies tut.

Ich bin auf dieses Problem gestoßen, als ich httpie innerhalb einer Funktion verwendet habe, die an GNU parallel übergeben wurde:

function call_api {
    local FOO=`http --json --auth $TOKEN: post $HOST/api/foo name="Ţẽṧẗ" < /dev/tty | python3 -c "import json,sys;obj=json.load(sys.stdin);print(obj['result']['id']);"`
    […]
    http --download --auth $TOKEN: GET $HOST/api/bla > /dev/tty
}

export -f call_api
export HOST=…
export TOKEN=…
parallel --env HOST --env TOKEN ::: call_api call_api call_api call_api call_api

Dank des obigen Kommentars funktioniert der parallele Funktionsaufruf jetzt. Hinterlasse diesen Kommentar hier für zukünftige Referenzen 😊

Als zukünftige Referenz gibt es jetzt ein CLI-Argument --ignore-stdin , das verwendet werden kann, um HTTPie explizit mitzuteilen, dass Anforderungsdaten (Schlüssel=Wert) gegenüber dem Anforderungstext (von stdin) bevorzugt werden sollen.

http --ignore-stdin http://… lorem=ipsum dolor=sit

Vgl. https://httpie.org/docs#redirected -input

Dies ist bei der Verwendung http in einer for-Schleife aufgetreten. Es hat lokal gut funktioniert, aber in Gitlab ist es fehlgeschlagen. --ignore-stdin hat es gelöst.

Ich habe versucht, stdin auf null </dev/null umzuleiten, aber es hat httpie dazu gebracht, sich seltsam zu verhalten. Warum ist das? Ich meine, sollte es nicht eine Möglichkeit geben, einen Befehl dazu zu bringen, stdin von der Shell selbst zu ignorieren?

@NightMachinary möchten Sie die Option --ignore-stdin verwenden. So weisen Sie HTTPie an, STDIN nicht zu lesen.

$ echo 'this STDIN data is ignored' | http  --ignore-stdin POST httpbin.org/post hello=world

@jakubroztocil Ich weiß das, ich sage, wenn http nicht --ignore-stdin hätte, wie könnten wir stdin eliminieren, das von der Shell selbst zu http geht?

@NightMachinary Sie können STDIN (und die anderen Standard-Streams) nicht eliminieren, aber Sie können es schließen:

$ echo ignored data | http httpbin.org/anything 0<&-

https://superuser.com/questions/813472/how-do-i-close-stdin-in-a-shell-script

@NightMachinary und die Umleitung /dev/null ist etwas anders:

$ http httpbin.org/anything < /dev/null

Dies ruft HTTPie immer noch mit einem offenen und umgeleiteten STDIN , sodass HTTPie es liest und mit einer leeren Zeichenfolge endet, die es dann gerne als Anforderungstextdaten verwendet (effektiv standardmäßig POST ), es sei denn, Sie sagen es mit --ignore-stdin .

Also ist es im Grunde äquivalent zu diesem:

$ echo -n | http httpbin.org/anything 
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen