dotfiles

August 01, 2017

مدیریت کردن فایل های تنظیمات یا dotfiles یکی از اساسی‌ترین کارهایی است که پس از نصب سیستم‌عامل باید انجام شود. روش‌های متعددی برای این کار هست، نرم‌افزار های مختلف و اسکریپت‌های مختلفی که هر کدام به نحوی این کار را انجام می‌دهند. برای مدیریت و نگهداری فایل های تنظیمات از git و sh استفاده خواهم کرد تا کمترین دیپندنسی را داشته باشد. محل ذخیره آنها ریپو http://github.com/MCSH/dot-files خواهد بود.

در این ریپو فایل setup.sh وظیفه نصب فایل‌های کانفیگ شما را در یک سیستم جدید خواهد داشت. فرایند کار به این صورت است که لیست فایل های کانفیگ را به اسکریپت می‌دهید و اسکریپت آن ها را لینک می‌کند. در اینجا این اسکریپت را خط به خط بررسی میکنیم.

#!/bin/sh

این خط به سیستم عامل می‌گوید که برای اجرای این اسکریپت باید این فایل را به برنامه /bin/sh بدهد. معروف به shebang.

FILES=""

متغییر FILES لیستی از فایل هایی است که باید در سیستم مستقر شوند. این خط باید چیزی شبیه به خط زیر باشد. به مرور فایل ها را به این لیست اضافه می کنیم.

FILES=".zshrc .tmux.conf .emacs .config/nvim"

سپس مقصدنصب فایل ها باید مشخص شود. فرض میکنیم پارامتر اول مقصد را در خود ذخیره کرده باشد و در صورت وجود نداشتن HOME را انتخاب می‌کنیم.

DEST=$1

if [ -z "$DEST" ]; then
    DEST="$HOME"
fi

در گام بعدی باید آدرس پوشه فعلی را پیدا کنیم:

BASE=$(dirname $(readlink -f $0))

در خط بعدی تابع ask_install را تعریف می‌کنیم. این تابع با گرفتن نام فایل از کاربر می‌پرسد که آیا قصد نصبش را دارد و اگر فایل وجود داشت قصد جایگزین کردنش را دارد یا نه.

ask_install(){
    FILENAME=$1
    
    LINK="$DEST/$FILENAME"
    TARGET="$BASE/$FILENAME"

    read -r -p "Link $LINK to $TARGET ?[y/N] " response
    case $response in
        [yY])
        if [ -e $LINK ]; then
            read -r -p "File exists, override? [y/N]" response
            case $response in
                [yY])
                    rm -r -f "$LINK"
                    ln -s "$TARGET" "$LINK"
                    ;;
            esac
        else
            ln -s "$TARGET" "$LINK"
        fi
        ;;
    esac
}

در ۳ خط اول نام فایل را از پارامتر اول می‌گیریم و سپس آدرس مبدا و مقصد را مشخص می‌کنیم. خطوط read برای دریافت پاسخ از کاربر است و پاسخ را در متغییر response قرار می‌دهد. چنانچه پاسخ y یا Y باشد دستور اعمال می شود. در بخش if [ -e $LINK ]; اسکریپت بررسی می‌کند ببینید فایل مقصد وجود دارد یا خیر. چنانچه وجود داشته باشد از کاربر تایید می‌خواهد و در غیر اینصورت با دستور ln آن را می‌سازد. در نهایت تابع فوق را بر روی تمامی فایل ها اجرا می‌کنیم:

for FILE in $FILES; do
    ask_install $FILE
done

بر ای استفاده از نصب جدیدمان zsh را اجرا کرده و پس از اتمام آماده سازی آن، فایل .zsrhc را که حاوی تنظیمات zsh است را به ریپو منتقل کردم. سپس لیست FILES را برابر با ".zshrc" گذاشتم و تغییرات را ذخیره کردم. با اجرای دستور ./setup.sh فرایند زیر صورت گرفت:

[sajjad@sajjad-hp dot-files]$ ./setup.sh 
Link /home/sajjad/.zshrc to /home/sajjad/src/git/dot-files/.zshrc ?[y/N] y

اکنون فایل تنظیم .zshrc با فایل درون ریپو هماهنگ خواهد بود. آدرس فایل setup.sh پس از این کامیت.