How to Preserve Destination File Permissions When Using cp Command in Linux


2 views

When copying files in Linux using the cp command, the default behavior creates new permissions on the destination file based on the umask settings. This often becomes problematic when you need to maintain the existing permissions of the target file while updating its content.

The normal cp command operation:

cp /source/file /destination/existing_file

This will overwrite the destination file's content AND change its permissions to match the source file.

The most effective solution is to combine --no-preserve=mode with cp:

cp --no-preserve=mode /tmp/file /home/file

This tells cp to copy the content but not modify the mode (permissions) of the destination file.

Another method that completely avoids cp's permission handling:

cat /tmp/file > /home/file

This preserves all original permissions since it's just writing content to an existing file.

Where this technique matters most:

  • Updating configuration files that require specific permissions
  • Maintaining web server file permissions during deployments
  • System administration tasks where permission consistency is critical

If you need more granular control:

cp --no-preserve=all --preserve=timestamps /src/file /dest/file

This preserves the destination's permissions while copying timestamps from source.

Important notes about behavior:

  • Directory permissions behave differently than files
  • Root user operations may bypass some permission rules
  • SELinux contexts add another layer of complexity

For most cases, this is the optimal command:

cp --no-preserve=mode --preserve=ownership /source /destination

It provides the best balance between content copying and permission preservation.


When copying files in Unix/Linux systems using the cp command, the default behavior creates new files with the permissions of the source file while ignoring the destination file's existing permissions. This becomes problematic when you need to maintain specific ownership (chown) and group (chgrp) settings on the destination file.

The most straightforward solution is to use the --no-preserve=mode option:

cp --no-preserve=mode /tmp/file /home/file

This tells cp not to preserve the source file's mode (permissions), allowing the destination file to keep its original permissions while updating the content.

1. Using install Command

The install command provides more control over file attributes:

install -p -m $(stat -c %a /home/file) /tmp/file /home/file

2. Combining cp and chmod

Copy first, then restore permissions:

cp /tmp/file /home/file
chmod $(stat -c %a /home/file.old) /home/file

3. Using rsync with --chmod

For more complex scenarios, rsync offers granular control:

rsync -av --chmod=ugo=rw /tmp/file /home/file

If you also need to preserve ownership (user and group), use:

cp --no-preserve=mode --preserve=ownership /tmp/file /home/file

Consider a scenario where you need to update website files without changing their permissions:

#!/bin/bash
SRC="/var/www/staging/index.html"
DEST="/var/www/production/index.html"

# Preserve destination permissions
OLD_PERMS=$(stat -c %a "$DEST")
cp --no-preserve=mode "$SRC" "$DEST"
chmod $OLD_PERMS "$DEST"

The key options for permission handling in cp:

  • --preserve=[ATTR_LIST]: Preserve specified attributes (mode,ownership,timestamps)
  • --no-preserve=[ATTR_LIST]: Don't preserve specified attributes
  • -p: Same as --preserve=mode,ownership,timestamps

When writing scripts that modify production files:

  1. Always check current permissions before copying
  2. Consider using install for more predictable behavior
  3. Test permission changes in staging first
  4. Document permission requirements in your deployment procedures