http: error: Request body (from stdin or a file) and request data (key=value) cannot be mixed.
هذا الخطأ غامض إلى حد ما. أنا أكتب برنامج شل النصي للتفاعل مع بقية واجهة برمجة التطبيقات ، وأنا أفعل هذا:
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 --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
أنا لا أقوم بإعادة توجيه 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
(والتي تمت إعادة توجيهها).
يجب أن تكون قادرًا على حل هذه المشكلة عن طريق تغيير STDIN
الخاص بـ HTTPie إلى إدخال المحطة الطرفية ( < /dev/tty
):
cat file | while read line; do
http POST example.org a="$line" < /dev/tty
done
رائع. انه يعمل انها تعمل. لم يكن لدي أي فكرة أن البيانات الداخلية لحلقة قذيفة ترث stdin من الحلقة المحيطة.
شكرًا لك على المساعدة ... لست متأكدًا من أنني كنت سأجد ذلك بنفسي.
(الآن لدي فضول لماذا (أفترض أن جميع الأصداف المشتقة من SH) اتخذت خيار التصميم هذا ...)
أعتقد أنه يجب أن يكون هناك خيار لتعطيل قراءة STDIN
التي ستعمل في كل مكان ، لذلك أبقي هذا مفتوحًا وأضع علامة عليه كميزة.
هذا أمر محير للغاية ، ويتعارض مع قدرة httpie على العمل في أي مكان. يعد استخدام مثل هذا الأمر داخل حلقة bash تطبيقًا شائعًا جدًا. يجب ألا يشتكي Httpie عند إعطاء المفتاح / القيمة ويتلقى stdin: بدلاً من ذلك ، السماح للمفتاح / القيمة بالسيطرة.
يجب ألا يشتكي Httpie عند إعطاء المفتاح / القيمة ويتلقى stdin: بدلاً من ذلك ، السماح للمفتاح / القيمة بالسيطرة.
قد يكون هذا أمرًا بديهيًا بالنسبة لك ، ولكن بالنسبة للكثيرين يكون العكس تمامًا أكثر سهولة. نظرًا لأن الأدوات يجب ألا تحاول التخمين ، فمن الأفضل بكثير أن ترفع خطأ وتزودك بفتحة هروب إذا كنت تشعر أنك تعرف بشكل أفضل ، وهو ما يفعله.
واجهت هذه المشكلة عند استخدام httpie داخل دالة تم تمريرها إلى GNU بالتوازي :
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 صراحة أن طلب البيانات (المفتاح = القيمة) يجب أن يكون مفضلًا على نص الطلب (من stdin).
http --ignore-stdin http://… lorem=ipsum dolor=sit
راجع https://httpie.org/docs#redirected -input
تمت مواجهة هذا أثناء استخدام http
في حلقة for. عملت بشكل جيد محليًا ، لكنها فشلت في gitlab. حلها --ignore-stdin
.
حاولت إعادة توجيه stdin إلى null </dev/null
، لكنها جعلت httpie تتصرف بشكل غريب. لماذا هذا؟ أعني ، ألا يجب أن تكون هناك طريقة لجعل الأمر يتجاهل stdin من القشرة نفسها؟
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
التعليق الأكثر فائدة
للرجوع إليها في المستقبل ، توجد الآن وسيطة CLI
--ignore-stdin
يمكن استخدامها لإخبار HTTPie صراحة أن طلب البيانات (المفتاح = القيمة) يجب أن يكون مفضلًا على نص الطلب (من stdin).راجع https://httpie.org/docs#redirected -input