How to Recursively Copy Hidden Files in Linux (Excluding . and .. Directories)


1 views


When trying to back up configuration files in a Linux home directory, many developers instinctively try:

cp -R .* ~/backup/

This fails because:

  • The pattern .* matches both . (current directory)
  • And .. (parent directory)
  • Resulting in recursive copying of everything

Method 1: Using find + cpio

This is the most reliable approach:

find . -name ".*" ! -name "." ! -name ".." -depth -print0 | cpio -pvdm0 ~/backup/

Where:

  • -name ".*" matches hidden files/dirs
  • ! -name "." excludes current dir
  • ! -name ".." excludes parent dir
  • -print0 handles spaces in filenames

Method 2: Using rsync

For a more modern approach:

rsync -a --include='.*' --exclude='.' --exclude='..' ~/ ~/backup/

Key advantages:

  • Properly handles symlinks and permissions
  • Allows incremental backups
  • Provides progress output

Method 3: Bash globbing (for simple cases)

In newer Bash versions (4.0+):

shopt -s dotglob cp -r ~/.[^.]* ~/backup/

The pattern .[^.]* means:

  • Starts with dot
  • Next character isn't dot
  • Followed by anything
  • Missing -depth in find can cause permission issues
  • Not using null terminators (-print0) breaks on special characters
  • Globbing methods may miss some edge cases

For large directories:

MethodSpeedMemory
find+cpioFastLow
rsyncMediumMedium
bash globSlowHigh


When attempting to back up configuration files in Linux home directories, many developers instinctively try:

cp -R .* ~/backup_folder

This command fails for two critical reasons:
1. It includes the current directory (.) and parent directory (..)
2. It ends up copying everything, not just hidden files

The most reliable method uses find to precisely target hidden files:

find . -name ".*" ! -name "." ! -name ".." -exec cp -r {} ~/backup_folder \;

This command:
• Starts from current directory (.)
• Matches all hidden files/dirs (.*)
• Excludes . and .. specifically
• Uses -exec to copy each match

For more advanced users, rsync provides better control:

rsync -av --include='.*' --exclude='.' --exclude='..' ~/ ~/backup_folder/

Some hidden files may have special permissions or be symlinks. Consider adding:

find . -name ".*" ! -name "." ! -name ".." -exec cp -r -p {} ~/backup_folder \;

The -p flag preserves permissions and timestamps.

To backup only your .config and .bashrc files:

find . $-name ".config" -o -name ".bashrc"$ -exec cp -r -p {} ~/backup_folder \;