0

I need to tar some files, where one is a dotfile.

FILE1=/tmp/foo/.env
FILE2=/tmp/foo/docker-compose.yml

FILES="${FILE1#/} ${FILE2#/}"

tar -C / -cf /tmp/foo/files.tar "$FILES"

The variable substitution avoids the tar: Removing leading '/' from member names warning, and simplifies untarring.

But I get this error:

tar: tmp/foo/.env tmp/foo/docker-compose.yml: Cannot stat: No such file or directory

Hardcoding the paths works: tar -C / -cf /tmp/foo/files.tar tmp/foo/.env tmp/foo/docker-compose.yml.

So I assume the problem is in handling that dotfile, or something to do with escaping?

3
  • If you like to archive two files, you should give two file arguments instead of just one.
    – schily
    Mar 23, 2020 at 12:33
  • If you put things into double quotes, the result is one single argument.
    – schily
    Mar 23, 2020 at 12:38
  • @schily Thanks, just tried your way and it works!
    – lonix
    Mar 23, 2020 at 12:42

1 Answer 1

2

When the shell expands "$FILES", the space loses its syntactical value. So the tar command receives tmp/foo/.env tmp/foo/docker-compose.yml as a single path.

Just as

file='a b'
touch "$file"

will create file a b, not two files a and b.

So, as suggested in comment, you should use different variables for different files: tar -C / -cf /tmp/foo/files.tar "${FILE1#/}" "${FILE2#/}".


The fact that directly running tar -C / -cf /tmp/foo/files.tar tmp/foo/.env tmp/foo/docker-compose.yml works is because the spaces have syntactical value there, separating one argument from another. To the "human eyes", the same space will be produced after the expansion of "$FILES" to tmp/foo/.env tmp/foo/docker-compose.yml, but in this case the space has no special meaning because of the quoting, so the whole value will be treated as a single path.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .