I'm trying to setup a simple backup script with tar as you can see below:
#!/bin/bash
TIME=`date +%F_%H-%M`
FILENAME=backup-$TIME.tar.gz
SRCDIR="~/PI/tutos/* ~/scripts/*"
DESTDIR=/media/sf_ubuntuSharedFolder/backups
tar cvpzf $FILENAME $SRCDIR
However, the usage of $SRCDIR causes a tar error that I do not have if I just expand it myself.
alex@ALeX-VirtualBox:~$ save
tar: ~/PI/tutos/*: Cannot stat: No such file or directory
tar: ~/scripts/*: Cannot stat: No such file or directory
What is wrong here at using a shell variable? Otherwise, how can I pass a list of folders to tar in a single line?
Best Answer
The issue is that
~
-expansion is not performed upon variable expansion (when you refer to that$SRCDIR
unquoted) nor inside double quotes (when you assign thatSRCDIR
variable).In leaving
$SRCDIR
unquoted, you're invoking the split+glob operator. That is the string that is stored in that scalar$SRCDIR
variable (~/PI/tutos/* ~/scripts/*
) is first split according to$IFS
(blanks by default), and then each word undergoes globbing, that is are treated as patterns that expand to the list of matching files.Because
~
is not expanded to your home directory there, that~
is just treated like any other character, so it's just looking for files in the~/PI/tutos
directory, where~
would be a directory in the current directory, which in your case doesn't exist.Best here would be to make
$SRCDIR
an array and have the globs expanded at the time of the assignment:Note that applying the split+glob operator on
$FILENAME
doesn't make sense, so we're disabling it by quoting$FILENAME
.Note that if
~/PI/tutos/*
doesn't match, it will be left as-is, so you'd still get an error fromtar
. To avoid that, you could do:You may be tempted to do:
As variables (such as
$HOME
) are expanded within double quotes, but I would advise against it as that wouldn't work properly if$HOME
contains glob characters or characters of$IFS
.~
s are expanded in variable assignments when not quoted and when at the start or following:
(that's so that it works in assignments of variables like$PATH
,$LD_LIBRARY_PATH
... such asPATH=~/bin:~/sbin
). So you may be tempted to do:But that's the same as above, that won't work properly if
$HOME
contains$IFS
characters (this time:
, so very unlikely as/etc/passwd
that defines your home directory is a colon-separated table) or glob characters.