وقتی sudo apt install nginx را اجرا می‌کنیم، سیستم باید چند پرسش را جواب دهد: کدام نسخه؟ از کدام مخزن؟ همراه کدام وابستگی‌ها؟ با چه تضمینی دربارهٔ اصالت فایل؟ و اگر تنظیم بسته شکست خورد، چه وضعیتی روی دیسک باقی می‌ماند؟

برای فهم این مسیر باید سه چیز را جدا ببینیم: اطلاعات مخزن، فایل بسته و وضعیت نصب‌شدهٔ سیستم. این نوشته مسیر میان این سه را در دبیان و اوبونتو دنبال می‌کند؛ از InRelease و Packages تا اسکریپت‌های نگه‌دارنده و پایگاه دادهٔ dpkg.

۱. تقسیم کار میان APT و dpkg#

APT مجموعه‌ای از کتابخانه‌ها و ابزارهای مدیریت بسته است. apt و apt-get رابط‌های خط فرمان آن هستند. dpkg لایه‌ای است که بسته را روی سیستم باز می‌کند، تنظیم می‌کند و وضعیت نصبش را نگه می‌دارد.

ابزارمسئولیت اصلی
aptرابط تعاملی برای جست‌وجو، نصب و ارتقا
apt-getرابط مناسب‌تر برای اسکریپت و خودکارسازی
apt-cacheپرس‌وجو از اطلاعات بسته‌ها و نسخه‌ها
dpkgنصب، تنظیم و حذف بسته روی سیستم محلی
dpkg-debبررسی یا استخراج فایل .deb
dpkg-queryپرس‌وجو از پایگاه دادهٔ بسته‌های سیستم

APT دربارهٔ مجموعهٔ بسته‌های لازم تصمیم می‌گیرد و آن‌ها را دریافت می‌کند؛ سپس اجرای تغییرات را به dpkg می‌سپارد. dpkg وابستگی‌ها را می‌شناسد و بررسی می‌کند، اما خودش برای پیدا کردن و دانلود وابستگی مفقود به مخزن مراجعه نمی‌کند. مرجع مدیریت بستهٔ دبیان

apt برای استفادهٔ انسانی طراحی شده و خروجی و بعضی پیش‌فرض‌هایش ممکن است تغییر کنند؛ برای اسکریپت‌ها از رابط‌های مناسب مانند apt-get استفاده کنید. راهنمای apt

۲. داخل فایل deb چه خبر است؟#

یک .deb صرفاً فایل اجرایی نیست. قالب معمول آن یک آرشیو ar با این اجزاست؛ پسوند فشرده‌سازی می‌تواند متفاوت باشد:

example.deb
├── debian-binary
├── control.tar.*
└── data.tar.*

debian-binary نسخهٔ قالب را مشخص می‌کند. آرشیو control شامل شناسنامهٔ بسته و احتمالاً اسکریپت‌های نگه‌دارنده و فهرست conffileهاست. آرشیو data فایل‌هایی را نگه می‌دارد که باید در مسیرهایی مانند /usr/bin، /usr/lib و /etc قرار بگیرند. همهٔ بسته‌ها همهٔ اسکریپت‌ها را ندارند. متادیتای بسته در کتاب راهنمای دبیان

برای بررسی بدون نصب، در پوشه‌ای قابل‌نوشتن اجرا کنید:

mkdir -p ~/apt-lab
cd ~/apt-lab
apt download hello

# اگر چند فایل وجود داشت، نام دقیق فایل موردنظر را جایگزین کنید.
dpkg-deb --info ./hello_*.deb
dpkg-deb --contents ./hello_*.deb
dpkg-deb --field ./hello_*.deb Package Version Architecture Depends
dpkg-deb --control ./hello_*.deb ./hello-control
dpkg-deb --extract ./hello_*.deb ./hello-root

دستورهای بالا بسته را نصب نمی‌کنند. استخراج، فایل‌ها را در پوشهٔ انتخابی می‌گذارد؛ اسکریپت‌های نصب اجرا نمی‌شوند و وضعیت dpkg تغییر نمی‌کند. بنابراین وجود فایل اجرایی در hello-root به معنی نصب‌شدن بسته نیست. راهنمای dpkg-deb

۳. APT مخزن را از کجا می‌شناسد؟#

تعریف مخزن در /etc/apt/sources.list و فایل‌های .list یا .sources زیر /etc/apt/sources.list.d/ قرار می‌گیرد. قالب چندخطی .sources را Deb822 می‌نامند.

این نمونه فقط ساختار یک ورودی دبیان را نشان می‌دهد؛ تنظیم کامل مخازن نیست و نباید جای تنظیمات اوبونتو قرار بگیرد:

Types: deb
URIs: https://deb.debian.org/debian
Suites: trixie
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
فیلدمعنا
Typesdeb برای بستهٔ باینری؛ deb-src برای اطلاعات بسته‌های سورس
URIsنشانی پایهٔ مخزن
Suitesنام انتشار یا شاخهٔ موردنظر
Componentsبخش‌هایی از مخزن که باید خوانده شوند
Signed-Byکلیدهای مجاز برای تأیید همین منبع

معماری هم در انتخاب فهرست‌ها نقش دارد؛ dpkg --print-architecture معماری اصلی را نشان می‌دهد. به این ترتیب APT لازم نیست فهرست تمام معماری‌های مخزن را دریافت کند. راهنمای sources.list

۴. ساختار مخزن: dists برای فهرست‌ها، pool برای بسته‌ها#

نمای زیر ساختاری آموزشی از یک مخزن متعارف است:

repository/
├── dists/
│   └── trixie/
│       ├── InRelease
│       ├── Release
│       ├── Release.gpg
│       └── main/
│           └── binary-amd64/
│               └── Packages.xz
└── pool/
    └── main/
        └── h/
            └── hello/
                └── hello_<version>_amd64.deb

یک بسته می‌تواند از فهرست چند انتشار ارجاع داده شود؛ لازم نیست برای هر انتشار نسخه‌ای از همان فایل در dists ذخیره شود. فهرست‌های Sources مربوط به بسته‌های سورس هستند و Contents نگاشت مسیر فایل‌ها به بسته‌ها را فراهم می‌کند. ساختار آرشیو در مرجع دبیان

Release شناسنامهٔ انتشار و اندازه و هش فهرست‌ها را دارد. در فایل واقعی Release دبیان می‌توان فیلدهایی مثل Suite، Codename، Architectures، Components و بخش SHA256 را دید.

هر رکورد Packages اطلاعات یک نسخهٔ بسته را توصیف می‌کند. مثال زیر ساختگی است و مقادیرش قابل‌استفاده برای دانلود یا تأیید نیست:

Package: demo-web
Version: 2.4-1
Architecture: amd64
Depends: libc6 (>= 2.36), demo-common (= 2.4-1)
Filename: pool/main/d/demo-web/demo-web_2.4-1_amd64.deb
Size: 123456
SHA256: <64 hexadecimal characters>
Description: Example package for this article

فیلد Filename مسیر بسته نسبت به ریشهٔ مخزن است. بنابراین APT نشانی دانلود را از متادیتا به دست می‌آورد؛ نام فایل را بر اساس نام بسته حدس نمی‌زند. این ساختار را مستندات رسمی ابزار apt-ftparchive نیز توضیح می‌دهد.

۵. apt update دقیقاً چه چیزی را به‌روز می‌کند؟#

sudo apt update

این دستور فهرست بسته‌های موجود در مخزن را تازه می‌کند؛ برنامه‌های نصب‌شده را ارتقا نمی‌دهد. APT اطلاعات انتشار و فهرست‌های لازم را دریافت و بررسی می‌کند و نسخهٔ محلی آن‌ها را زیر /var/lib/apt/lists/ نگه می‌دارد. راهنمای apt-get

مسیر دریافت همیشه یک دانلود کامل نیست: مخزن ممکن است فهرست فشرده، تفاوت فهرست‌ها یا PDiff، و دریافت بر اساس هش یا By-Hash ارائه کند. By-Hash کمک می‌کند هنگام همگام‌سازی آینه، فهرستی متعلق به نسخهٔ دیگری از متادیتا دریافت نشود. گزینه‌های دریافت در sources.list

نتیجهٔ عملی: apt install معمولاً بر اساس فهرست محلی تصمیم می‌گیرد. اگر آن فهرست قدیمی باشد، ممکن است نسخه‌ای را انتخاب کند که فایلش دیگر روی آینه موجود نیست. اجرای update و بررسی خطاهای آن، بخشی از تشخیص چنین وضعیتی است. کار با APT در کتاب راهنمای دبیان

۶. زنجیرهٔ اعتماد: امضا کجاست؟#

در مسیر عادی مخزن، APT امضای جداگانهٔ تک‌تک فایل‌های .deb را بررسی نمی‌کند. زنجیره چنین است:

Trusted archive key
        |
        v
InRelease signature OR Release + Release.gpg
        |
        v
Index checksums in Release
        |
        v
Package checksum in Packages
        |
        v
Downloaded .deb

InRelease محتوای Release را همراه امضای درون‌متنی حمل می‌کند؛ Release.gpg امضای جداگانهٔ Release است. پس از تأیید امضا، هش فهرست و سپس هش بسته بررسی می‌شود. هش به‌تنهایی اصالت ایجاد نمی‌کند؛ باید از متادیتایی بیاید که اعتبارش تأیید شده است.

Signed-By دامنهٔ اعتماد کلید را به منبع مربوط محدود می‌کند. برای کلیدهای محلی مدیر سیستم معمولاً /etc/apt/keyrings/ و برای کلیدهای مدیریت‌شده با بسته /usr/share/keyrings/ استفاده می‌شود.

این سازوکار دست‌کاری آینه یا مسیر انتقال را آشکار می‌کند، اما تضمین نمی‌کند نرم‌افزار ناشر بی‌اشکال یا بی‌خطر است. همچنین نصب یک .deb محلی به‌خودی‌خود آن را وارد زنجیرهٔ اعتماد مخزن نمی‌کند. مدل اعتماد در apt-secure

۷. انتخاب نسخه و حل وابستگی‌ها#

APT نسخه‌های موجود را با وضعیت فعلی سیستم و سیاست انتخاب نسخه مقایسه می‌کند. «بزرگ‌ترین شمارهٔ نسخه» همیشه برنده نیست: اولویت مخازن، pinning، انتشار هدف و قواعد downgrade مؤثرند. در اوبونتو، phased updates نیز می‌تواند عرضهٔ بعضی ارتقاها را برای گروهی از سیستم‌ها عقب بیندازد.

apt-cache policy nginx
apt-cache depends nginx
apt-get -s install nginx

در خروجی policy، مقدار Installed نسخهٔ نصب‌شده و Candidate نامزد انتخاب‌شده بر اساس سیاست فعلی است. گزینهٔ -s تغییرات پیشنهادی را شبیه‌سازی می‌کند؛ این پیش‌نمایش، موفقیت اسکریپت نصب در اجرای واقعی را تضمین نمی‌کند. سیاست انتخاب نسخه ، شبیه‌سازی apt-get

وابستگی‌ها یک نمودار از قیدها هستند:

رابطهاثر
Dependsوابستگی لازم برای تنظیم صحیح بسته
Pre-Dependsشرط سخت‌گیرانه‌تر که پیش از بازکردن بسته هم اثر دارد
Recommendsهمراه پیشنهادی قوی
Suggestsهمراه اختیاری
Conflictsجلوگیری از هم‌زیستی بسته‌های ناسازگار
Breaksاعلام ناسازگاری با نسخه‌هایی از بستهٔ دیگر
Replacesمجازکردن جایگزینی فایل‌های متعلق به بستهٔ دیگر در شرایط مشخص
Providesارائهٔ یک قابلیت یا نام بستهٔ مجازی

مثلاً Depends: mail-transport-agent ممکن است با یکی از چند ارائه‌دهنده برآورده شود. Replaces به‌تنهایی معادل «حذف بستهٔ دیگر» نیست. روابط بسته‌ها در Debian Policy

APT معمولاً Recommends را هم نصب می‌کند؛ گزینهٔ --no-install-recommends این رفتار را برای درخواست تغییر می‌دهد. اگر هیچ ترکیب سازگاری پیدا نشود، عملیات با خطای وابستگی متوقف می‌شود. راهنمای apt-get

۸. دانلود و تحویل به dpkg#

پس از انتخاب مجموعهٔ بسته‌ها، APT فایل‌های لازم را دریافت می‌کند. مسیر معمول آرشیوها /var/cache/apt/archives/ و محل فایل‌های در حال دریافت زیرپوشهٔ partial/ است. باقی‌ماندن .deb پس از نصب به ابزار و تنظیمات پاک‌سازی بستگی دارد؛ خالی‌بودن این پوشه نشانهٔ نصب‌نبودن برنامه‌ها نیست. کش بسته‌ها در مرجع دبیان

برای نصب یک فایل محلی همراه با حل وابستگی‌ها:

sudo apt install ./example.deb

این مثال را تنها با نام فایل واقعی و مورداعتماد جایگزین کنید. در مقابل، sudo dpkg -i ./example.deb وابستگی گمشده را دانلود نمی‌کند و ممکن است بسته را در وضعیت تنظیم‌نشده باقی بگذارد. نصب بستهٔ محلی در کتاب راهنمای دبیان

۹. چرخهٔ نصب: unpack با configure فرق دارد#

نمای سادهٔ نصب اولیهٔ موفق چنین است:

not-installed -> preinst -> unpacked -> postinst configure -> installed

این نمودار تمام جزئیات ارتقا، خطا و triggerها را نشان نمی‌دهد. preinst پیش از بازشدن فایل‌ها اجرا می‌شود. پس از unpack، فایل‌ها وجود دارند، اما بسته هنوز الزاماً قابل‌استفاده نیست. در configure، تنظیم conffileها و اجرای postinst انجام می‌شود. شکست یک اسکریپت می‌تواند نصب را نیمه‌تمام بگذارد. راهنمای dpkg

اسکریپت‌های نگه‌دارنده عبارت‌اند از:

اسکریپتکاربرد معمول
preinstآماده‌سازی پیش از unpack
postinstتکمیل تنظیم پس از unpack
prermکارهای پیش از حذف یا برخی مراحل ارتقا
postrmپاک‌سازی پس از حذف و هنگام purge

هنگام ارتقا، اسکریپت‌های نسخهٔ قدیم و جدید با آرگومان‌های متفاوت اجرا می‌شوند؛ ترتیب آن با نصب اولیه یکسان نیست. ساخت کاربر سیستمی یا مدیریت سرویس می‌تواند بخشی از این اسکریپت‌ها باشد. dpkg فقط فایل‌ها را کپی نمی‌کند؛ کد نگه‌دارنده را نیز با دسترسی نصب اجرا می‌کند. چرخهٔ اسکریپت‌ها در Debian Policy

Triggerها اجازه می‌دهند کار مشترکی مثل بازسازی یک کش پس از تغییر چند بسته جمع‌بندی شود. بنابراین دیدن Processing triggers مرحله‌ای از تکمیل تغییرات است. وضعیت‌هایی مانند triggers-pending و half-configured نیز نشان می‌دهند فرایند هنوز کامل نشده است. وضعیت‌های dpkg

۱۰. فایل تنظیمات کاربر هنگام ارتقا چه می‌شود؟#

بعضی فایل‌های تنظیمات به‌عنوان conffile ثبت می‌شوند. dpkg برای تشخیص تغییر محلی، اطلاعات نسخهٔ قبلی را نگه می‌دارد. اگر هم شما فایل را ویرایش کرده باشید و هم نسخهٔ بسته آن را تغییر داده باشد، ممکن است دربارهٔ نگه‌داشتن نسخهٔ فعلی یا پذیرفتن نسخهٔ جدید سؤال شود.

هر فایل زیر /etc لزوماً conffile نیست؛ بعضی تنظیمات با اسکریپت یا ابزارهایی مانند ucf مدیریت می‌شوند. در نتیجه نمی‌توان از محل فایل به‌تنهایی رفتار ارتقای آن را حدس زد. فایل‌هایی مثل .dpkg-dist یا .dpkg-old نیز می‌توانند حاصل تصمیم مربوط به نسخه‌های تنظیمات باشند. سیاست فایل‌های تنظیمات ، رفتار dpkg

۱۱. سیستم از کجا می‌داند چه چیزی نصب است؟#

مسیرنقش
/var/lib/apt/lists/اطلاعات دریافت‌شده دربارهٔ بسته‌های موجود در مخازن
/var/cache/apt/archives/فایل‌های بستهٔ دانلودشده، اگر نگه داشته شوند
/var/lib/dpkg/statusوضعیت بسته‌ها در سیستم محلی
/var/lib/dpkg/info/اطلاعات فایل‌ها و اسکریپت‌های بسته‌ها
/var/lib/apt/extended_statesاطلاعات تکمیلی APT مانند نصب خودکار

سه پرسش متفاوت داریم: «چه بسته‌ای موجود است؟»، «چه فایلی دانلود شده؟» و «چه بسته‌ای نصب شده؟». پاک‌کردن کش دانلود معادل حذف برنامه نیست. پایگاه‌های دادهٔ مدیریت بسته

برای مشاهدهٔ وضعیت و مالکیت فایل‌ها:

dpkg-query -W -f='${binary:Package}\t${Version}\t${Status}\n' bash
dpkg-query -L bash
dpkg-query -S /usr/bin/apt
dpkg -l nginx

-L فایل‌های ثبت‌شده برای بسته را نشان می‌دهد؛ لزوماً شامل تمام فایل‌هایی نیست که برنامه یا اسکریپت‌هایش بعداً ساخته‌اند. -S در اطلاعات محلی جست‌وجو می‌کند، نه در همهٔ مخازن. در خروجی dpkg -l، حالت رایج ii یعنی بسته برای نصب انتخاب شده و نصب است؛ rc یعنی حذف شده اما تنظیمات باقی مانده‌اند. راهنمای dpkg-query

۱۲. ارتقا، حذف و autoremove#

دستوررفتار
apt updateتازه‌کردن فهرست‌ها
apt upgradeارتقا با امکان افزودن وابستگی جدید، بدون حذف بستهٔ نصب‌شده
apt full-upgradeارتقا با امکان حذف بسته برای حل تغییر وابستگی‌ها
apt-get upgradeدر حالت معمول، بدون افزودن یا حذف بسته
apt remove PACKAGEحذف بسته با باقی‌ماندن conffileها
apt purge PACKAGEحذف بسته و تنظیمات تحت مدیریت فرایند purge

full-upgrade به‌خودی‌خود انتشار بعدی دبیان یا اوبونتو را انتخاب نمی‌کند؛ همچنان از منابع پیکربندی‌شده استفاده می‌کند. purge نیز پاک‌کنندهٔ عمومی داده‌های کاربر در home نیست. راهنمای apt ، راهنمای apt-get

APT میان بستهٔ درخواستی شما و بسته‌ای که خودکار برای وابستگی آمده تفاوت می‌گذارد. وقتی بستهٔ خودکار دیگر لازم نباشد، می‌تواند نامزد autoremove شود. برای مشاهده:

apt-mark showmanual
apt-mark showauto
apt-mark showhold
apt-get -s autoremove

اگر بسته‌ای را مستقل لازم دارید، sudo apt-mark manual PACKAGE آن را دستی علامت می‌زند. hold مفهوم دیگری دارد: درخواست نگه‌داشتن وضعیت بسته برای جلوگیری از تغییر خودکار آن است. راهنمای apt-mark

۱۳. وقتی نصب نیمه‌تمام می‌ماند#

نصب چند بسته یک تراکنش اتمیک با rollback کامل نیست. ممکن است تعدادی بسته تغییر کرده باشند و بعد اسکریپتی شکست بخورد. ابتدا محل شکست را پیدا کنید:

dpkg --audit
less /var/log/apt/history.log
less /var/log/apt/term.log
less /var/log/dpkg.log

تاریخچهٔ APT درخواست‌ها و تغییرات را نشان می‌دهد؛ term.log برای خروجی فرایند نصب و dpkg.log برای تغییر وضعیت بسته‌ها مفید است. عیب‌یابی مدیریت بسته در مرجع دبیان

پس از رفع علت، مانند کمبود فضا یا خطای تنظیمات، sudo dpkg --configure -a تنظیم بسته‌های معطل را دوباره امتحان می‌کند. اگر وابستگی‌ها شکسته‌اند، ابتدا برنامهٔ اصلاح را با apt-get -s --fix-broken install ببینید و سپس در صورت مناسب‌بودن اجرا کنید:

sudo apt-get --fix-broken install

این دستور ممکن است برای بازگرداندن سازگاری، بسته نصب یا حذف کند؛ درمان هر خطای postinst نیست. بازیابی با dpkg ، گزینهٔ fix-broken

برای خطای قفل، ابتدا بررسی کنید فرایند دیگری مانند به‌روزرسان خودکار فعال نباشد؛ حذف فایل قفل راه تشخیص نیست. برای خطای امضا، منبع، کلید و پیام دقیق را بررسی کنید؛ غیرفعال‌کردن تأیید اصالت علت خطا را برطرف نمی‌کند.

۱۴. تمرین: مسیر یک بسته را دنبال کنید#

این تمرین را می‌توان بدون نصب nginx انجام داد:

# نسخه و سیاست انتخاب
apt-cache policy nginx

# روابط بسته و برنامهٔ نصب
apt-cache depends nginx
apt-get -s install nginx

# متادیتای نسخه‌های موجود در فهرست محلی
apt-cache show nginx

# دانلود در پوشهٔ آزمایش، بدون نصب
mkdir -p ~/apt-lab/nginx
cd ~/apt-lab/nginx
apt download nginx
dpkg-deb --info ./nginx_*.deb
dpkg-deb --contents ./nginx_*.deb

خروجی‌ها را کنار هم بگذارید: آیا Candidate با نسخهٔ فایل یکی است؟ چه وابستگی‌هایی از قبل نصب بوده‌اند؟ کدام فایل‌ها داخل این بسته‌اند و کدام احتمالاً در بسته‌ای دیگر قرار دارند؟ پاسخ دقیق به انتشار و معماری سیستم شما وابسته است؛ نام nginx به‌تنهایی محتوای تمام بسته‌های مرتبط را مشخص نمی‌کند.

منابع و ایدهٔ اولیه#

ایدهٔ دنبال‌کردن مسیر نصب و سپس بررسی ساختار مخزن از این دو نوشته آمده است؛ متن حاضر ترجمهٔ آن‌ها نیست:

جزئیات فنی با مستندات رسمی پیوندشده در هر بخش تطبیق داده شده‌اند. به‌ویژه توضیح امضای مستقل هر .deb در مقالهٔ اول با مدل معمول apt-secure سازگار نیست. مثال‌های apt-key در مقالهٔ قدیمی Packagecloud نیز مبنای تنظیم پیشنهادی این نوشته نیستند؛ اینجا کلید هر منبع با Signed-By مشخص شده است.