Quoting space in bash script - bash

I have a script which needs to pass a string containing a space.
Basically, I want to collect the error return of calling curl "https://my-api.com" -H'X-API-Key: API key here'
The following works, but I'd really rather avoid using eval. I'm sure there is a cleaner way of writing this, but I can't find it.
CURL="curl -s --fail $URL -H\"X-API-Key:$API_KEY\""
return $(eval "$CURL" >> /dev/null)

This is a duplicate of Dynamically building a command in bash, but here is the fix for your code.
Please take the time to read the answers from the parent question.
# Build the curl command with its arguments in an array
curl_cmd=(curl -s --fail "$URL" -H "X-API-Key:$API_KEY")
# Execute the curl command with its arguments from the curl_cmd array
"${curl_cmd[#]}"

Related

curl set dynamic header token throws invalid key

Im trying to hit a rest api with token in header.
apikeyName="$(date '+%s')"
key=$(curl -k -X POST -H "Content-Type: application/json" \
-d '{"name":"'$apikeyName'", "role": "Admin"}' \
http://admin:admin#localhost:3000/api/auth/keys | jq '.key')
echo $key
# # Alerting API
curl -k -X GET 'http://localhost:3000/api/alert-notifications' -H 'Authorization: Bearer '$key'';
Terminal output
"eyJrIjoiaWJPaDFFZXZMeW1RYU90NUR4d014T3hYUmR6NDVUckoiLCJuIjoiMTY3NTM1OTc4OCIsImlkIjoxfQ=="
{"message":"invalid API key","traceID":""}
First 1 is the key printing and last one from api response. I tried to hardcode the key and it works.
Short answer: Use jq -r '.key' to extract the key from the json response without adding quotes to it.
Long answer: There is a difference between quotes on the command line and quotes embedded in a variable. Consider:
key='"abcd"'
printf '%s\n' $key "abcd"
# prints:
# "abcd"
# abcd
Quotes on the command line are bash syntax. Bash notes what is being quoted and then removes the quotes from the command line when it's done, thus printf only prints abcd in the second case above.
Quotes inside a variable are plain old data. Bash doesn't do anything with them, so they get passed through to the command like any other data and printf prints "abcd" in the first case.
In your curl case the receiver doesn't expect the key to have quotes embedded in the data. So, curl -blah "keydata" works fine because bash takes the quotes out, but curl -blah $key fails because bash does NOT remove the embedded quotes.
See also: BashParser

Running an alias in a bash script gives me `<arguments>: command not found`

I have a script with an alias _test. It works fine, but before printing the output, it does <arguments>: command not found. For example, _test -h gives line 49: -h: command not found
This is a minimal example:
alias _test='
echo Hi
'
shopt -s expand_aliases
_test -h
EDIT: For those asking about using functions, I did in fact, used to have a function instead -- but it started to cause recursion problems. I just wanted something similar to a macro -- something that acts as if the text was inserted into the script.
EDIT 2: I just realized why I kept having recursion with my function/alias. I fixed it, and I switched back to a function, but this question may help someone else.
Remove the newlines. As written, _test -h expands to this, with a blank line above and below the echo:
echo Hi
-h
Make it a one-line alias:
alias _test='echo Hi'
In general, though, avoid aliases. They're really intended for convenience in interactive shells. In a script—or heck, even in interactive shells—it's better to use functions instead. For example:
_test() {
echo Hi "$#"
}
For those asking about using functions, I did in fact, used to have a function instead -- but it started to cause recursion problems. I just wanted something similar to a macro -- something that acts as if the text was inserted into the script.
Were you trying to wrap an existing command, like this?
alias ls='ls --color=auto -F'
If so you can use command to prevent a function calling itself recursively. The equivalent function would be:
ls() {
command ls --color=auto -F "$#"
}
command ls calls the ls command rather than the ls function we've just defined so we don't get stuck in an infinite recursive loop.
Thanks to Kugelman's answer, I was able to solve it with
alias _test='
echo Hi
true'
shopt -s expand_aliases
_test -h

curl command works manually but not in script

I have a curl command in a script, when the script is run the command isn't able to fetch a resource (the command itself works, it's the response that's incorrect), but if I copy and paste the same command into the terminal I get the expected response.
After reading this my script looks like this:
jsess=`awk '/\sJSESSION/ { print "\x27"$6"="$7"\x27" }' cookies.txt`
ARGS=( -k -v -b $jsess $url7)
echo "curl ${ARGS[*]}"
curl "${ARGS[#]}"
and the last echo looks like this:
curl -k -v -b 'JSESSIONID=hexystuff' https://secretstuff.com
The last curl doesn't work, but copy-pasting that echo works. Any ideas what could be wrong? Thanks.
The problem seems in the two single quotes, try this :
jsess="$(awk '/\sJSESSION/ { print $6"="$7 }' cookies.txt)"
ARGS=( -k -v -b "$jsess" "$url7")
echo "curl ${ARGS[*]}"
curl "${ARGS[#]}"
args="-k -v -b"
jsess=$(awk '/\sJSESSION/ { print "\x27"$6"="$7"\x27" }' cookies.txt)
url7="https://secretstuff.com"
curl "${args}" "${jsess}" "${url7}"
The use of arrays is not my personal preference, and I believe the current situation demonstrates why. I believe that as much as possible, every individual item of data should be contained in its' own variable. This makes accessing said variables much simpler, and also greatly increases flexibility. I can choose exactly which pieces of information will go into a given command line.

How can I check that a Bash script argument is a user-defined function?

I need to validate that, when running a bash script via the command line, the user is calling, as their first argument, one of the user defined functions in the same script. I know that there is a built in bash command "type," so I am trying to use that. However, I can't seem to get it to work - even when I run the script in -x mode, what is returned from "type -t $1" is just an empty string.
I have tried $(type -t $1), $(type -t "$1"), if [ $(type -t "$1") = "foo"], etc.
Nothing is ever indicated when I test with a function that it is a function, and nothing is returned when I try to validate. I am very new to Bash scripting, apologies if this question is asked elsewhere, I couldn't find it.

curl command not accepting input from file

I'm trying to run a curl command such as:
curl -Sks -XPOST https://localhost:9999/some/local/service -d 'some text arguments'
The above works fine. However, when I place
'some text arguments'
in a file and call the command as:
curl -Sks -XPOST https://localhost:9999/some/local/service -d `cat file_with_args`
I get many exceptions from the service. Does anyone know why this is?
Thanks!
If the file contains 'some text arguments', then your command is equivalent to this:
curl -Sks -XPOST https://localhost:9999/some/local/service -d \'some text arguments\'
— that is, it's passing 'some, text, and arguments' as three separate arguments to curl.
Instead, you should put just some text arguments in the file (no single-quotes), and run this command:
curl -Sks -XPOST https://localhost:9999/some/local/service -d "`cat file_with_args`"
(wrapping the `cat file_with_args` part in double-quotes so that the resulting some text arguments doesn't get split into separate arguments).
Incidentally, I recommend writing $(...) rather than `...`, because it's more robust in general (though in your specific command it doesn't make a difference).

Resources