
したがって、POSTリクエストをGist(github)に送信するには、次のようにします。https://gist.github.com/caspyi...
curl --user "user" -X POST --data '{"description":"Created via API","public":"true","files":{"file1.txt":{"content":"Demo"}}' https://api.github.com/gists
しかし、上記の例では、ファイル名とファイルの内容がハードコードされており、その部分が.. file1.txt":{"content":"Demo"}
..
私は上記の部分を変数に置き換えています$file":{"content":"$content"}
が、変数を初期化しています。JSONリクエストは二重引用符で囲む必要があります。
curl --user "user" -X POST --data "{\"description\":\"Created via API\",\"public\":\"true\",\"files\":{\"$file\":{\"content\":\"$content\"}}' https://api.github.com/gists
しかし、これは機能せず、json エラーが発生します。
{
"message": "Problems parsing JSON",
"documentation_url": "https://developer.github.com/v3/gists/#create-a-gist"
}
エスケープされた二重引用符をすべて一重引用符に置き換えた場合でも同じです\'
。
このJSONリクエスト内に変数を含める方法を誰か知っていますか?ちなみに私は次のようなすべてのヘッダーを使用しました
-H "Content-Type: application/json; charset=UTF-8"
リクエストを検証するために多くの組み合わせを試したが、役に立たなかった
アップデート。
全体の内容は次のようになります。
function gist_controller(){
content=$(cat $1)
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
read -p "enter your password - " pass
public="false"
gist_content=$(cat $1)
curl --user "samserayo" -H "Content-Type: application/json; charset=UTF-8" -X POST -d "{ 'description': 'Created via API', 'public': 'true', 'files':{ ' '$1 ':{ 'content': '$gist_content'}}" https://api.github.com/gists
}
アップデート2
スクリプトが壊れる原因となるファイル(アップロードしようとしているファイル)
<?php echo 'hello world' ?>
答え1
$file または $content に設定した値が表示されません。これらは両方ともどのように展開されますか? どちらか一方、または両方に、JSON パーサーが好まない文字が含まれている可能性があります。おそらく、変数展開値内の何かを、curl を介して JSON パーサーに送信する前に、さらにエスケープまたはエンコードする必要があります。
環境変数をエクスポートしましたか?
試す:
echo "$file $content";
両方が期待どおりに設定されていることを確認します。
答え2
使用しているシェルを指定していませんが、二重引用符で囲まれたものはすべてシェルのファイル名の展開の対象となります。特に、{} はほとんどのシェルで意味を持ちます。引用した例で全体を一重引用符で囲んでいるのはそのためです。
シェル エスケープは扱いにくく、時には望む結果が得られないこともあります。正直なところ、このような場合、シェルが「役に立たない」ことはわかっているので、curl を呼び出す Python スクリプトを作成します。
答え3
これはレビューのために差し戻されたので、別の回答をここに示します。
各部分を個別にエスケープします (最初のエスケープを閉じてから、変数をエスケープします)。
curl --user "user" -X POST --data '{"description":"Created via API","public":"true","files":{"'"${file}"'":{"content":"'"${content}"'"}}}' https://api.github.com/gists
または読みやすくするために分割します:
'{"description":"Created via API","public":"true","files":{"'
"${file}"
'":{"content":"'
"${content}"
'"}}}'
シェルが変数自体の空白を解釈しないように、内部フィールド区切り文字を変更する必要がある場合もあります。
MWE:cat /tmp/myfile | ./thisscript.sh "myfilename.txt"
#!/bin/sh
FILENAME="${1}"
#CONTENT="$(cat)"
CONTENT="$(sed -e 's/"/\\"/g')" # escape stuff
OFS="${IFS}"
IFS=''
PERSONAL_ACCESS_TOKEN="e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e"
curl --user "username:${PERSONAL_ACCESS_TOKEN}" -X POST --data '{"description":"Created via API","public":"true","files":{"'"${FILENAME}"'":{"content":"'"${CONTENT}"'"}}}' https://api.github.com/gists
IFS="${OFS}"
これを正しく動作させるには、もちろんJSONを壊すすべての文字をエスケープする必要があります。、ファイルの内容には、"
制御文字(DOSの改行)などが含まれます。JSON
データ構造を使用することにしたのは残念です。ファイルの内容アップロード。
Gistを作成する別の方法を提案させていただくとすれば、API呼び出しを使用して、たとえば定型文のコンテンツ(空にできない)を含むcurl
単一のファイルを作成するだけです。 次に、返されたjson構造をgrepして、README
git_push_url
そしてクローンgist git リポジトリ。その後は、バイナリ データやエスケープの問題を気にせずに、gist に内容を追加するだけgit commit
です。git push
答え4
ここに解決策がありますが、2 つのことを前提としています。
は、file
スクリプトに最初の引数として提供されるファイル名です。 は、content
ファイルの内容ですtext
。
また、POST URL がお客様のものとは異なることにもご注意ください (説明は下記を参照)。
#!/bin/bash
file=$1
content=$(cat $1)
curl -H "Content-Type: application/json; charset=UTF-8" -X POST -d "{ 'description': 'Created via API', 'public': 'true', 'files':{ ' '${file}':{ 'content': '${content}'}}" https://postman-echo.com/post
content.txt ファイルには以下が含まれます:
This is content of the content file.
実行例:
./curl.sh content.txt
出力例:
{
"args": {},
"data": "{ 'description': 'Created via API', 'public': 'true', 'files':{ ' 'content.txt ':{ 'content': 'This is content of the content file.'}}",
"files": {},
"form": {},
"headers": {
"x-forwarded-proto": "https",
"host": "postman-echo.com",
"content-length": "134",
"accept": "*/*",
"content-type": "application/json; charset=UTF-8",
"user-agent": "curl/7.65.3",
"x-forwarded-port": "443"
},
"json": null,
"url": "https://postman-echo.com/post"
}
ノート:
https://postman-echo.com/post
ここでは、投稿したすべての内容を JSON としてエコーする Web サイトを使用しています。
content.txt ファイルの内容がより複雑な場合、適切にエスケープする必要があるため、このソリューションは機能しない可能性があります。コンテンツは「content」フィールドに入力されるため、json のすべてのエスケープ ルールがここに適用されます。
応答が美しく表示されるようにするには (上記の json のように)、curl の最後に以下を追加します| jq .
(最初にインストールする必要がある場合があります)。
https://postman-echo.com/post | jq .
コンテンツ ファイル全体を自動的に引用するために使用することも可能ですjq
(より高度な使用が必要な場合)。
$ jq -Rs '.' content.txt
"This is just a text.\n"
$ jq -Rs '.' content.cpp
"#include <iostream>\nusing namespace std;\nint main() \n{\n cout << \"Hello, World!\";\n return 0;\n}\n"
curl.sh
動作させるにはスクリプトを少し変更する必要があります:
content=$(jq -Rs '.' $1)