How to get a specific string from a variable using Shell Script - bash

I have a code which returns an access token string.
#!/bin/bash
token=$(curl --globoff -X POST "https://example.com/token" -F 'grant_type=client_credentials' -F 'client_id=d86fc9b690963b8dda602bd26f33454r457e9024a4ecccf4c3bbf66ffcbc241b' -F 'client_code'='ff148c56118728b62c9f2ew3e4r009a7a1c645276b70611fa32fa055b9944934')
echo "$token" > Token.txt
The output given by this command is :
{
"access_token": "5048e7d38e73b4a809a4fcb219b63ae34f34f43f83d6663ffd777203afb5654ab",
"token_type": "bearer",
"expires_in": 7200
}
ie. the variable token contains the above result. My question is how to get the access token 5048e7d38e73b4a809a4fcb219b63ae34f34f43f83d6663ffd777203afb5654ab alone from this and save to another variable.

First try jq, if not possible, this is a workaround using awk:
access_token=$(curl --globoff -X POST "https://example.com/token" \
-F 'grant_type=client_credentials' \
-F 'client_id=d86fc9b690963b8dda602bd26f33454r457e9024a4ecccf4c3bbf66ffcbc241b' \
-F 'client_code'='ff148c56118728b62c9f2ew3e4r009a7a1c645276b70611fa32fa055b9944934'|\
awk -F\" '/access_token/{print $4}')
The way to do this in jq would be to do
access_token=$(curl --globoff -X POST "https://example.com/token" \
-F 'grant_type=client_credentials' \
-F 'client_id=d86fc9b690963b8dda602bd26f33454r457e9024a4ecccf4c3bbf66ffcbc241b' \
-F 'client_code'='ff148c56118728b62c9f2ew3e4r009a7a1c645276b70611fa32fa055b9944934'|\
jq -r '.access_token' )

I am using this in bash to get and use the token ...
access_tok=$(curl -s -X POST -d "client_id=$(< "$LOGON_HOME/client_id" )&client_secret=$(< "$LOGON_HOME/client_secret")&grant_type=client_credentials" "${TOKEN_URL}" )
access_tok=${access_tok#*access_token\":\"}
access_tok=${access_tok%%\"*}
and later
curl -l -s -O -H "Authorization: Bearer ${access_tok}" "${FILE_URL}"

Related

how to put 2 elements from jq variables in one request?

There is a part of the script where each request receives a response and is written to a variable. How to do it in one request with writing to variables?
boolStatus=$(curl -X 'GET' \
"https://tsit-app1/api/v2/workItems/$case?versionNumber=0" \
-H 'accept: application/json' \
-H "Authorization: $apiKey" | jq '.isAutomated')
echo $boolStatus
name=$(curl -X 'GET' \
"https://tsit-app1/api/v2/workItems/$case?versionNumber=0" \
-H 'accept: application/json' \
-H "Authorization: $apiKey" | jq '.name')
echo $name
I tried
curl -X 'GET' \
"https://tsit-app1/api/v2/workItems/$case?versionNumber=0" \
-H 'accept: application/json' \
-H "Authorization: $apiKey" | jq '"boolStatus=\(.isAutomated)", "name=\(.name)"'
but in echo i get
"boolStatus=true",
"name=bla bla"
need to
echo $boolStatus
true
echo $name
bla bla
One way would be to use the #sh string interpolation and then use your shell's eval.
Using the string interpolation would output something like:
boolStatus=true
name='abc'
which can then be fed to eval:
vars="$(curl ... | jq -r '#sh "boolStatus=\(.isAutomated)", #sh "name=\(.name)"')"
eval "$vars"
or explicitly output the line break:
jq -r '#sh "boolStatus=\(.isAutomated)\nname=\(.name)"'
Disclaimer: Note that this will evaluate any shell code and might open your system to malicious code (#sh escapes the values, but it's always a good idea to be aware of this).
Use process substitution to allow two uses of read to read from the output of jq.
{ read boolStatus; read name; } < <(curl ... | jq -r '.isAutomated, .name')
(assuming the name does not contain any newlines).
At the very least, you can save the output to process with jq twice.
response=$(curl ...)
name=$(echo "$response" | jq -r .name)
boolStatus=$(echo "$response" | jq -r .isAutomated)

How to get Http Status Code and Vourbose logs by Curl function

We try to check the API connection and response by several curl commands as follows, we have two issue though.
-- function
function exec_cmd() {
cmd=$#
echo "curl command:" ${cmd}
response=$(${cmd} --max-time ${timeout_sec} -o ${LogFile} -w '%{http_code}\n' -S)
echo statud_code:${response}
}
-- curl command#1 ...
exec_cmd curl -v -x put <LBFrontIP/ApiEndpoint1> -H 'Content-Type:application/json; charset=utf-8' -H 'Host:<HostName>' -d '{"SystemId":"XXXX", "AppNo":"99999999999"}'
-- curl command#2
exec_cmd curl -v -x put <LBFrontIP/ApiEndpoint2> -H 'Content-Type:application/json; charset=utf-8' -H 'Host:<HostName>' -d '{"sbSystemId":"XXXX", "email":"XXX#example.com",
"PhoneNo":"99999999999"}'
-- curl command#3
exec_cmd curl -v -x put <LBFrontIP/ApiEndpoint3> -H 'Content-Type:application/json; charset=utf-8' -H 'Host:<HostName>' -d '
{
"ID1": "XXXXX",
"ID2": "1q2w3e4r5t",
"applyNo": "00db182faef74e779ca958681127bcec", ...
"docLiveScore": "0.1391"
}'
Issue #1 : cmd=$# can get the curl command but if that curl command contains # or return code, it can't work as expected.
curl command#1 is working fine, but curl command#2 and #3 is not, since bash misunderstands # and return code in data option as terminate of the command line. Curl command can work by itself though.
Also tried cmd=$* or cmd="$#" but not working so far.
Issue #2 : We'd like to get status_code for our quick check, but on the same time, we'd like to get the detail response in the log.
Is there any better way to get both of status_code and verbose log by appropriate function?
Above commands over write the verbose logs...
Given the complexity of the commands involved, I am tempted to say that you should avoid command parsing and read the command lines from a job configuration file.
#!/bin/bash
START=`pwd`
echo ${START}
BASE=`basename "$0" ".sh" `
ThisDATE=`date '+%Y%m%d_%H%M%S' `
LogPrefix="${START}/${BASE}.${ThisDATE}" ; rm -f "${LogPrefix}"*
BatchFile="${START}/${BASE}.${ThisDATE}.config" ; rm -f "${BatchFile}"
cat >$BatchFile <<-!EnDoFbAtCh
curl -v -x put <LBFrontIP/ApiEndpoint1> -H 'Content-Type:application/json; charset=utf-8' -H 'Host:<HostName>' -d '{"SystemId":"XXXX", "AppNo":"99999999999"}'
curl -v -x put <LBFrontIP/ApiEndpoint2> -H 'Content-Type:application/json; charset=utf-8' -H 'Host:<HostName>' -d '{"sbSystemId":"XXXX", "email":"XXX#example.com", "PhoneNo":"99999999999"}'
curl -v -x put <LBFrontIP/ApiEndpoint3> -H 'Content-Type:application/json; charset=utf-8' -H 'Host:<HostName>' -d '{ "ID1": "XXXXX", "ID2": "1q2w3e4r5t", "applyNo": "00db182faef74e779ca958681127bcec", ... "docLiveScore": "0.1391" }'
!EnDoFbAtCh
function exec_cmd() {
echo "curl command: ${cmd}"
${cmd} --max-time ${timeout_sec} -o ${LogFile} -w '%{http_code}\n' -S
RC=$?
echo "statud_code:${RC}"
}
index=1
while read cmd
do
if [ -z "${cmd}" ] ; then break ; fi
LogFile="${LogPrefix}.${index}.log"
exec_cmd
index=`expr ${index} + 1 `
done < "${BatchFile}"

cURL using bash script with while read text file

Hi there anyone there having the same trouble like mine?
whenever I cURL the $list from the list.txt it just displaying {} which is a blank response from the API does my code should be really working properly or it is just a bug?
I know the $list is working because I can update the database status
Please this is a bit urgennnnttt :(
#! /bin/bash
filename=/var/lib/postgresql/Script/list.txt
database='dbname'
refLink='URL'
authorization='Authorization: Basic zxc'
expireDate=$(date -d "+3 days")
body="Message."
while IFS=' ' read -r list
do
wow=$(curl --location --request POST $refLink \
--header 'Authorization: Basic $authorization' \
--header 'Content-Type: application/json' \
--data-raw '{
"title":"Expiration Notice",
"body":"$body",
"min" :[{"mobileNumber" : "$list"}],
"type" : "Notification",
"action_type" : "NotificationActivity"}')
echo "result: '$result'"
RESP=$(echo "$result" | grep -oP "^[^a-zA-Z0-9]")
echo "RESP:'$RESP'"
echo $body
#echo $wow >> logs.txt
psql -d $database -c "UPDATE tblname SET status='hehe' WHERE mobile='$list'"
done < $filename
Your "$list" JSON entry is not populated with the content of the $list variable because it is within single quotes of the --data-raw curl parameter.
What you need is compose your JSON data for the query before-hand, preferably with the help of jq or some other JSON processor, before sending it as argument to the curl's POST request.
Multiple faults in your scripts (not exhaustive):
Shebang is wrong with a space #! /bin/bash
expireDate=$(date -d "+3 days") return date in locale format and this may not be what you need for your request.
The request and the response data are not processed with JSON grammar aware tools. grep is not appropriate for JSON data.
Some clues but cannot fix your script more without knowing more about the API answers and functions you use.
Anyway here is how you can at least compose a proper JSON request:
#!/usr/bin/env bash
filename='/var/lib/postgresql/Script/list.txt'
database='dbname'
refLink='URL'
authorization='zxc'
expireDate=$(date -R -d "+3 days")
body="Message."
while IFS=' ' read -r list; do
raw_json="$(
jq -n --arg bdy "$body" --arg mobN "$list" \
'.action_type="NotificationActivity"|.title="Expiration Notice"|.type="Notification"|.body=$bdy|.min[0].mobileNumber=$mobN|.'
)"
json_reply="$(curl --location --request POST "$refLink" \
--header "Authorization: Basic $authorization" \
--header 'Content-Type: application/json' \
--data-raw "$raw_json")"
echo "json_reply: '$json_reply'"
echo "$body"
# psql -d "$database" -c "UPDATE tblname SET status='hehe' WHERE mobile='$list'"
done <"$filename"

Curl command in shell script returning error {"Error":"bpapigw-300 Cannot authorize access to resource"

I am trying to execute curl using this shell script:
#!/bin/bash
curl -k -H "Content-Type:application/json" -d '{"username":"admin","password":"adminpw", "tenant":"master"}' https://localhost/tron/api/v1/tokens > /tmp/token.data
grep -Po '{\"token\":\"\K[^ ]...................' /tmp/token.data > /tmp/token
tokendetails=`cat /tmp/token`
for token in $tokendetails
do
TOKEN=`echo $token`
done
userdetails=`cat /tmp/curloutput.txt | sed 's/{"clientInactivityTime"/\n{"clientInactivityTime"/g' | sed 's/\(.*\).\("firstName":[^,]*\)\(.*\)\("lastName":[^,]*\)\(.*\)\("email":[^,]*\)\(.*\)\("username":[^,]*\)\(.*\)/\2,\4,\6,\8/g' | grep username`
for user in $userdetails
do
firstName=`echo $user | sed 's/,/\n/g' | grep firstName | sed 's/.*:"\([^"]*\).*/\1/g'`
lastName=`echo $user | sed 's/,/\n/g' | grep lastName | sed 's/.*:"\([^"]*\).*/\1/g'`
email=`echo $user | sed 's/,/\n/g' | grep email | sed 's/.*:"\([^"]*\).*/\1/g'`
username=`echo $user | sed 's/,/\n/g' | grep username | sed 's/.*:"\([^"]*\).*/\1/g'`
curl -k -X POST "https://haxsne09/tron/api/v1/users" -H "accept: application/json" -H "Authorization: Bearer =${TOKEN}" -H "Content-Type: application/x-www-form-urlencoded" -d "first_name=${firstName}\&last_name=${lastName}\&email=${email}\&password=Tata123^\&username=${username}\&is_active=true"
echo $RESPONSE
done
I am getting ths error:
{"Error":"bpapigw-300 Cannot authorize access to resource: Could not authorize path for user identifier: Failed to get Roles for identifier: REST operation failed 0 times: '[GET /api/v1/current-user][401] currentUserListUnauthorized \u0026{Detail:Invalid token}'. This user is unauthenticated?"}
Do I need to add any syntax before executing curl -k -X POST?
What I see is that -H "Authorization: Bearer =${TOKEN}" contains an = sign which shouldn't be there...
It should be: -H "Authorization: Bearer ${TOKEN}"
More, in a command you use /tmp/curloutput.txt file, which is never created by your script...
The Authorization header you are using is not working. Maybe the syntax is not Bearer =aAbBcCdDeEfF0123456 but something else for the server running on haxsne09, maybe without the = like #MarcoS suggests.
Alternatively, your grep command may be returning one too many characters (a rogue quote maybe).
I rewrote your code below to be more readable. You will notice that I:
Changed your matching groups in sed to capture only the needed parts and put them in variables using read. I also used the -E flag to avoid having to use \( and \)
Removed the useless for loops
Quoted all variable expansions properly
Added some line breaks for readability
Removed some temporary files and associated useless uses of cat
Here is the updated script:
#!/bin/bash
curl -k -H 'Content-Type:application/json' -d \
'{"username":"admin","password":"adminpw", "tenant":"master"}' \
https://localhost/tron/api/v1/tokens > /tmp/token.data
token=$(grep -Po '{"token":"\K[^ ]...................' /tmp/token.data)
IFS=, read -r firstName lastName email username < <(
</tmp/curloutput.txt sed 's/{"clientInactivityTime"/\n&/' |
sed -nE 's/.*."firstName":"([^"]*)".*"lastName":"([^"]*)").*"email":"([^"]*).*"username":"([^"]*)".*/\1,\2,\3,\4/p'
)
curl -k -X POST 'https://haxsne09/tron/api/v1/users' -H 'accept: application/json' \
-H "Authorization: Bearer $token" -H "Content-Type: application/x-www-form-urlencoded" -d \
"first_name=$firstName&last_name=$lastName&email=$email&password=Tata123^&username=$username&is_active=true"
echo

Passing arguments values to shell script

I'm using the following script to purge cache from cdn,
#!/bin/bash
## API keys ##
zone_id=""
api_key=""
login_id=""
akamai_crd=""
## URL ##
urls="$1"
[ "$urls" == "" ] && { echo "Usage: $0 url"; exit 1; }
echo "Purging $urls..."
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/${zone_id}/purge_cache" \
-H "X-Auth-Email: ${login_id}" \
-H "X-Auth-Key: ${api_key}" \
-H "Content-Type: application/json" \
--data "{\"files\":[\"${urls}\"]}"
#echo "CF is done now purging from Akamai ..."
echo "..."
curl -v -s https://api.ccu.akamai.com/ccu/v2/queues/default -H "Content-Type:application/json" -d '{"objects":["$urls"]}' -u $akamai_crd
The 1st part for cloudflare is working fine the 2nd part when I pass it to Akamai
["$urls"]
I keep getting an error and it's passing the url as an argument it returns the variable itself ($urls) not the arg value.
I ran the script as following:
sh +x script.sh url
Any advise here?
First i would change this:
SCRIPTNAME=$(basename "$0")
...
if [ $# != 1 ] then
echo "Usage: $SCRIPTNAME url"
exit
fi
$urls="$1"
Change your second curl command as the following (you need to escape the quotes):
--data "{\"files\":[\"${urls}\"]}"
Avoid creating JSON by hand like this; you can't guarantee that the resulting JSON is properly escaped. Use a tool like jq instead.
#!/bin/bash
## API keys ##
zone_id=""
api_key=""
login_id=""
akamai_crd=""
## URL ##
url=${1:?Usage: $0 url}
headers=(
-H "X-Auth-Email: $login_id"
-H "X-Auth-Key: $api_key"
-H "Content-Type: application/json"
)
purge_endpoint="https://api.cloudflare.com/client/v4/zones/${zone_id}/purge_cache"
echo "Purging $url..."
jq -n --arg url "$url" '{files: [$url]}' |
curl -X DELETE "$purge_endpoing" "${headers[#]}" --data #-
#echo "CF is done now purging from Akamai ..."
echo "..."
jq -n --arg url "$url" '{objects: [$url]}' |
curl -v -s -H "Content-Type:application/json" -d #- -u "$akamai_crd"

Resources