Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent bash from adding single quotes to variable output

Problem: I'm writing a script that performs several HTTP requests with curl and I want to add the headers to a variable, CURL_HEADERS, so that I don't have to type them out constantly. When I echo the CURL_HEADERS variable in the curl command, single quotations appear where I don't want them. How can I prevent this? (The code below is simplified for the sake of clarity)

Code

#!/usr/bin/env bash
AUTH_KEY='1234'
set -x
CURL_HEADERS='-H "Authorization: Basic '${AUTH_KEY}'" -H "Content-Type: application/json"'
echo "${CURL_HEADERS}"
curl -s $(echo "${CURL_HEADERS}") 'http://www.example.org' > /dev/null
set +x

Expected Output:

+ CURL_HEADERS='-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
+ echo '-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
-H "Authorization: Basic 1234" -H "Content-Type: application/json"
++ echo '-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
+ curl -s -H "Authorization: Basic 1234" -H "Content-Type: application/json" http://www.example.org
+ set +x

Actual Output

+ CURL_HEADERS='-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
+ echo '-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
-H "Authorization: Basic 1234" -H "Content-Type: application/json"
++ echo '-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
+ curl -s -H '"Authorization:' Basic '1234"' -H '"Content-Type:' 'application/json"' http://www.example.org
+ set +x
like image 675
AJ Schmidt Avatar asked Sep 22 '17 23:09

AJ Schmidt


People also ask

Why is bash adding single quotes?

Bash is displaying single quotes so as to show a command that is valid input syntax. It is not running a command which contains these single quotes in a parameter to the ssh command.

What does $@ do bash?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc.


1 Answers

A reasonably straightforward solution is to use a bash array to store the four arguments you will want to pass:

CURL_HEADERS=(
             '-H' "Authorization: Basic ${AUTH_KEY}"
             '-H' 'Content-Type: application/json'
)

curl -s "${CURL_HEADERS[@]}" 'http://www.example.org' > /dev/null

Unlike scalar variables, which are just ordinary strings of ordinary characters no matter how many quotes they might contain, arrays are lists of strings, each one distinguished from each other one. In this sense, bash is just like almost every other programming language.

This problem, and the solution I suggest as well as several other ones, is well-described in the Bash FAQ entry 50 (I'm trying to put a command in a variable, but the complex cases always fail!), which is worth reading in detail. (Link taken from a comment by @John1024.)

like image 164
rici Avatar answered Nov 16 '22 04:11

rici