Httpie: 添加选项以忽略标准输入数据

创建于 2013-07-23  ·  15评论  ·  资料来源: httpie/httpie

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

这个错误相当神秘。 我正在编写一个 shell 脚本来与一个 rest 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}"

这会产生(当前面有'echo'时,一个运行良好的命令。但是,这个版本给出了主题中的错误。

是我傻了,还是另有原因?

仅供参考:上述结果如下(稍微消毒)

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 请求数据(key=value)应该优先于请求正文(来自标准输入)。

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

参照。 https://httpie.org/docs#redirected -input

所有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-headers 混合。 但是,我也无法使其正常工作(通过STDIN推送表单数据和作为参数的标题......或通过STDIN作为标题和表单数据的某种组合,或其他)。

我明白了,问题是在循环上下文中 HTTPie 继承了它的STDIN (被重定向)。

您应该可以通过将 HTTPie 的STDIN更改回终端输入( < /dev/tty )来解决它:

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

哇。 这样可行。 我不知道 shell 循环的内部语句继承了周围循环的标准输入。

谢谢你的帮助......我不确定我是否会自己找到它。

(现在我很好奇为什么(我假设所有 SH 派生的外壳)做出了这样的设计选择......)

我认为应该有一个选项来禁用STDIN的读取,它可以在任何地方工作,所以我保持打开状态并将其标记为一个功能。

这非常令人困惑,并且不利于 httpie 能够在任何地方工作。 在 bash 循环中使用这样的命令是一个非常常见的应用程序。 当给定键/值并接收标准输入时,Httpie 不应该抱怨:而是让键/值占主导地位。

当给定键/值并接收标准输入时,Httpie 不应该抱怨:而是让键/值占主导地位。

这对你来说可能很直观,但对许多其他人来说,恰恰相反更直观。 因为工具不应该试图猜测,所以如果您觉得自己知道得更多,最好提出错误并为您提供一个逃生舱口,这就是这样做的。

我在传递给GNU parallel的函数中使用 httpie 时遇到了这个问题:

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 请求数据(key=value)应该优先于请求正文(来自标准输入)。

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

参照。 https://httpie.org/docs#redirected -input

在 for 循环中使用http时遇到此问题。 它在本地运行良好,但在 gitlab 中失败了。 --ignore-stdin解决了它。

我尝试将 stdin 重定向到 null </dev/null ,但它使 httpie 表现得很奇怪。 为什么? 我的意思是,不应该有一种方法可以让命令忽略 shell 本身的标准输入吗?

@NightMachinary你想使用--ignore-stdin选项。 这就是告诉 HTTPie 不要读取STDIN的方式。

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

@jakubroztocil我知道,我是说如果http没有--ignore-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

这仍然使用打开和重定向的STDIN调用 HTTPie,因此 HTTPie 将读取它并以一个空字符串结束,然后它将愉快地用作请求正文数据(实际上默认为POST ),除非你用--ignore-stdin告诉它不要这样做。

所以它基本上相当于这个:

$ echo -n | http httpbin.org/anything 
此页面是否有帮助?
0 / 5 - 0 等级