1. Introduction
  2. Getperm
  3. Setperm
  4. /etc example
  5. Feedback

1. Introduction

Version control systems are not consistent about saving file metadata, like owner, group, modification date, and permissions. Git in particular doesn't preserve ownership and permissions well enough to be trusted with things like /etc files, so you should track that yourself.

I wrote two scripts to handle the most annoying parts of the problem: getperm saves metadata for a set of files, and setperm restores it. The scripts are in Perl; you can use something like mtree (BSD) or the Linux port if you prefer something else. Integrity checkers like aide can save metadata, but you'd have to write something to restore from it.

2. Getperm

Getperm reads filenames from stdin (separated by newlines or nulls -- your choice), gets the file metadata, and saves the results as text.

You can do most of this using something like find, but people love to use filenames with spaces, special characters and other crap which makes them harder to work with from a Unix command line. These scripts handle this by checking for "interesting" characters and encoding them like URLs. These characters are left alone:

A-Z a-z 0-9 / - _ . ! ~ , ( ) +

2.1. Example

me% touch -d yesterday 'spaces (and parens)'

me% ls -lF *perm article* *space*
-rw-r--r-- 1 vogelke mis 3226 05-Jul-2025 18:44:52  article.t2t
-rwxr-xr-x 1 vogelke mis 4994 18-Nov-2023 19:48:13  getperm*
-rwxr-xr-x 1 vogelke mis 4260 16-Aug-2023 03:40:12  setperm*
-rw-r--r-- 1 vogelke mis    0 04-Jul-2025 18:45:33 'spaces (and parens)'

me% find . -print | grep -E 'perm|article|space' | getperm > PERM

me% cat PERM
vogelke|mis|0644|1751755492|./article.t2t
vogelke|mis|0755|1700354893|./getperm
vogelke|mis|0755|1692171612|./setperm
vogelke|mis|0644|1751669133|./spaces%20(and%20parens)

The modification time is stored as epoch time, which is the number of elapsed seconds since 1 Jan 1970 00:00:00 Coordinated Universal Time (UTC). This makes it much easier to sort by time.

3. Setperm

setperm reads output generated by getperm and restores ownership, permission, and modification time.

3.1. Example

me% ls -lF *perm article* *space*
-rw-r--r-- 1 vogelke mis 3867 05-Jul-2025 18:53:43  article.t2t
-rwxr-xr-x 1 vogelke mis 4994 18-Nov-2023 19:48:13  getperm*
-rwxr-xr-x 1 vogelke mis 4260 16-Aug-2023 03:40:12  setperm*
-rw-r--r-- 1 vogelke mis    0 05-Jul-2025 18:54:05 'spaces (and parens)'

me% touch *perm article* *space*
me% chgrp www *perm article* *space*

me% ls -lF *perm article* *space*
-rw-r--r-- 1 vogelke www 3867 05-Jul-2025 18:55:44  article.t2t
-rwxr-xr-x 1 vogelke www 4994 05-Jul-2025 18:55:44  getperm*
-rwxr-xr-x 1 vogelke www 4260 05-Jul-2025 18:55:44  setperm*
-rw-r--r-- 1 vogelke www    0 05-Jul-2025 18:55:44 'spaces (and parens)'

me% setperm < PERM

me% ls -lF *perm article* *space*
-rw-r--r-- 1 vogelke mis 3867 05-Jul-2025 18:44:52  article.t2t
-rwxr-xr-x 1 vogelke mis 4994 18-Nov-2023 19:48:13  getperm*
-rwxr-xr-x 1 vogelke mis 4260 16-Aug-2023 03:40:12  setperm*
-rw-r--r-- 1 vogelke mis    0 04-Jul-2025 18:45:33 'spaces (and parens)'

4. /etc example

Save user, group, filemode and modification time for specific /etc files:

me% cat etc-files
/etc/login.conf
/etc/make.conf
/etc/nsswitch.conf
/etc/ntp.conf
/etc/periodic.conf
/etc/rc.conf
/etc/resolv.conf
/etc/sysctl.conf
/etc/syslog.conf

me% ls -lF $(cat etc-files)
-rw-r--r-- 1 root wheel 6790 08-Oct-2020 04:39:43 /etc/login.conf
-rw-r--r-- 1 root wheel 2344 02-Mar-2025 19:29:23 /etc/make.conf
-rw-r--r-- 1 root wheel  338 05-Jul-2019 00:47:42 /etc/nsswitch.conf
-rw-r--r-- 1 root wheel 3983 02-Nov-2020 22:28:08 /etc/ntp.conf
-rw-rw-r-- 1 root wheel  894 01-May-2025 16:43:47 /etc/periodic.conf
-rw-r--r-- 1 root wheel 2657 26-Jun-2025 01:45:12 /etc/rc.conf
-rw-r--r-- 1 root wheel  379 27-Feb-2025 16:36:55 /etc/resolv.conf
-rw-r--r-- 1 root wheel 5411 27-Feb-2025 16:37:43 /etc/sysctl.conf
-rw-r--r-- 1 root wheel 1398 07-Sep-2023 03:03:29 /etc/syslog.conf

me% getperm < etc-files > /tmp/PERM

me% cat /tmp/PERM
root|wheel|0644|1602146383|/etc/login.conf
root|wheel|0644|1740961763|/etc/make.conf
root|wheel|0644|1562302062|/etc/nsswitch.conf
root|wheel|0644|1604374088|/etc/ntp.conf
root|wheel|0664|1746132227|/etc/periodic.conf
root|wheel|0644|1750916712|/etc/rc.conf
root|wheel|0644|1740692215|/etc/resolv.conf
root|wheel|0644|1740692263|/etc/sysctl.conf
root|wheel|0644|1694070209|/etc/syslog.conf

You can restore these settings as root:

root# setperm < /tmp/PERM

You can download getperm and setperm here.

5. Feedback

Feel free to send comments.


Generated from article.t2t by txt2tags
$Revision: 1.4 $
$UUID: d86155e6-c560-3271-94ab-363ee61d006d $