3

Hi there I am trying to have

curl -v --request POST https://example.com --data-urlencode "username=usr]” --data-urlencode "password=[pass]”

pass the output to the [TOKEN] field in here:

curl -D - --request POST https://example.com --data-urlencode token=[TOKEN]

However, I am unfamiliar with JSON as my output for the first command is

{
    "token": "value_of_token"
}

How would I take just "value_of_token" and get it to be [TOKEN]?

3

To most efficiently take just value_of_token from the output of the curl command, pipe the output to a single sed (stream editor) command. Use command substitution $() to store the output in a shell variable:

token=$(curl ... | sed -n '/ *"token": *"/ { s///; s/".*//; p; }')

Then you can reference the variable token as a parameter to the second curl command:

curl ... token="$token"

Explanation of the sed command:

sed -n '/ *"token" *: *"/ { s///; s/".*//; p; q; }'
  • -n option tells sed to not print every input line

  • / *"token" *: *"/ addresses the line containing the value. This pattern (regular expression) matches the entire beginning of the line, up to and including the first double quote delimiting the token value.

  • { begin a command block which will be applied to the addressed line.

  • s///; a sed command to delete what was previously matched (in the address part). The line ("pattern space") now looks like: value_of_token"

  • s/".*// sed command to delete the remaining double quote (") and everything after.

  • p sed command to print the current (edited) line ("pattern space" in sed terminology).

  • q Immediately quit the sed script without processing any more input

  • '}' end the command block.

For example,

$ echo '
{                          
    "token": "value_of_token"
}
' | sed -n '/ *"token" *: *"/ { s///; s/".*//; p; }'
value_of_token
$

This method is much more efficient than piping 4 other commands together to achieve the same result. This sed command assumes there are no tab characters in the JSON input. If tabs exist, the sed command will require modification.

0

First, please note that I had to replace the URL you have in your commands with <URL> because stackexchange thought I was spamming and wouldn't let me post.

OK, you have two questions here:

1) How do you take the output of one command and make it an argument of another command?

answer: The most canonical method would be to use shell's command substitution by replacing your argument in the second command with $( <first command> ) like so:

curl -D - --request POST <URL> --data-urlencode token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” )

However, for readability purposes, you really should do this in separate lines by saving the output from the first command and reusing it like so:

token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” )
curl -D - --request POST <URL> --data-urlencode token="$token"

Also, for completeness and because you asked specifically how to "pipe", you could use the xargs command instead of shell's command substitution:

curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” | xargs "curl -D - --request POST <URL> --data-urlencode token="{}

However, as you noted, your output from the first command isn't quite what you're looking for as your token; thus the above solutions would not work as you expect, which brings us to your next question:

2) How can we isolate just "value_of_token" from the entire JSON output?

Without getting into some JSON API, a simple pipelining of grep, head and cut should do the job:

token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” ) | grep '"token":' | head -1 | cut -d ':' -f 2 | cut -d '"' -f 2
curl -D - --request POST <URL> --data-urlencode token="$token"

Note, the head -1 is just in case there happen to be multiple token lines from the output, in which case only the first is used.

You should know that this isn't a very robust solution if this application is important. If it is, you should really check the return code of and do more extensive validation of the output from the first curl command so that you don't get some unexpected results; but that would require a larger script and is beyond the scope of this question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.