Jenkins pipeline use variable inside shell and curl - shell

I would like to use a variable inside a curl and shell command, the command is :
sh """\ oc exec pod-test -c "conttest" -- \\ /bin/bash -c 'curl X POST \\ -u "usr:pass" \\ -H "content-Type:application/json" \\ -d "{\"id\": \"1\"} \\ http://127.0.0.1:8080/tym/api/obj/$profile/add"' """.stripIndent()
the variable profile is not replaced correctly and i have this error : command terminated with exit 3

Be sure you use the right string syntax espacially escaping characters like " and \.
You can use variables in strings like this
"${profile}"
For more information about groovy and strings see https://www.tutorialspoint.com/groovy/groovy_strings.htm

Related

How can I pass all arguments to another command, some of which are quoted and contain spaces?

I want to pass multiple arguments through to curl. Some of these arguments are quoted and contain spaces.
I have tried like this:
ARGS="http://example.org -H 'My-Header: Foo'"
curl -vvv $ARGS
But my header is not set and I get an error at the end curl: (6) Could not resolve host: Foo'.
I have also tried quoting ARGS like this:
ARGS="http://example.org -H 'My-Header: Foo'"
curl -vvv "$ARGS"
But I get curl: (3) URL using bad/illegal format or missing URL.
If I just run curl with the arguments directly, then it works fine:
curl -vvv http://example.org -H 'My-Header: Foo'
How can I pass these arguments through to curl correctly?
There is a command called eval which evaluates all the arguments into one string and then runs it as a one big command.
Try eval curl $ARGS
I recommend you to checkout eval's man page ;)

Optionally include a user and password in curl request?

I am optionally including a user and password in a curl request as follows:
declare creds=""
if [ -n "$user" ] && [ -n "$password" ]; then
creds="-u ${user}:${password}"
fi
output=$(curl ${creds} -X PUT -v --write-out "%{http_code}" "$url" \
-H 'Content-Type: application/json' -s -o /dev/null --data "${payload}")
This seems to work fine, but I'm getting this shellcheck warning:
Double quote to prevent globbing and word splitting
https://github.com/koalaman/shellcheck/wiki/SC2086
Puting quotes around it doesn't work, e.g. if I do this:
output=$(curl "${creds}" -X PUT -v --write-out "%{http_code}" "$url" \
-H 'Content-Type: application/json' -s -o /dev/null --data "${payload}")
then when the username and password are not supplied, this results in empty double quotes in the curl request curl "" -X PUT ..., which generates a <url> malformed error.
I could use an if-else for the curl command, but I'd rather avoid the duplication. Is the above approach acceptable despite the shellcheck warning?
You were doing right in putting quotes around the variable, but shellcheck doesn't catch the issue of storing commands in a variable which has its own downfalls. Since this being a an issue with function of the shell, shellcheck can't quite catch it out-of-the-box. When you did below
creds="-u ${user}:${password}"
and quoted "$creds", it is passed as one single argument word to curl instead of being broken down to -u and "${user}:${password}" separately. The right approach should have been to use an array to store the commands and expand it, so that the words are preserved and not split by the shell (foremost reason to quote the variable, as indicated by shellcheck)
creds=(-u "${user}:${password}")
and invoke
curl "${creds[#]}" <rest-of-the-cmd>
Also explore the following
I'm trying to put a command in a variable, but the complex cases always fail!
How to store a command in a variable in a shell script?

How i can safe the curl result in a bash variable

When i run the command
curl -d "param1=value1&param2=value2" -X POST https://xxx.xxxx.de/xx/xx.php 2>/dev/null on the normal command line i get the requested result {"success":false,"cause":"Token needed"}.
I need this result on a bash script but when i try to run it
curl = "$(curl -d "param1=value1&param2=value2" -X POST https://xxx.xxxx.de/xx/xx.php 2>/dev/null)"
echo $curl
I don't recieve the requested result i recieve this
[1/2]: "success":false --> <stdout>
--_curl_--"success":false
curl: (3) URL using bad/illegal format or missing URL
[2/2]: "cause":"Token needed" --> <stdout>
--_curl_--"cause":"Token needed"
curl: (3) URL using bad/illegal format or missing URL
How i can use the correct result in my bash script ?
Your command is not a variable assignment, it tries to executes curl with arguments = and the output of the command substitution. Remove the space characters before and after = and you may omit the quotes around the command substitution (this is one of the few occasions where quotes are not needed).
curl=$(curl -d "param1=value1&param2=value2" -X POST https://xxx.xxxx.de/xx/xx.php 2>/dev/null)
echo "$curl"

Percent sign % not working in crontab

I have a cron issue with curl:
curl -w "%{time_total}\n" -o /dev/null -s http://myurl.com >> ~/log
works great and add a line in log file with total_time.
But the same line with cron doesn't do anything.
It's not a path problem because curl http://myurl.com >> ~/log works.
% is a special character for crontab. From man 5 crontab:
The "sixth" field (the rest of the line) specifies the command to be
run. The entire command portion of the line, up to a newline or a
"%" character, will be executed by /bin/sh or by the shell specified
in the SHELL variable of the cronfile. A "%" character in the
command, unless escaped with a backslash (\), will be changed into
newline characters, and all data after the first % will be sent to
the command as standard input.
So you need to escape the % character:
curl -w "%{time_total}\n" -o /dev/null -s http://myurl.com >> ~/log
to
curl -w "\%{time_total}\n" -o /dev/null -s http://myurl.com >> ~/log
^

curl -F line break not interpreted correctly

I'm trying to send a notification via pushover using curl in a bash script.
I cannot get curl -F to interpret the line break correctly though.
curl -s \
-F "token=TOKEN" \
-F "user=USER" \
-F "message=Root Shell Access on HOST \n `date` \n `who` " \
https://api.pushover.net/1/messages.json > NUL
I've tried:
\n
\\\n
%A0
I'd rather push the message out directly, not through a file.
curl doesn't interpret backslash escapes, so you have to insert an actual newline into the argument which curl sees. In other words, you have to get the shell (bash in this case) to interpret the \n, or you need to insert a real newline.
A Posix standard shell does not interpret C escapes like \n, although the standard utility command printf does. However, bash does provide a way to do it: in the quotation form $'...' C-style backslash escapes will be interpreter. Otherwise, $'...' acts just like '...', so that parameter and command substitutions do not take place.
However, any shell -- including bash -- allows newlines to appear inside quotes, and the newline is just passed through as-is. So you could write:
curl -s \
-F "token=$TOKEN" \
-F "user=$USER" \
-F "message=Root Shell Access on $HOST
$(date)
$(who)
" \
https://api.pushover.net/1/messages.json > /dev/null
(Note: I inserted parameter expansions where it seemed like they were missing from the original curl command and changed the deprecated backtick command substitutions to the recommended $(...) form.)
The only problem with including literal newlines, as above, is that it messes up indentation, if you care about appearances. So you might prefer bash's $'...' form:
curl -s \
-F "token=$TOKEN" \
-F "user=$USER" \
-F "message=Root Shell Access on $HOST"$'\n'"$(date)"$'\n'"$(who)" \
https://api.pushover.net/1/messages.json > /dev/null
That's also a little hard to read, but it is completely legal. The shell allows a single argument ("word") to be composed of any number of quoted or unquoted segments, as long as there is no whitespace between the segments. But you can avoid the multiple quote syntax by predefining a variable, which some people find more readable:
NL=$'\n'
curl -s \
-F "token=$TOKEN" \
-F "user=$USER" \
-F "message=Root Shell Access on $HOST$NL$(date)$NL$(who)" \
https://api.pushover.net/1/messages.json > /dev/null
Finally, you could use the standard utility printf, if you are more used to that style:
curl -s \
-F "token=$TOKEN" \
-F "user=$USER" \
-F "$(printf "message=Root Shell Access on %s\n%s\n%s\n" \
"$HOST" "$(date)" "$(who)")" \
https://api.pushover.net/1/messages.json > /dev/null

Resources