Ley Missailidis
Ley Missailidis

Reputation: 79

Bash: A multiword variable breaking curl

I am having a small problem with in bash.

I have this rather ugly line

curl -u "$USER:$PASS" --request POST --data '{"title": "'$BRANCH_NAME'", "body": "'$DESCRIPTION'", "head": "'$OWNER':'$BRANCH_NAME'", "base": "develop"}' https://api.github.com/repos/$OWNER/$REPO_NAME/pulls

Where most of these variables are single words the $DESCRIPTION can be more than one but it seems that it breaks the line.

Is there some way to make $DESCRIPTION not break the curl command when it has more than one word in it?

Upvotes: 1

Views: 3274

Answers (3)

Gilles Quénot
Gilles Quénot

Reputation: 185319

Using here-doc, that will be safer for (y)our brain(s) :

curl \
    -X POST \
    -H "Content-type:text/json" \
    -d@- \
    "https://api.github.com/repos/$OWNER/$REPO_NAME/pulls" <<EOF
    {
        "title": "$BRANCH_NAME",
        "body" : "$DESCRIPTION",
        "head" : "$OWNER:$BRANCH_NAME",
        "base" : "develop"
    }
EOF
  • -X switch is the same as --request
  • -d switch is the same as --data
  • you can replace d@- by -d@/dev/stdin if exists.
  • @ for -d switch means read from a file

The simple and proper solution =)

Upvotes: 11

user80168
user80168

Reputation:

You should put your variables within "" quotes. Like:

curl -u "$USER:$PASS" --request POST --data '{"title": "'"$BRANCH_NAME"'", "body": "'"$DESCRIPTION"'", "head": "'"$OWNER"':'"$BRANCH_NAME"'", "base": "develop"}' "https://api.github.com/repos/$OWNER/$REPO_NAME/pulls"

Alternatively, you could (probably even should) do:

data="$( printf '{"title": "%s", "body": "%s", "head": "%s:%s", "base": "develop"}' "$BRANCH_NAME" "$DESCRIPTION" "$OWNER" "$BRANCH_NAME" )"
curl -u "$USER:$PASS" --request POST --data "$data" "https://api.github.com/repos/$OWNER/$REPO_NAME/pulls"

Upvotes: 3

Jonathan Leffler
Jonathan Leffler

Reputation: 754190

Since $DESCRIPTION can be multiple words, it must be surrounded by double quotes, thus:

curl -u "$USER:$PASS" --request POST \
     --data '{"title": "'$BRANCH_NAME'", "body": "'"$DESCRIPTION"'", \
              "head": "'$OWNER':'$BRANCH_NAME'", "base": "develop"}' \
     https://api.github.com/repos/$OWNER/$REPO_NAME/pulls

That's a trifle non-obvious, but the "'"$DESCRIPTION"'" section has a double quote inside the single quoted value for --data; then the single quote is terminated (temporarily), then there are double quotes around "$DESCRIPTION", then there's the start of a new single quoted section, and the first character inside is a double quote.

For consistency and future-proofing, you should also surround the other variables similarly:

curl -u "$USER:$PASS" --request POST \
     --data '{"title": "'"$BRANCH_NAME"'", "body": "'"$DESCRIPTION"'", \
              "head": "'"$OWNER"':'"$BRANCH_NAME"'", "base": "develop"}' \
     https://api.github.com/repos/$OWNER/$REPO_NAME/pulls

Try to avoid both single and double quotes in all the shell variable values; you will have nightmares getting it right if you have to worry about such quotes.

Upvotes: 0

Related Questions