Httpie: Tambahkan opsi untuk mengabaikan data stdin

Dibuat pada 23 Jul 2013  ·  15Komentar  ·  Sumber: httpie/httpie

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

Kesalahan ini agak samar. Saya sedang menulis skrip Shell untuk berinteraksi dengan API lainnya, dan saya melakukan ini:

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}"

Yang menghasilkan (bila didahului oleh 'echo' perintah yang bekerja dengan baik. Namun, versi ini memberikan kesalahan pada subjek.

Apakah saya bodoh, atau apakah ini sesuatu yang lain?

FYI: Hasil di atas adalah sebagai berikut (sedikit disanitasi)

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

Komentar yang paling membantu

Untuk referensi di masa mendatang, sekarang ada argumen CLI --ignore-stdin yang dapat digunakan untuk secara eksplisit memberi tahu HTTPie bahwa data permintaan (kunci=nilai) harus lebih disukai daripada badan permintaan (dari stdin).

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

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

Semua 15 komentar

Kesalahan ini terjadi ketika STDIN HTTPie dialihkan dan data juga ditentukan dalam argumen secara bersamaan:

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

Saya tidak mengarahkan STDIN sama sekali. Berikut ini sedikit lebih banyak konteks dalam skrip:

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}"

(dan kemudian saya mengurai file 'subnet', dan melanjutkan untuk melakukan hal-hal lain)

Apa yang MUNGKIN saya lakukan adalah mencampur bidang formulir dengan http-header. Namun, saya juga tidak dapat membuatnya berfungsi dengan benar (beberapa kombinasi mendorong data formulir melalui STDIN, dan header sebagai parameter... atau sebagai header dan data formulir melalui STDIN, atau apa pun).

Saya mengerti, masalahnya adalah bahwa dalam konteks loop HTTPie mewarisi STDIN (yang dialihkan).

Anda seharusnya dapat mengatasinya dengan mengubah STDIN HTTPie kembali ke input terminal ( < /dev/tty ):

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

Wow. Itu bekerja. Saya TIDAK tahu bahwa pernyataan bagian dalam dari loop Shell mewarisi stdin dari loop di sekitarnya.

Terima kasih atas bantuannya... Saya tidak yakin saya akan menemukannya sendiri.

(Sekarang saya ingin tahu mengapa (saya berasumsi semua shell turunan SH) membuat pilihan desain itu ...)

Saya pikir harus ada opsi untuk menonaktifkan pembacaan STDIN yang akan berfungsi di mana saja, jadi saya tetap membukanya dan menandainya sebagai fitur.

Ini sangat membingungkan, dan bertentangan dengan kemampuan httpie untuk bekerja di mana saja. Menggunakan perintah seperti itu di dalam bash loop adalah aplikasi yang sangat umum. Httpie seharusnya tidak mengeluh ketika kunci/nilai diberikan dan menerima stdin: alih-alih membiarkan kunci/nilai mendominasi.

Httpie seharusnya tidak mengeluh ketika kunci/nilai diberikan dan menerima stdin: alih-alih membiarkan kunci/nilai mendominasi.

Itu mungkin intuitif bagi Anda, tetapi bagi banyak orang lain, kebalikannya jauh lebih intuitif. Karena perkakas tidak boleh mencoba menebak, jauh lebih baik untuk meningkatkan kesalahan dan memberi Anda jalan keluar jika Anda merasa lebih tahu, yang memang demikian.

Saya mengalami masalah ini saat menggunakan httpie di dalam fungsi yang diteruskan ke GNU parallel :

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

Berkat komentar di atas , pemanggilan fungsi paralel berfungsi sekarang. Meninggalkan komentar ini di sini untuk referensi di masa mendatang 😊

Untuk referensi di masa mendatang, sekarang ada argumen CLI --ignore-stdin yang dapat digunakan untuk secara eksplisit memberi tahu HTTPie bahwa data permintaan (kunci=nilai) harus lebih disukai daripada badan permintaan (dari stdin).

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

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

Menemukan ini saat menggunakan http dalam for loop. Ini bekerja dengan baik secara lokal, tetapi gagal di gitlab. --ignore-stdin menyelesaikannya.

Saya mencoba mengarahkan stdin ke null </dev/null , tetapi itu membuat httpie berperilaku aneh. Mengapa itu? Maksud saya, bukankah seharusnya ada cara untuk membuat perintah mengabaikan stdin dari Shell itu sendiri?

@NightMachinary Anda ingin menggunakan opsi --ignore-stdin . Begitulah cara Anda memberi tahu HTTPie untuk tidak membaca STDIN .

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

@jakubroztocil Saya tahu itu, saya katakan jika http tidak memiliki --ignore-stdin , bagaimana kita bisa menghilangkan stdin menuju http dari shell itu sendiri?

@NightMachinary Anda tidak dapat menghilangkan STDIN (dan aliran standar lainnya), tetapi Anda dapat menutupnya:

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

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

@NightMachinary dan mengarahkan ulang /dev/null sedikit berbeda:

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

Ini masih memanggil HTTPie dengan open & redirected STDIN , jadi HTTPie akan membacanya dan berakhir dengan string kosong, yang kemudian akan dengan senang hati digunakan sebagai data badan permintaan (secara efektif default ke POST ), kecuali jika Anda melarangnya dengan --ignore-stdin .

Jadi pada dasarnya setara dengan ini:

$ echo -n | http httpbin.org/anything 
Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

pyvotal-cguers picture pyvotal-cguers  ·  5Komentar

Govinda-Fichtner picture Govinda-Fichtner  ·  6Komentar

filipesperandio picture filipesperandio  ·  3Komentar

maciej picture maciej  ·  4Komentar

a-x- picture a-x-  ·  7Komentar