There are very few files that absolutely must be different between two machines, and need to be regenerated when cloning:
- The host name
/etc/hostname
.
- The SSH host keys:
/etc/ssh_host_*_key*
or /etc/ssh/ssh_host_*_key*
or similar location.
- The random seed:
/var/lib/urandom/random-seed
or /var/lib/random-seed
or similar location. (/var/lib/systemd/random-seed
on systems using systemd)
Anything else could be identical if you have a bunch of identical machines.
A few files are typically different on machines with different hardware:
/etc/fstab
, /etc/crypttab
, /etc/mdadm.conf
, and bootloader configuration files (if located in /etc
— some distributions put them in /boot
) if disks are partitioned differently.
/etc/X11/xorg.conf
, if present, if the machines have different graphics cards.
- Modules to load or blacklist in
/etc/modules
, /etc/modprobe.conf
, /etc/modprobe.d/
and /etc/modutils/
.
In addition, some network configuration may need to change, in particular:
- If you have static IP addresses, they need to be diversified per machine. The location of IP configuration varies between distribution (e.g.
/etc/network/interfaces
on Debian, /etc/sysconfig/network
on Red Hat).
/etc/hosts
often contains the host name.
- Mail configuration often contains the host name: check
/etc/mailname
.
There's no general answer to “what are the files in /etc
folder (…) are unique for each computer” because the whole purpose of /etc
is to store files that can be customized on each computer. For example, if you have different accounts on different machines, then obviously you can't share the account database — and if you want to be able to share the account database, then you'll end up with the same accounts.
Generally speaking, don't try to share /etc
by default unless you have a set of machines with the same software configuration — same installed software, same accounts, etc. If you do share /etc
, you'll need to blacklist a few files from sharing as indicated above.
If you have machines with different configurations, then whitelist what you synchronize. Treat files in /etc
as distinct on different machines, like files in /var
. Synchronize only the ones that you've decided should apply everywhere.
One possible way to manage synchronization is to keep machine-specific files in a different directory, e.g. /local/etc
, and make symbolic links like /etc/fstab -> ../local/etc/fstab
. This still requires a largely homogeneous set of machines in terms of software as different distributions put files in different locations. Or, conversely, keep only the machine-specific files in /etc
and all generic files elsewhere — but typical distributions don't accommodate this well.
You obviously can't do a live test of the restoration of the system configuration of one system on a different system. To test the restoration of your backups, fire up a virtual machine that emulates the hardware configuration sufficiently well (in particular, with a similar disk layout).
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 that SRCDIR
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:
SRCDIR=(~/PI/tutos/* ~/scripts/*) # ~ and globs expanded at this point
tar cvpzf "$FILENAME" "${SRCDIR[@]}"
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 from tar
. To avoid that, you could do:
shopt -s nullglob # remove non-matching globs
SRCDIR=(~/PI/tutos/* ~/scripts/*)
if ((${#SRCDIR[@]} != 0)); then
tar cvpzf "$FILENAME" "${SRCDIR[@]}"
fi
You may be tempted to do:
SRCDIR="$HOME/PI/tutos/* $HOME/scripts/*"
tar cvpzf "$FILENAME" $SRCDIR
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 as PATH=~/bin:~/sbin
). So you may be tempted to do:
SRCDIR=~/PI/tutos/*:~/scripts/* # ~ (not globs) expanded here
IFS=:
tar cvpzf "$FILENAME" $SRCDIR
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.
Best Answer
You need to specify the archive name before the directory: