Небольшая заметка о утилите, которая требуется редко, но метко – lndir.

Когда у меня стало больше одного Мака, появилась проблема синхронизации настроек. Другими словами, чтобы всякие .thisrc и .thatrc были одинаковы и подхватывались при изменении. Сюда входит конфиг Emacs, ssh, словари aspell, профили AWS, конфиги ctags, zshell и многое другое.

Легче всего держать dot-файлы в репозитории и ставить симлинки. Неожиданно я столкнулся с тем, что не так легко написать shell-скрипт, который бы поставил симлинки на файлы из папки. Пытался при помощи find ... -execute и xargs, но постоянно что-то мешало. То отсутствие файла, то его существование, словом, всякие досадные случаи. В итоге было две команды: сначала одна удаляет симлинки, а вторая создает их заново.

Оказалось, что lndir делает именно то, что я искал. Они принимает две папки и строит дерево симлинков из первой во вторую. При этом учитывает случаи, что я перечислил, например если симлинк уже есть. Благодаря этому дерево можно обновлять итеративно.

Пример: в каталоге ~/work/System/Dotfiles хранятся оригинальные файлы Emacs, .ssh и прочие. Следующая команда make расставит симлинки в домашнюю папку:

HOME = /Users/ivan
PWD = $(shell pwd)

create-symlinks:
	lndir ${PWD}/Dotfiles ${HOME}
	chmod 600 ${HOME}/.ssh/*

Для файлов ssh необходимо выставить права 600, иначе утилита ругается.

Синхронизация происходит обычным способом через git. Как только вы поменяли один из файлов, делаете коммит и пуш. На другой машине пулл и make create-symlinks, и все подхватывается. Репозиторий, понятно, должен быть приватным.

По умолчанию lndir нет в поставке Линукса и Мака. Ставится из привычных apt и brew.