does the trick:
for i in 1 2; do
cmd="date --date=\"$i days ago\""
See also: Uwe Waldmann - A Guide to Unix Shell Quoting - Common misconceptions
Before the shell executes a command, it performs the following operations (check the manual for details):
1. Syntax analysis (Parsing)
2. Brace expansion
3. Tilde expansion
4. Parameter and variable expansion
5. Command substitution
6. Arithmetic expansion
7. Word splitting
8. Filename expansion
9. Quote removal
It is important to realize that parsing takes place before parameter and command substitution. The result of a step n
is subject to the next steps (n+
), but the preceding steps (n-
) are not re-executed. In other words: after for example variable expansion (step 4) the result is not
re-parsed (step 1).
In the example of the command:
$cmd # cmd="date --date=\"1 days ago\""
the command date --date=\"$i days ago\"
is the result of variable expansion (step 4). Quote removal (step 9) removes the backslashes and turns the command into date --date="$i days ago"
. But since parsing (step 1) already has taken place, "1 days ago" is not seen as 1 argument but as 3 separate arguments: "1
, which gives you the error message:
date: extra operand `ago"'
Try `date --help' for more information.
To force one more run through the parsing/expansion procedure, use:
Now first $cmd
is expanded (steps 1-9) to date --date="1 days ago"
. Then eval
causes the expanded string to be re-parsed again (steps 1-9), resulting in the correct command:
date --date="1 days ago"
Wed Nov 29 08:11:46 CET 2006