[Techtalk] Shell expansion and quote removal nightmare

Almut Behrens almut-behrens at gmx.net
Tue Jan 7 03:50:29 EST 2003


On Mon, Jan 06, 2003 at 06:20:25PM -0500, Brenda Bell wrote:
> 
> I'm trying to write a script that collects a bunch of data and 
> dynamically constructs the arguments for a tar command... like either of 
> the following:
> 
>     tar --create --file test.tar list-of-files
>     tar --create --after-date "valid-date-here" --file test.tar 
> list-of-files
> 
> Note that the tar command may or may not use the --after-date option 
> depending on input to the script.  Also note that the argument for 
> --after-date comes from a file and is in the default format you get from 
> date.
> 
> I incorrectly assumed I could construct a shell variable TARPARM1 whose 
> value is either "" or "--after-date 'valid-date-here'" and execute tar 
> ${TARPARM1}.

the trick is to use an "eval" in front of the tar command, e.g.

  #!/bin/bash
  
  AFTERDATE="--after-date '`date -d yesterday`'"
  
  eval tar --create $AFTERDATE --file test.tar *

The first interpolation (variable expansion) happens when the
arguments for the eval get prepaired. The second interpolation
during the execution of the eval then realises that the substring
'Mon Jan 6 02:24:32 CET 2003' is only *one* argument. Without the
eval, the shell passes all (space-separated) arguments individually
as single entities to tar, and tar itself does not handle quoting
across multiple arguments. You can observe this behaviour using
strace (-f), which shows you something like

...
execve("/bin/tar", ["tar", "--create", "--after-date", "\'Mon", "Jan", "6", "02:24:32", "CET", "2003\'", "--file", "test.tar", ...
...

Whether you call this a bug or not is up to you... ;)

Almut



More information about the Techtalk mailing list