dotdee(8)

πŸ’– dotdee(8) β€” bestie's guide to the dynamic-file generator πŸ’–

okay so this is dotdee, and it lives in section 8 of the manual (that's the sysadmin zone, very main character energy πŸ‘‘). Buckle up, this one's actually so good.


✨ NAME ✨

dotdee β€” converts a flat file into one that's dynamically generated from a .d directory. That's the whole serve. 🫢


πŸŽ€ SYNOPSIS πŸŽ€

Pick your mode, bestie. One at a time. No mixing. 😌

dotdee -c|--comment /PATH/TO/FILE [COMMENT_DELIMITER_START [COMMENT_DELIMITER_END]]
dotdee -d|--dir /PATH/TO/FILE
dotdee -l|--list
dotdee -o|--original /PATH/TO/FILE
dotdee -s|--setup /PATH/TO/FILE [COMMENT_DELIMITER_START [COMMENT_DELIMITER_END]]
dotdee -u|--update /PATH/TO/FILE
dotdee --update-contents /PATH/TO/FILE
dotdee --update-link /PATH/TO/FILE
dotdee --undo /PATH/TO/FILE

And for the people who need the receipts, here's what each one is shaped like:

  • -c, --comment β€” takes /PATH/TO/FILE, plus optionally COMMENT_DELIMITER_START and COMMENT_DELIMITER_END πŸ’…
  • -d, --dir β€” takes /PATH/TO/FILE
  • -l, --list β€” takes literally nothing, it just vibes πŸ¦‹
  • -o, --original β€” takes /PATH/TO/FILE
  • -s, --setup β€” takes /PATH/TO/FILE, plus optionally COMMENT_DELIMITER_START and COMMENT_DELIMITER_END
  • -u, --update β€” takes /PATH/TO/FILE
  • --update-contents β€” takes /PATH/TO/FILE
  • --update-link β€” takes /PATH/TO/FILE
  • --undo β€” takes /PATH/TO/FILE

🌸 DESCRIPTION 🌸

okay so <purple>dotdee</purple> is an administrative utility β€” it's the one you call when you want to convert a flatfile into a dynamically generated file, from a .d directory. Iconic behaviour, honestly.

Here's the glow-up it performs: the original path at /PATH/TO/FILE gets replaced with a symbolic link pointing at /etc/dotdee/PATH/TO/FILE, and that file is dynamically generated by concatenating all of the files in /etc/dotdee/PATH/TO/FILE.d/*, per the order of the shell. Chef's kiss. πŸŽ€

And the magic that keeps it fresh? The Linux kernel's inotify(7) mechanism, which <cyan>dotdee</cyan> uses by running iwatch(1) against the /etc/dotdee/ directory. Any changes to the constituent files are automatically reflected in the constructed, dynamically generated file. So β€” and this is the part that matters β€” as long as iwatch(1) is running, you should never need to actually run dotdee --update /PATH/TO/FILE manually. Not me telling you twice. 🫢

🌈 what lives in the .d directory 🌈

There is at least 1 file always present in an /etc/dotdee/PATH/TO/FILE.d/ directory:

  • 50-original is the original file being managed; note that write permissions are removed from this file, as we don't want to ever modify it. Hands off, bestie. πŸ™ˆ

Optionally, a 2nd file might be present in an /etc/dotdee/PATH/TO/FILE.d/ directory:

  • .comment is a text file that defines the "comment" string; if, for instance, the contents of .comment is the # character, the following will be printed to the head of the generated file:
# DO NOT EDIT THIS FILE DIRECTLY!
# Rather, add, remove, or modify file(s) in [/etc/dotdee/path/to/some.conf.d]
# per the dotdee(8) manpage.

Alternatively, .comment might contain //, or ;, or anything else that denotes that the rest of the string will be a comment. It's flexible like that. πŸ’…

As for the rest of the contents of the /etc/dotdee/PATH/TO/FILE.d/ directory β€” all of them must begin with 2 or more digits, to ensure that they are processed in a specific order. The numbers are the whole point, don't skip them. πŸ”₯

⭐ the 3 supported file types ⭐

  1. plain text files, which must not be executable; these files are simply concatenated in order
  2. executable files; these files are executed, with the current state of the managed file provided on STDIN, and the STDOUT is then written to the managed file
  3. patch/diff files; these files end in either .patch or .diff, and are applied using the patch(1) command to the current state of the managed file

πŸ”₯ EXAMPLES πŸ”₯

This is the part where it all clicks, bestie. Watch. πŸ‘€

πŸ¦‹ step 1: set it up

$ sudo dotdee --setup /etc/hosts
update-alternatives: using /etc/dotdee/etc/hosts to provide /etc/hosts (etc:hosts) in auto mode.
$ ll /etc/hosts
lrwxrwxrwx 1 root root 27 2011-05-25 00:26 /etc/hosts -> /etc/alternatives/etc:hosts

$ ll /etc/alternatives/etc:hosts
lrwxrwxrwx 1 root root 22 2011-05-25 00:26 /etc/alternatives/etc:hosts -> /etc/dotdee/etc/hosts

$ ll /etc/dotdee/etc/hosts
-rw-r--r-- 1 root root 221 2011-05-16 01:40 /etc/dotdee/etc/hosts

πŸ¦‹ step 3: the original contents

$ cat /etc/hosts
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

πŸ¦‹ step 4: drop a new numbered file in and watch the magic

$ echo 10.9.8.7 somehost | sudo tee /etc/dotdee/etc/hosts.d/10-somehost
$ cat /etc/hosts
10.9.8.7 somehost
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

πŸ¦‹ step 5: patches, because why edit when you can diff

$ cat /etc/dotdee/etc/hosts.d/60-googledns.patch
--- /etc/hosts    2011-05-16 01:40:03.000000000 +0000
+++ /tmp/hosts.new    2011-05-25 00:30:41.187412417 +0000
@@ -1,6 +1,8 @@
 10.9.8.7 somehost
 127.0.0.1 localhost

+8.8.8.8 googledns
+
 # The following lines are desirable for IPv6 capable hosts
 ::1 ip6-localhost ip6-loopback
 fe00::0 ip6-localnet
$ cat /etc/hosts
10.9.8.7 somehost
127.0.0.1 localhost

8.8.8.8 googledns

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

πŸ¦‹ step 6: executable files get STDIN, give STDOUT

$ cat /etc/dotdee/etc/hosts.d/90-uppercase
#!/bin/sh
tr '[:lower:]' '[:upper:]'
$ cat /etc/hosts
10.9.8.7 SOMEHOST
127.0.0.1 LOCALHOST

8.8.8.8 GOOGLEDNS

# THE FOLLOWING LINES ARE DESIRABLE FOR IPV6 CAPABLE HOSTS
::1 IP6-LOCALHOST IP6-LOOPBACK
FE00::0 IP6-LOCALNET
FF00::0 IP6-MCASTPREFIX
FF02::1 IP6-ALLNODES
FF02::2 IP6-ALLROUTERS
FF02::3 IP6-ALLHOSTS

πŸ¦‹ step 7: finding your way around

$ sudo dotdee --dir /etc/hosts
/etc/dotdee/etc/hosts.d
$ cat /some/hosts/snippet > $(sudo dotdee --dir /etc/hosts)/60-foo
$ sudo dotdee --original /etc/hosts
/etc/dotdee/etc/hosts.d/50-original
$ cat /some/other/hosts/file > $(sudo dotdee --original /etc/hosts)

πŸ¦‹ step 8: custom comment delimiters, for the XML girlies

$ sudo dotdee --comment /path/to/some.xml '<!--' '-->'

πŸ’œ SEE ALSO πŸ’œ

update-alternatives(8), iwatch(1), patch(1) β€” go read those too, they're part of the lore. πŸ“š


πŸ‘‘ AUTHOR πŸ‘‘

This manpage and the utility was written by Dustin Kirkland <kirkland@ubuntu.com> for Ubuntu systems (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 published by the Free Software Foundation.

On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL, or on the web at http://www.gnu.org/licenses/gpl.txt.


and that's the whole page, bestie πŸ’– this dotdee(8) manual dropped on 21 May 2011 and it's still serving looks. periodt. πŸ’…βœ¨

πŸ“¦ where this page comes from