5

I often use backticks in with long commands that I break up with backslash-newlines for readability. When I replace the backticks with the $( ... ) syntax, I get errors.

For instance, I set a variable using curl and jq inside backquotes (reading from my Trello daily to-do list and returning card.id and card.name for everything but a specific card):

AllCardsInDTL=\
`\
curl -s "https://api.trello.com/1/lists/$DailyTasksListID/cards\
?$WhoMe\
&fields=name,id,pos\
"\
| jq  '\
    .[] | \
    if .name | test ("Tasks here are copied.*") \
    then empty \
    else .id, .name \
    end \
    '\
`  # End of AllCardsInDTL=

That has no problems and the shell variable consists of alternating lines of ID and Name values.

But if I replace the backquoteswith $( ... ), I get an error from jq:

jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
\
jq: 1 compile error
(23) Failed writing body

It's not clear to me from the error, whether the ) is not actually terminating the command started by $( or whether inside the $( ... ) the backslash is not being interpreted as I expect.

I would like to be able to use the $( ... ) syntax because there are times when I want to nest one subshell inside another and that's very difficult to do with backquotes.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
August
  • 343
  • 3
  • 10
  • Please show the code where the backticks are replaced with `$(...)`, or at least the two lines of code in question. – agc Oct 28 '20 at 08:59

2 Answers2

7

You can certainly use \ to escape end-of-lines inside a $(...) expression. Also note that you don't need those \'s in the jq expression inside the single quotes.

I would probably write it something like this:

AllCardsInDTL=$(
curl -s "https://api.trello.com/1/lists/$DailyTasksListID/cards\
?$WhoMe\
&fields=name,id,pos" |
jq  '.[] |
    if .name | test ("Tasks here are copied.*")
    then empty
    else .id, .name
    end
    '
)

I can't test this, since I don't have a useful value for $DailyTasksListID nor am I equipped to authenticate to trello at the moment.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • Thanks for the tip about not needing the backslashes inside the jq singlequotes. I notice the pipe at the end of the line between the curl and jq does not have a backslash in your version. Is that generally allowable in bash scripts or is only inside the $(...) here? – August Oct 29 '20 at 03:09
  • That's generally allowable in bash scripts. – larsks Oct 29 '20 at 03:53
  • I really like breaking up long command lines to be able to more easily read the flow so this tip will save me a LOT of backslashes. Thanks. – August Oct 30 '20 at 07:56
0

Yes. Demo:

echo $(echo foo
echo bar
echo baz
)

Output:

foo bar baz
agc
  • 7,973
  • 2
  • 29
  • 50
  • Ah! the internal three echo commands will put one word per line but that is then sent to echo again which puts them all on one line. I think I'm catching on. Thanks. – August Oct 29 '20 at 03:11
  • 2
    ...and note that if you put quotes (`"`) around the `$(...)` expression, it will then preserve newlines. – larsks Oct 29 '20 at 03:54