Reputation: 1554
I don't understand why this works
dateCMD=$(date -d "4 hours ago")
echo $dateCMD
Tue Oct 18 02:20:34 AEDT 2016
and this works
dateCMD="date"
$dateCMD
Tue Oct 18 06:23:19 AEDT 2016
But not this
dateCMD='date -d "4 hours ago"'
$($dateCMD)
date: extra operand ‘ago"’
How can I get this last case to work?
Upvotes: 2
Views: 64
Reputation: 1554
To get the last case to work, you can use eval
Of course you should not use eval on any user input without completely validating that input.
dateCMD='date -d "4 hours ago"'
eval $dateCMD
Upvotes: 0
Reputation: 532268
Short answer: you don't want to do that. Use a function instead.
dateCMD () {
date -d "4 hours ago"
}
dateCMD
Long answer: quotes in the value of a parameter are not "syntactic" quotes; they are just regular data. When you write
dateCMD='date -d "4 hours ago"'
$($dateCMD)
It is evaluated as follows:
$dateCMD
expands to date -d "4 hours ago"
date
, -d
, "4
, hours
, and ago"
. The quotes are not treated specially.date
, is treated as the command with the rest of the words passed as distinct arguments.date
treates "4
as the argument to the -d
option. Since date
takes only one additional positional argument (the format string), it takes hours
as that argument, then complains that ago
is an extra operand. Upvotes: 6
Reputation: 786091
Use BASH array to make it work:
dateCMD=(date -d "4 hours ago")
"${dateCMD[@]}"
Mon Oct 17 11:38:54 EDT 2016
I was typing explanation on your quoting problem but then I noticed very well explained answer from @chepner so avoided adding redundant information in my answer.
Upvotes: 2