0

As a fun side project, I'm building a serverless Todo application on AWS. I do a lot in the terminal, but my knowledge is basic.

The command to add something into my DynamoDB table via the AWS CLI (v2.3.4) is this:

aws dynamodb put-item \ --table-name tasks \ --item \ '{"task_id": {"S": "3495353e-726f-4e0e-b290-8014c03be971"}, "user_id": {"S": "aae30f8e-aabe-4e38-918f-0f5a2223f589"}, "created_at": {"S": "2022-09-09T12:51:05Z"}, "content": {"S": "Clean car"}, "is_done": {"BOOL": false}}' \ --profile personal 

Notice that for created_at I'm manually typing in the ISO-8601 date as a string.

Now I know that on linux, in order to get the UTC datetime in the ISO-8601 format I need to run:

date -u +"%Y-%m-%dT%H:%M:%SZ" 

My question is, how do I fit that into my DynamoDB put-item command so that I automatically/dynamically get the created_at from my linux system.

What I have tried:

I tried to simply plunk the date command into my DynamoDB command where the created_at value would go like this:

aws dynamodb put-item \ --table-name tasks \ --item \ '{"task_id": {"S": "3495353e-726f-4e0e-b290-8014c03be971"}, "user_id": {"S": "aae30f8e-aabe-4e38-918f-0f5a2223f589"}, "created_at": {"S": date -u +"%Y-%m-%dT%H:%M:%SZ"}, "content": {"S": "Clean car"}, "is_done": {"BOOL": false}}' \ --profile personal 

But that doesn't work. The command errors out and it returns with:

Error parsing parameter '--item': Invalid JSON: Expecting value: line 1 column 138 (char 137) JSON received: {"task_id": {"S": "3495353e-726f-4e0e-b290-8014c03be971"}, "user_id": {"S": "aae30f8e-aabe-4e38-918f-0f5a2223f589"}, "created_at": {"S": date -u +"%Y-%m-%dT%H:%M:%SZ"}, "content": {"S": "Clean car"}, "is_done": {"BOOL": false}} 

Update:

I just tried the $(command) method as suggested by Marcus, and I still get the invalid JSON error.

aws dynamodb put-item \ --table-name tasks \ --item \ '{"task_id": {"S": "3495353e-726f-4e0e-b290-8014c03be971"}, "user_id": {"S": "aae30f8e-aabe-4e38-918f-0f5a2223f589"}, "created_at": {"S": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"}, "content": {"S": "Clean car"}, "is_done": {"BOOL": false}}' \ --profile personal 
0

    2 Answers 2

    1

    You could use jq to insert the date into the json object:

    aws dynamodb put-item \ --table-name tasks \ --item "$( jq -c '.created_at.S=(now|todate)' << 'EOF' { "task_id": { "S": "3495353e-726f-4e0e-b290-8014c03be971" }, "user_id": { "S": "aae30f8e-aabe-4e38-918f-0f5a2223f589" }, "created_at": {"S":""}, "content": { "S": "Clean car" }, "is_done": { "BOOL": false } } EOF )" --profile personal 

    Also note that you can format dates in zsh without having to invoke date:

    ${(%):-%D{%FT%TZ}} expands to the current time in that format, though you'd have to set TZ=UTC0 to get actual Zulu time. There's also a strftime builtin in the zsh/datetime module.

    3
    • Thank you, this did the trick!
      – J86
      CommentedSep 11, 2022 at 12:07
    • It should say expands to the current local time in that format. And adding a trailing Z is claiming that the time is UTC (Zulu) while that will only be true if the local time used is UTC. It is better to format as ${(%):-%D{%FT%T%Z%z}}. In that way it will be clear what the timestamp means.CommentedSep 11, 2022 at 12:47
    • If I wanted to add a modified_at field to my JSON, how would change the command above Stephane?
      – J86
      CommentedOct 27, 2022 at 9:58
    1

    As the error message highlights, the JSON is invalid.

    So, as to be expected, the command you wanted to be executed never was – how was the shell supposed to know which parts of the command line you wanted to pass unaltered, and which one you want executed?

    If you want to substitute a command's output, use $(command), e.g., $(date -u +"%Y-%m-%dT%H:%M:%SZ")

    6
    • Thanks Marcus, I must be missing something, cause even after trying your suggestion, I still get the same error about invalid JSON.
      – J86
      CommentedSep 9, 2022 at 15:13
    • Here is a screenshot that shows the syntax highlighting from zsh. It looks like it still doesn't recognise the $(command) format.
      – J86
      CommentedSep 9, 2022 at 15:22
    • well, sure, within ' it doesn't! You'll need to escape your JSON differently. It might really be easier to write the JSON to a file first, do a replacement on that, and use that.CommentedSep 9, 2022 at 15:28
    • Thanks, I don't want to go the "JSON in a separate file" route cause I want to easily change values right from within the command. Hopefully someone know of a way to easily escape the JSON and make it work with the $(command)
      – J86
      CommentedSep 9, 2022 at 15:37
    • As said, you simply can't use ' to quote the string if you want anything within to be expanded. So, you need to use " as quoting, but then all the " within the JSON itself need to be escaped \".CommentedSep 9, 2022 at 15:42

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.