Skip to content

Instantly share code, notes, and snippets.

@ruario
Last active December 7, 2025 09:05
Show Gist options
  • Select an option

  • Save ruario/3e7ccda93d1c96185f15f5657894bfcb to your computer and use it in GitHub Desktop.

Select an option

Save ruario/3e7ccda93d1c96185f15f5657894bfcb to your computer and use it in GitHub Desktop.
Archive formats like .7z and .zip often fail to preserve UNIX file metadata such as permissions and ownership. Here are three simple shell one‑liners that generate helper scripts to restore these attributes after extraction

Preserving UNIX (Linux) File Permissions and Ownership in .7z and .zip Archives

When possible, native *nix formats like tar are the best choice for backups. However, there are cases where other formats may be preferable due to their features. For example, specific compression options or non‑solid compression that allow faster access to individual files. In these situations, common tools such as 7‑Zip (with Windows heritage) may not store UNIX meta data correctly. By combining small, easy‑to‑create helper scripts with your backup archives, you can preserve metadata. Here are three short scripts that can be generated via shell one-liners:

  • perms.sh → Restores file permissions only.
  • ownperms.sh → Restores both permissions and ownership.
    • Run with no arguments → restores both.
    • Run with -o → ownership only.
    • Run with -p → permissions only.
  • symlinks.sh → Recreates symbolic links.
    • Optional: delete symlinks before archiving to avoid duplication, then restore them afterward.

Warning: These simple scripts may not work reliably if you have very exotically named files/directories. For example, files that include " in their name. In such cases I assume you are an advanced user and know how to work around such things. In fact, you probably do not even need this gist. 🤣


Saving and Restoring Permissions

If you are backing up a directory, run the following one‑liner inside that directory before archiving:

{ printf '#!/bin/sh\nset -e\ncd "$(dirname "$0")"\n'; find . -depth ! -type l ! -name perms.sh -printf 'chmod %m "%p"\n'; } > perms.sh

Note: Triple-click to select the entire line above.

This generates a script (perms.sh) that can later be executed with:

sh perms.sh

to restore file permissions on a UNIX‑like system.


Saving and Restoring Permissions and Ownership

If you also need to preserve file ownership, use this slightly more advanced variant:

{ printf '#!/bin/sh\nset -e\no=n\np=n\n[ -z "${1:-}" ] && o=y && p=y\n[ "${1:-}" = "-o" ] && o=y\n[ "${1:-}" = "-p" ] && p=y\ncd "$(dirname "$0")"\n'; find . -depth ! -type l ! -name ownperms.sh -printf '[ "$o" = y ] && chown "%u:%g" "%p"\n[ "$p" = y ] && chmod %m "%p"\n'; } > ownperms.sh

To restore both permissions and ownership:

sh ownperms.sh
  • Use -o to restore ownership only.
  • Use -p to restore permissions only.

Note: Restoring ownership may require elevated privileges (e.g. sudo or runas).


Handling Symlinks

While 7-zip (with -snl) and Info‑ZIP (with -y) can store symlinks, some tools or other archive formats cannot. In those cases, you could also generate a script to recreate symlinks:

{ printf '#!/bin/sh\nset -e\ncd "$(dirname "$0")"\n'; find . -type l -printf 'ln -sfn "%l" "%p"\n'; } > symlinks.sh

This produces symlinks.sh, which can be executed as follows to restore symlinks:

sh symlinks.sh

Optionally, you may delete symlinks before creating the archive. This avoids possible duplication of linked files and folders being included in the backup twice.

⚠️ Warning: This last command is highly destructive!

Only do this if you have first created symlinks.sh and also fully understand and accept the impact of the following (it deletes all symlinks on your system recursively from the directory you are currently working in!).

find . -type l -delete

Note: Assuming you created it first, you can restore the symlinks at any point by running symlinks.sh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment