Httpie: Добавить опцию для игнорирования данных стандартного ввода

Созданный на 23 июл. 2013  ·  15Комментарии  ·  Источник: httpie/httpie

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

Эта ошибка довольно загадочна. Я пишу сценарий оболочки для взаимодействия с остальным API, и я делаю это:

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

Который выдает (когда ему предшествует «эхо» команда, которая работает отлично. Однако эта версия выдает ошибку в теме.

Я туплю или это что-то другое?

FYI: результат вышеизложенного выглядит следующим образом (слегка продезинфицирован)

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

Самый полезный комментарий

Для справки в будущем теперь есть аргумент CLI --ignore-stdin , который можно использовать для явного указания HTTPie, что данные запроса (ключ = значение) должны быть предпочтительнее тела запроса (из стандартного ввода).

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

См. https://httpie.org/docs#redirected-ввод

Все 15 Комментарий

Эта ошибка возникает, когда HTTPie STDIN перенаправляется, и данные также указываются в аргументах одновременно:

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

Я вообще не перенаправляю STDIN. Вот еще немного контекста в сценарии:

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

(а затем я анализирую файл «подсети» и продолжаю делать другие вещи)

Что я МОЖЕТ делать, так это смешивать поля форм с http-заголовками. Однако я тоже не мог заставить это работать правильно (какая-то комбинация передачи данных формы через STDIN и заголовков в качестве параметров... или заголовков и данных формы через STDIN или что-то еще).

Я вижу, проблема в том, что в контексте цикла HTTPie наследует свой STDIN (который перенаправляется).

Вы должны иметь возможность обойти это, изменив HTTPie STDIN обратно на ввод терминала ( < /dev/tty ):

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

Ух ты. Это работает. Я понятия не имел, что внутренние операторы цикла оболочки наследуют стандартный ввод окружающего цикла.

Спасибо за помощь... Я не уверен, что нашел бы это самостоятельно.

(Теперь мне любопытно, почему (я предполагаю, что все оболочки, производные от SH) сделали такой выбор дизайна...)

Я думаю, что должна быть возможность отключить чтение STDIN , которая будет работать везде, поэтому я держу это открытым и помечаю как функцию.

Это очень сбивает с толку и противоречит тому, что httpie может работать где угодно. Использование такой команды внутри цикла bash — очень распространенное приложение. Httpie не должен жаловаться, когда передается ключ/значение, и он получает stdin: вместо этого позволяет доминировать ключ/значение.

Httpie не должен жаловаться, когда передается ключ/значение, и он получает stdin: вместо этого позволяет доминировать ключ/значение.

Это может быть интуитивно понятно для вас, но для многих других гораздо более интуитивно понятно прямо противоположное. Поскольку инструменты не должны пытаться угадать, гораздо лучше выдать ошибку и предоставить вам аварийный выход, если вы чувствуете, что знаете лучше, что и происходит.

Я столкнулся с этой проблемой при использовании httpie внутри функции, переданной 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

Благодаря приведенному выше комментарию вызов параллельной функции теперь работает. Оставлю этот комментарий здесь для дальнейшего использования 😊

Для справки в будущем теперь есть аргумент CLI --ignore-stdin , который можно использовать для явного указания HTTPie, что данные запроса (ключ = значение) должны быть предпочтительнее тела запроса (из стандартного ввода).

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

См. https://httpie.org/docs#redirected-ввод

Столкнулся с этим при использовании http в цикле for. Он отлично работал локально, но не работал в gitlab. --ignore-stdin разрешил это.

Я попытался перенаправить stdin на null </dev/null , но это заставило httpie вести себя странно. Почему это? Я имею в виду, не должен ли быть способ заставить команду игнорировать стандартный ввод из самой оболочки?

@NightMachinary вы хотите использовать опцию --ignore-stdin . Вот как вы говорите HTTPie не читать STDIN .

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

@jakubroztocil Я знаю это, я говорю, что если бы у http не было --ignore-stdin , как мы могли бы исключить stdin, идущий к http из самой оболочки?

@NightMachinary вы не можете удалить STDIN (и другие стандартные потоки), но вы можете закрыть его:

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

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

@NightMachinary и перенаправление /dev/null немного отличаются:

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

Это по-прежнему вызывает HTTPie с открытым и перенаправленным STDIN , поэтому HTTPie прочитает его и получит пустую строку, которую затем с радостью использует в качестве данных тела запроса (фактически по умолчанию POST ), если только вы не скажете ему не делать это с помощью --ignore-stdin .

Так что это в основном эквивалентно этому:

$ echo -n | http httpbin.org/anything 
Была ли эта страница полезной?
0 / 5 - 0 рейтинги