I am trying below code to get response body and status:
read -ra result <<< $(curl -i --insecure \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data "$configData" $openingNode"/voice/v1/updateWithPh")
status=${result[1]}
response=${result[#]}
echo $status
Problem here is -
I get both status code and response Body correctly.
But when I create a bash function and send it as an argument, the response body changes to "HTTP/1.1" in the function as shown below.
echo $(validateUpdate $configData $response)
Code for the function -
function validateUpdate(){
echo $1
echo $2
}
$2 prints as "HTTP/1.1"
What is the reason? How to rectify this issue?
You need to enclose your variables in double quotes to prevent bash splitting it into separate tokens.
Try
echo $(validateUpdate "$configData" "$response")
or even better (echo is useless as #tripleee points out; furthermore curly braces improves readability):
validateUpdate "${configData}" "${response}"
use same thing inside of your function
echo "$2"
Related
How can I get a specific field from the json response?
#!/bin/bash -
status=`curl -sk -H "api-token: $TOKEN" -H "Content-Type: application/json" https://path_to/values`
The response is
{
"cancelled": false,
"percentage": 0.5,
"state": "running"
}
I want to poll the 'status' that the response percentage is 100 and the cancelled field is always true. Can this be done without another tool like jq?
EDIT
I`m trying to figure out if I can install jq on the system. Is my approach correct using jq?
while
update_status=`curl -sk -H "api-token: $TOKEN" -H "Content-Type: application/json" https://path_to/values`
cancelled=$(jq -r '.cancelled' <<< "$update_status")
percentage_complete=$(jq -r '.percentage_complete' <<< "$update_status")
state=$(jq -r '.state' <<< "$update_status")
[[ $cancelled -eq 1 || $state == 'running' ]]
do true; done
"cancelled" is a boolean and "state" is a string with the values "running" or "not_running".
How can I add a log message which shows if the update fails or not? I`m not pretty sure with the do while loop...
echo "[INFO] Update done" ## depending on the failed var?
Using jq and reading the results into an array:
readarray -t dat <<< "$(curl -sk -H "api-token: $TOKEN" -H "Content-Type: application/json" https://path_to/values | jq -r '.cancelled,.percentage,.state')"
The array can then be used in an if statement:
if [[ "${dat[0]" == "true" && "${dat[1]" == "100" ]]
then
echo "There are no issues"
else
echo "There are issues"
fi
If jq is really not an option and if the json returned is as posted, you can use awk and return back an error code:
if (curl -sk -H "api-token: $TOKEN" -H "Content-Type: application/json" https://path_to/values | awk '/(cancelled)|(percentage)|(state)/ { gsub("[\",:]","",$0);gsub(" ","",$1);map[$1]=$2 } END { if ( map["cancelled"]=="false" && map["percentage"] == 100 ) { exit 0 } else { exit 1 } }');
then
echo "There are no issues"
else
echo "There are issues"
fi
Pipe the output of the curl command into awk and where there is "cancelled", "percentage" or "state" in the line, process. Remove any "," or double quotes or ":" from the line and then remove any spaces from the first space delimited field with gsub and then add to an array called map and use the first field as the index and the second field as the value. At the end, check the indexes of the map array and exit with 0 if all are as expected, otherwise, exit with 0.
I am using this bash script to post a new message to my rocket.chat instance.
#!/usr/bin/env bash
function usage {
programName=$0
echo "description: use this program to post messages to Rocket.chat channel"
echo "usage: $programName [-b \"message body\"] [-u \"rocket.chat url\"]"
echo " -b The message body"
echo " -u The rocket.chat hook url to post to"
exit 1
}
while getopts ":b:u:h" opt; do
case ${opt} in
u) rocketUrl="$OPTARG"
;;
b) msgBody="$OPTARG"
;;
h) usage
;;
\?) echo "Invalid option -$OPTARG" >&2
;;
esac
done
if [[ ! "${rocketUrl}" || ! "${msgBody}" ]]; then
echo "all arguments are required"
usage
fi
read -d '' payLoad << EOF
{"text": "${msgBody}"}
EOF
echo $payLoad
statusCode=$(curl \
--write-out %{http_code} \
--silent \
--output /dev/null \
-X POST \
-H 'Content-type: application/json' \
--data "${payLoad}" ${rocketUrl})
echo ${statusCode}
Everthings works fine, so i can send a new message like this
./postToRocket.sh -b "Hello from here" -u $RocketURL
But when i try to add a message with multiple lines like this
./postToRocket.sh -b "Hello from here\nThis is a new line" -u $RocketURL
it doesn't work. I get the following output:
{"text": "Hello from heren New Line"}
200
So what do i need to change, to use break line with these bash script. Any ideas?
First, the thing making the backslash in your \n disappear was the lack of the -r argument to read. Making it read -r -d '' payLoad will fix that. However, that's not a good solution: It requires your callers to pass strings already escaped for inclusion in JSON, instead of letting them pass any/every possible string.
To make valid JSON with an arbitrary string -- including one that can contain newline literals, quotes, backslashes, or other content that has to be escaped -- use jq:
payLoad=$(jq -n --arg msgBody "$msgBody" '{"text": $msgBody}')
...and then, after doing that, amend your calling convention:
./postToRocket.sh -b $'Hello from here\nThis is a new line' -u "$RocketURL"
I believe this has already been answered in SO here
Should work by adding the $ sign and using single quotes:
./postToRocket.sh -b $'Hello from here\nThis is a new line' -u $RocketURL
i need help in understanding what is wrong with the below shell script,all its doing is executing a curl script using shell scripting and searching for a string domain_id in the output of curl command ,once it finds the search all it does it simply displays valid url
Here is the full code for shell script below
#!/bin/sh
# Black Box Tester!
url=”https://api.platform.abc.com/auth/oauth/token“
content=”$(curl --location --request POST “$url” --header 'Content-Type:
application/x-www-form-urlencoded' --header 'Authorization: Basic
V0pSWURISA==' --data-raw 'grant_type=password&username=event-
player1#abc.com&password=********' | grep domain_id”
if [ ! -z $content ] && [ $content -eq domain_id ]
then
echo “valid url”
else
echo “invalid url”
fi
Below is the error i get in console after i try executing the script
WS-126691A:loginimagedocker carolyn$ ./login.sh
./login.sh: line 4: unexpected EOF while looking for matching `)'
./login.sh: line 11: syntax error: unexpected end of file
You are trying to pass parameter in multiple line without mentioning end of line.
use \ to pass multi line argument
#!/bin/sh
# Black Box Tester!
url=”http://api.platform.abc.com/auth/oauth/token“
content=”$(curl --location --request POST “$url” --header 'Content-Type: \
application/x-www-form-urlencoded' --header 'Authorization: Basic \
V0pSWURISA==' --data-raw 'grant_type=password&username=event- \
player1#abc.com&password=********' | grep domain_id” )
if [ ! -z $content ] && [ $content -eq domain_id ]
then
echo “valid url”
else
echo “invalid url”
fi
I have a curl command that looks like this:
curl -X PUT -H "myheader:coca-cola" -d '{ "name":"harrypotter" }' http://mygoogle.com/service/books/123
Running this command as is via terminal returns the expected results.
I am trying to incorporate this curl command in my bash script as follows:
#!/bin/bash
MYURL=http://mygoogle.com/service/books/123
# Generate body for curl request
generate_put_data()
{
cat <<EOF
{
"name":"harrypotter"
}
EOF
}
put_data=$(echo "$(generate_put_data)")
put_data_with_single_quotes="'$put_data'"
# Generate headers for curl request
header=myheader:coca-cola
header_with_double_quotes="\"$header\""
# The following function takes two inputs - a simple string variable (with no spaces or quotes) and the curl command string
function run_cmd() {
echo $1
echo $2
#Run the curl command
"$2"
#Check return code of the curl command
if [ "$?" -ne 0 ]; then
#do something with simple string variable
echo "$1"
echo "Job failed"
exit 1
else
#do something with simple string variable
echo "$1"
echo "Job Succeeded"
fi
}
# Run the bash function - run_cmd
run_cmd "mysimplestring" "curl -X PUT -H $header_with_double_quotes -d $put_data_with_single_quotes $MYURL"
However, when I try to run the above bash script, it fails at the point where I call run_cmd() function with the two inputs. I get the following error:
curl -X PUT -H "myheader:coca-cola" -d '{
"name":"harrypotter"
}' http://mygoogle.com/service/books/123: No such file or directory
Job failed
This error occurs on the line where "$2" is being executed in the run_cmd() function declaration.
Could someone help me understand where I am going wrong? Thanks!
"$2"
This will take the second argument and try to run it without doing any word splitting. It treats it as one string.
You're going to run into trouble passing in the curl command as one string. You'll do better if you pass it without quotes, just as if you typed it on the command line. You'll want to quote each of the variables but not quote the command as a whole.
run_cmd "mysimplestring" curl -X PUT -H "$header" -d "$put_data" "$MYURL"
Notice that you don't need the "with_quotes" variables any more. You don't have to do anything like that. The original plain values will work.
Now you can access the command using array syntax:
function run_cmd() {
local name=$1; shift
local cmd=("$#")
#Run the curl command
"${cmd[#]}"
}
By the way, this is a useless use of echo:
put_data=$(echo "$(generate_put_data)")
Make that:
put_data=$(generate_put_data)
I have a script that runs curl. I want to be able to optionally add a -H parameter, if a string isn't empty. What's complex is the levels of quoting and spaces.
caption="Test Caption"
if [ "${caption}" != "" ]; then
CAPT=-H "X-Caption: ${caption}"
fi
curl -A "$UA" -H "Content-MD5: $MD5" -H "X-SessionID: $SID" -H "X-Version: 1" $CAPT http://upload.example.com/$FN
The idea is that the CAPT variable is either empty, or contains the desired -H header in the same form as the others, e.g., -H "X-Caption: Test Caption"
The problem is when run, it interprets the assignment as a command to be executed:
$bash -x -v test.sh
+ '[' 'Test caption' '!=' '' ']'
+ CAPT=-H
+ 'X-Caption: Test caption'
./test.sh: line 273: X-Caption: Test caption: command not found
I've tried resetting IFS before the code, but it didn't make a difference.
The key to making this work is to use an array.
caption="Test Caption"
if [[ $caption ]]; then
CAPT=(-H "X-Caption: $caption")
fi
curl -A "$UA" -H "Content-MD5: $MD5" -H "X-SessionID: $SID" -H "X-Version: 1" "${CAPT[#]}" "http://upload.example.com/$FN"
If you only need to know whether or not the caption is there, you can interpolate it when it needs to be there.
caption="Test Caption"
NOCAPT="yeah, sort of, that would be nice"
if [ "${caption}" != "" ]; then
unset NOCAPT
fi
curl ${NOCAPT--H "X-Caption: ${caption}"} -A "$UA" ...
To recap, the syntax ${var-value} produces value if var is unset.
I finally did get it to work. Part of the problem is specific to curl, in that when using the -H option to set custom headers, it seems to work best when everything after the -H (that is, both the custom header name and value) are protected by single quotes. Then, I needed to pass the constructed string through eval to get it to work.
To make this easier to read, I store a single quote in a variable named TICK.
Example:
TICK=\'
#
HDRS=""
HDRS+=" -H ${TICK}Content-MD5: ${MD5}${TICK}"
HDRS+=" -H ${TICK}X-SessionID: ${SID}${TICK}"
HDRS+=" -H ${TICK}X-Version: 1.1.1${TICK}"
HDRS+=" -H ${TICK}X-ResponseType: REST${TICK}"
HDRS+=" -H ${TICK}X-ID: ${ID}${TICK}"
if [ "${IPTC[1]}" != "" ]; then
HDRS+=" -H ${TICK}X-Caption: ${IPTC[1]}${TICK}"
fi
if [ "${IPTC[2]}" != "" ]; then
HDRS+=" -H ${TICK}X-Keywords: ${IPTC[2]}${TICK}"
fi
#
# Set curl flags
#
CURLFLAGS=""
CURLFLAGS+=" --cookie $COOKIES --cookie-jar $COOKIES"
CURLFLAGS+=" -A \"$UA\" -T ${TICK}${the_file}${TICK} "
eval curl $CURLFLAGS $HDRS -o $OUT http://upload.example.com/$FN