توی این درس یاد میگیری در Debian و Ubuntu برنامهها با apt نصب میشوند: از مخزنها (repositories) که فهرست بستهها را دارند، با حل خودکار وابستگیها. فرق apt update (بهروزکردن فهرست بستهها) و apt upgrade (بهروزکردن برنامههای نصبشده) را میفهمی؛ با apt search، apt install، apt remove و purge کار میکنی؛ ابزار پایهی dpkg (dpkg -l، -L، -S، -i) را میشناسی؛ و میبینی چطور یک میرور داخلی را آزمایش و منبع دانلود را عوض کنی. تمرین: htop را نصب میکنی و منبع apt را به یک میرور داخلی تغییر میدهی.
مسئله: برنامه را از کجا و چطور بگیریم؟
Section titled “مسئله: برنامه را از کجا و چطور بگیریم؟”در ویندوز معمولاً فایل نصب را از سایت هر برنامه میگیری و اجرا میکنی. در لینوکس مدیر بسته (package manager) این کار را برایت میکند: برنامه را از یک مخزن مورد اعتماد (با امضای دیجیتال) میگیرد، وابستگیها (کتابخانههایی که برنامه لازم دارد) را خودش پیدا و نصب میکند، همهچیز را ثبت میکند تا بشود بهروز کرد یا کامل حذف کرد.
تشبیه: مدیر انبار و کارگر قفسهچین
Section titled “تشبیه: مدیر انبار و کارگر قفسهچین”apt مثل مدیر انبار است: فهرست کالاها را میخواند (update)، سفارش را بررسی میکند (install)، میداند هر کالا چه قطعاتی لازم دارد (وابستگیها)، و از انبار مرکزی (مخزن یا میرور) میآورد. dpkg کارگر قفسهچین است: فقط یک بستهی آماده (.deb) را میگیرد و روی قفسهها (/usr/bin، /etc…) میگذارد، بدون اینکه بداند از کجا آمده یا قطعاتش کجاست.
مثالهای عملی
Section titled “مثالهای عملی”همهی این درس روی Ubuntu 24.04 واقعی اجرا شده است (در ماشین آزمایشی من که یک ARM است؛ فقط یک نکتهی معماری در مثال ۱ و ۷ هست). دستورهای نصب و حذف root میخواهند، پس با sudo.
مثال ۱: مخزنها، apt بستهها را از کجا میآورد؟
Section titled “مثال ۱: مخزنها، apt بستهها را از کجا میآورد؟”فایل منبعها در Ubuntu 24.04 این است (فرمت جدید deb822؛ نسخههای قدیمیتر بهجایش فایل /etc/apt/sources.list دارند):
. /etc/os-release; echo "سیستم: $PRETTY_NAME"echo "معماری: $(dpkg --print-architecture)"echo "--- /etc/apt/sources.list.d/ubuntu.sources (بدون توضیح):"grep -v '^#' /etc/apt/sources.list.d/ubuntu.sources | grep -v '^$'سیستم: Ubuntu 24.04.5 LTSمعماری: arm64--- /etc/apt/sources.list.d/ubuntu.sources (بدون توضیح):Types: debURIs: http://ports.ubuntu.com/ubuntu-ports/Suites: noble noble-updates noble-backportsComponents: main universe restricted multiverseSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpgTypes: debURIs: http://ports.ubuntu.com/ubuntu-ports/Suites: noble-securityComponents: main universe restricted multiverseSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpgهر بلوک یک مخزن است:
| کلید | معنی |
|---|---|
URIs |
آدرس مخزن (همان جایی که میشود عوضش کرد؛ مثال ۷) |
Suites |
شاخهها: noble (نسخهی اصلی ۲۴٫۰۴)، noble-updates (اصلاحات بعدی)، noble-backports (نسخههای جدیدتر)، noble-security (وصلههای امنیتی) |
Components |
بخشها: main (رسمی و پشتیبانیشده)، universe (جامعه)، restricted و multiverse (مالکیتی یا با محدودیت) |
Signed-By |
کلید عمومی که امضای مخزن را بررسی میکند (امنیت) |
یک نکته: آدرس این ماشین ports.ubuntu.com/ubuntu-ports است چون معماری ARM (arm64) است. روی سرور و WSL معمولی (x86) آدرس archive.ubuntu.com/ubuntu و برای وصلههای امنیتی security.ubuntu.com/ubuntu است؛ بقیهی ساختار یکی است.
مثال ۲: apt update در برابر apt upgrade
Section titled “مثال ۲: apt update در برابر apt upgrade”apt یک نسخهی محلی از فهرست بستهها نگه میدارد (در /var/lib/apt/lists). apt update فقط آن فهرست را از مخزنها تازه میکند و هیچ برنامهای را عوض نمیکند. در ماشینهای داکری فهرست عمداً خالی است (تا image کوچک بماند)؛ ببین بدون update چه میشود:
sudo rm -rf /var/lib/apt/lists/*sudo apt install -y figletReading package lists...Building dependency tree...Reading state information...E: Unable to locate package figletUnable to locate package: apt هیچ فهرستی ندارد که بداند figlet چیست. روی یک سرور تازه هم اگر مدتی از آخرین update گذشته باشد، همین خطا یا نسخههای قدیمی میبینی. پس اول:
sudo apt updateGet:17 http://ports.ubuntu.com/ubuntu-ports noble-security/universe arm64 Packages [1624 kB]Get:18 http://ports.ubuntu.com/ubuntu-ports noble-security/restricted arm64 Packages [2886 kB]Get:19 http://ports.ubuntu.com/ubuntu-ports noble-security/multiverse arm64 Packages [89.7 kB]Fetched 35.1 MB in 46s (755 kB/s)Reading package lists...Building dependency tree...Reading state information...2 packages can be upgraded. Run 'apt list --upgradable' to see them.خطهای Get: یعنی فهرست یک بخش از یک مخزن دانلود شد (Hit: یعنی تغییری نکرده). آخرش میگوید چند بسته نسخهی جدیدتر دارند. ببینیمشان، و بدون هیچ تغییری شبیهسازی کنیم upgrade چه میکرد (--dry-run):
echo "--- بستههای قابلبهروزرسانی:"apt list --upgradable 2>/dev/nullecho "--- شبیهسازی upgrade (--dry-run؛ چیزی نصب نمیشود):"sudo apt upgrade --dry-run | grep -E '^(Inst|[0-9]+ upgraded)'--- بستههای قابلبهروزرسانی:Listing...libaudit-common/noble-updates 1:3.1.2-2.1ubuntu0.1 all [upgradable from: 1:3.1.2-2.1build1.1]libaudit1/noble-updates 1:3.1.2-2.1ubuntu0.1 arm64 [upgradable from: 1:3.1.2-2.1build1.1]--- شبیهسازی upgrade (--dry-run؛ چیزی نصب نمیشود):2 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.Inst libaudit-common [1:3.1.2-2.1build1.1] (1:3.1.2-2.1ubuntu0.1 Ubuntu:24.04/noble-updates [all])Inst libaudit1 [1:3.1.2-2.1build1.1] (1:3.1.2-2.1ubuntu0.1 Ubuntu:24.04/noble-updates [arm64])apt update: فهرست را تازه کن (کاتالوگ).apt upgrade: نسخهی جدیدتر برنامههایی که نصباند را نصب کن، بدون حذف یا نصب بستهی دیگر.apt full-upgradeاگر لازم باشد بستهها را حذف/اضافه هم میکند. هیچکدام سیستم را به نسخهی بعدی Ubuntu نمیبرند.
ترتیب همیشگی: sudo apt update && sudo apt upgrade. (apt upgrade را من فقط شبیهسازی کردم تا ماشین آزمایشی تغییر نکند؛ روی سرور خودت با -y تأیید خودکار هم میگیری.)
مثال ۳: جستجو و اطلاعات بسته
Section titled “مثال ۳: جستجو و اطلاعات بسته”echo "--- apt search (جستجو در نام و توضیح):"apt search figlet 2>/dev/null | head -6echo "--- apt show (جزئیات؛ ۱۲ خط اول):"apt show figlet 2>/dev/null | head -12echo "--- apt-cache policy (کدام نسخه و از کدام مخزن؟):"apt-cache policy figlet--- apt search (جستجو در نام و توضیح):Sorting...Full Text Search...figlet/noble 2.2.5-3 arm64 Make large character ASCII banners out of ordinary text
php-text-figlet/noble 1.0.2-5 all--- apt show (جزئیات؛ ۱۲ خط اول):Package: figletVersion: 2.2.5-3Priority: optionalSection: universe/textOrigin: UbuntuMaintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>Original-Maintainer: Carlos Laviola <claviola@debian.org>Bugs: https://bugs.launchpad.net/ubuntu/+filebugInstalled-Size: 745 kBDepends: libc6 (>= 2.17)Homepage: http://www.figlet.org/Download-Size: 130 kB--- apt-cache policy (کدام نسخه و از کدام مخزن؟):figlet: Installed: (none) Candidate: 2.2.5-3 Version table: 2.2.5-3 500 500 http://ports.ubuntu.com/ubuntu-ports noble/universe arm64 PackagesCandidate نسخهای است که نصب میشود، Installed: (none) یعنی هنوز نصب نیست، و آخر خط، مخزنی که این نسخه را دارد. Depends در apt show وابستگیهاست.
مثال ۴: apt install
Section titled “مثال ۴: apt install”sudo apt install -y figletReading package lists...Building dependency tree...Reading state information...The following NEW packages will be installed: figlet0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.Need to get 130 kB of archives.After this operation, 745 kB of additional disk space will be used.Get:1 http://ports.ubuntu.com/ubuntu-ports noble/universe arm64 figlet arm64 2.2.5-3 [130 kB]Fetched 130 kB in 1s (104 kB/s)Selecting previously unselected package figlet.(Reading database ... 23924 files and directories currently installed.)Preparing to unpack .../figlet_2.2.5-3_arm64.deb ...Unpacking figlet (2.2.5-3) ...Setting up figlet (2.2.5-3) ...update-alternatives: using /usr/bin/figlet-figlet to provide /usr/bin/figlet (figlet) in auto modeProcessing triggers for man-db (2.12.0-4build2) ...مراحل خروجی: فهرست و وابستگیها محاسبه شد؛ «NEW packages will be installed» یعنی چه چیزهایی تازه میآیند (اینجا فقط یک بسته)؛ Get: دانلود از مخزن؛ و بعد Unpacking/Setting up، یعنی dpkg فایلها را باز و تنظیم کرد. -y به همهی پرسشهای «ادامه بدهم؟» جواب «بله» میدهد (برای اسکریپتها)؛ بدون آن apt قبل از نصب میپرسد [Y/n]. حالا برنامه کار میکند، و ببین بسته چه چیزی روی سیستم گذاشته:
figlet LoopXecho "--- کجاست؟"which figletecho "--- فایل ls مال کدام بسته است؟ (dpkg -S)"dpkg -S /usr/bin/lsecho "--- فایلهایی که بستهی figlet نصب کرده (dpkg -L؛ چند تای اول):"dpkg -L figlet | head -8 _ __ __| | ___ ___ _ __\ \/ /| | / _ \ / _ \| '_ \\ /| |__| (_) | (_) | |_) / \|_____\___/ \___/| .__/_/\_\ |_|--- کجاست؟/usr/bin/figlet--- فایل ls مال کدام بسته است؟ (dpkg -S)coreutils: /usr/bin/ls--- فایلهایی که بستهی figlet نصب کرده (dpkg -L؛ چند تای اول):/./etc/etc/emacs/etc/emacs/site-start.d/etc/emacs/site-start.d/50figlet.el/usr/usr/bin/usr/bin/chkfontdpkg -S فایل میگوید یک فایل مال کدام بسته است (ls مال بستهی coreutils است) و dpkg -L بسته همهی فایلهای نصبشدهی یک بسته را میدهد. (چون figlet با سازوکار update-alternatives یک لینک نمادین /usr/bin/figlet میسازد، خود آن مسیر در فهرست بسته نیست و برای آن dpkg -S جوابی نمیدهد؛ برای فایلهای معمولی مثل ls همیشه جواب میدهد.)
کدام دستور میگوید فایل /usr/bin/ls از کدام بسته آمده؟
dpkg -S (search) از فایل به بسته میرسد؛ dpkg -L (list) از بسته به فهرست فایلهایش.
مثال ۵: apt remove، purge و autoremove
Section titled “مثال ۵: apt remove، purge و autoremove”remove برنامه را حذف میکند ولی فایلهای تنظیمات (در /etc) را نگه میدارد، تا اگر دوباره نصب کردی تنظیماتت سر جایش باشد. purge همهچیز را پاک میکند. با یک فایل تنظیمات واقعی همین بسته ببینیمش:
CONF=/etc/emacs/site-start.d/50figlet.elecho "; تنظیم شخصی من" | sudo tee -a $CONF > /dev/nullecho "--- بعد از apt remove:"sudo apt remove -y figletls -l $CONFdpkg -l figlet | tail -1echo "--- بعد از apt purge:"sudo apt purge -y figletls $CONFdpkg -l figlet | tail -1--- بعد از apt remove:Reading package lists...Building dependency tree...Reading state information...The following packages will be REMOVED: figlet0 upgraded, 0 newly installed, 1 to remove and 2 not upgraded.After this operation, 745 kB disk space will be freed.(Reading database ... 24003 files and directories currently installed.)Removing figlet (2.2.5-3) ...Processing triggers for man-db (2.12.0-4build2) ...-rw-r--r-- 1 root root 317 Oct 3 21:42 /etc/emacs/site-start.d/50figlet.elrc figlet 2.2.5-3 arm64 Make large character ASCII banners out of ordinary text--- بعد از apt purge:Reading package lists...Building dependency tree...Reading state information...The following packages will be REMOVED: figlet*0 upgraded, 0 newly installed, 1 to remove and 2 not upgraded.After this operation, 0 B of additional disk space will be used.(Reading database ... 23927 files and directories currently installed.)Purging configuration files for figlet (2.2.5-3) ...ls: cannot access '/etc/emacs/site-start.d/50figlet.el': No such file or directorydpkg-query: no packages found matching figletستون اول dpkg -l وضعیت بسته است: ii نصبشده، rc حذفشده ولی تنظیماتش مانده (removed, config files)، و un (unknown/not installed) یعنی هیچ ردی نیست. بعد از remove فایل مانده بود (rc) و بعد از purge رفت (un). و وابستگیهایی که فقط به خاطر یک بسته نصب شده بودند را با sudo apt autoremove پاک میکنی:
sudo apt autoremove -yReading package lists...Building dependency tree...Reading state information...0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.مثال ۶: dpkg و نصب دستی یک فایل .deb
Section titled “مثال ۶: dpkg و نصب دستی یک فایل .deb”گاهی یک فایل .deb داری (از سایت یک برنامه یا apt download). dpkg -i آن را نصب میکند، ولی وابستگیها را حل نمیکند. با apt download یک .deb بدون وابستگیهایش بگیریم تا این را ببینیم (mc، یک فایلمنیجر ترمینالی):
apt download mc 2>&1 | tail -1ls -1 mc_*.debsudo dpkg -i mc_*.debFetched 562 kB in 1s (441 kB/s)mc_3%3a4.8.30-1ubuntu0.1_arm64.debSelecting previously unselected package mc.(Reading database ... 23924 files and directories currently installed.)Preparing to unpack mc_3%3a4.8.30-1ubuntu0.1_arm64.deb ...Unpacking mc (3:4.8.30-1ubuntu0.1) ...dpkg: dependency problems prevent configuration of mc: mc depends on libslang2 (>= 2.2.4); however: Package libslang2 is not installed. mc depends on libssh2-1t64 (>= 1.2.8); however: Package libssh2-1t64 is not installed. mc depends on mc-data (= 3:4.8.30-1ubuntu0.1); however: Package mc-data is not installed.
dpkg: error processing package mc (--install): dependency problems - leaving unconfiguredErrors were encountered while processing: mcdpkg نصب را نیمهکاره گذاشت: mc به کتابخانههایی (libslang2 و بقیه) نیاز دارد که نصب نیستند، و فقط apt میداند آنها را از کجا بیاورد. راهحل apt install -f (fix broken) است که وابستگیهای ناقص را کامل میکند:
sudo apt install -f -y 2>&1 | tail -6dpkg -l mc | tail -1echo "--- پاکسازی:"sudo apt purge -y mc > /dev/nullsudo apt autoremove -y > /dev/nullrm -f mc_*.debdpkg -l | grep -c '^ii'Setting up libslang2:arm64 (2.3.3-3build2) ...Setting up mc-data (3:4.8.30-1ubuntu0.1) ...Setting up libssh2-1t64:arm64 (1.11.0-4.1ubuntu0.24.04.4) ...Setting up mc (3:4.8.30-1ubuntu0.1) ...Processing triggers for man-db (2.12.0-4build2) ...Processing triggers for libc-bin (2.39-0ubuntu8.9) ...ii mc 3:4.8.30-1ubuntu0.1 arm64 Midnight Commander - a powerful file manager--- پاکسازی:303پس dpkg -l فهرست همهی بستههای نصبشده است (عدد آخر: بستههای ii). برای نصب یک .deb محلی، بهتر است مستقیم sudo apt install ./فایل.deb بزنی (apt وابستگیها را خودش میآورد). قاعده: از apt استفاده کن؛ dpkg فقط برای پرسوجو (-l، -L، -S).
مثال ۷: میرور، منبع دانلود را عوض کن
Section titled “مثال ۷: میرور، منبع دانلود را عوض کن”میرور یک کپی کامل از مخزن روی یک سرور دیگر است. سه چیز برای انتخاب یک میرور مهم است: در دسترس بودن، سرعت و مهمتر تازهبودن: میرور بیبهروز یعنی وصلههای امنیتی دیر میرسند. هر سه را با یک حلقهی curl از همین ماشین بررسی میکنم. برای هر آدرس، فایل InRelease شاخهی امنیتی (noble-security) را میگیرم و کد پاسخ، زمان، و مهمتر تاریخ Date: آن را چاپ میکنم (تاریخی که مخزن آخرین بار تازه شده):
for m in http://archive.ubuntu.com/ubuntu https://mirror.arvancloud.ir/ubuntu https://repo.iut.ac.ir/ubuntu https://ubuntu.pishgaman.net/ubuntu https://mirror.iranserver.com/ubuntu; do code=$(curl -sL -m 20 -o /tmp/inrelease -w '%{http_code} %{time_total}s' "$m/dists/noble-security/InRelease") echo "$code | $(grep -m1 '^Date:' /tmp/inrelease) | $m"donerm -f /tmp/inreleaseecho "--- ساعت همین سیستم: $(date -u '+%a, %d %b %Y %H:%M UTC')"200 0.853118s | Date: Sat, 03 Oct 2026 8:51:07 UTC | http://archive.ubuntu.com/ubuntu200 0.370186s | Date: Fri, 02 Oct 2026 3:27:10 UTC | https://mirror.arvancloud.ir/ubuntu200 0.635259s | Date: Thu, 01 Oct 2026 17:53:35 UTC | https://repo.iut.ac.ir/ubuntu200 0.322770s | Date: Sat, 03 Oct 2026 8:51:07 UTC | https://ubuntu.pishgaman.net/ubuntu200 0.572752s | Date: Fri, 02 Oct 2026 6:20:59 UTC | https://mirror.iranserver.com/ubuntu--- ساعت همین سیستم: Sat, 03 Oct 2026 21:42 UTC(اینها چند میرور عمومی Ubuntu هستند که آدرسشان را آزمایش کردهام؛ توصیهی رسمی نیستند و کیفیتشان با زمان و شبکهی تو تغییر میکند. نتیجهی بالا مال همین لحظه است و باید خودت تست کنی.) هر خط: کد 200 یعنی در دسترس، زمان پاسخ، و Date: آخرین تازهشدن. میرور خوب 200 با تاریخ نزدیک به الآن دارد. اگر تاریخ یک میرور هفتهها عقب باشد از آن استفاده نکن.
حالا خود تغییر منبع. چون ماشین آزمایشی من ARM است و میرورهای ایرانیِ Ubuntu که آزمایش کردم فقط نسخهی x86 (/ubuntu) را دارند (نه ubuntu-ports)، همین کار را روی یک Debian انجام میدهم: Debian با Ubuntu همان apt را دارد و میرور مورد نظر نسخهی ARM آن را هم دارد. یک کانتینر Debian دورریختنی (lx-deb) میسازم (-e DEBIAN_FRONTEND=noninteractive یعنی apt پرسش تعاملی نپرسد) و منبع پیشفرضش را نشان میدهم (از اینجا deb یعنی «در آن کانتینر اجرا کن»):
docker rm -f lx-deb > /dev/null 2>&1docker run -d -e DEBIAN_FRONTEND=noninteractive --name lx-deb debian:stable-slim sleep 900 > /dev/nulldeb() { docker exec lx-deb "$@"; }echo "--- منبع پیشفرض Debian:"deb grep -E '^(URIs|Suites)' /etc/apt/sources.list.d/debian.sources--- منبع پیشفرض Debian:URIs: http://deb.debian.org/debianSuites: stable stable-updatesURIs: http://deb.debian.org/debian-securitySuites: stable-securityآدرس مخزن اصلی (http://deb.debian.org/debian) همان خط URIs اول است؛ دومی مخزن امنیتی. اگر URIs را به یک میرور HTTPS عوض کنیم، با یک تله روبهرو میشویم که روی image های کمحجم (و گاهی سرورهای تازه) رایج است:
deb() { docker exec lx-deb "$@"; }deb sed -i 's|http://deb.debian.org/debian$|https://mirror.iranserver.com/debian|' /etc/apt/sources.list.d/debian.sourcesdeb grep -E '^URIs' /etc/apt/sources.list.d/debian.sourcesecho "--- apt-get update:"deb apt-get update 2>&1 | grep -E '^W:' | head -2URIs: https://mirror.iranserver.com/debianURIs: http://deb.debian.org/debian-security--- apt-get update:W: Failed to fetch https://mirror.iranserver.com/debian/dists/stable/InRelease SSL connection failed: error:0A000086:SSL routines::certificate verify failed / Success [IP: 185.255.89.114 443]W: Failed to fetch https://mirror.iranserver.com/debian/dists/stable-updates/InRelease SSL connection failed: error:0A000086:SSL routines::certificate verify failed / Success [IP: 185.255.89.114 443]SSL ... certificate verify failed: برای اعتبارسنجی HTTPS به بستهی ca-certificates (فهرست گواهیهای معتبر) نیاز است که در این image نیست. راهحل (مشکل مرغ و تخممرغ): برای نصب ca-certificates به منبع قدیمی (HTTP) برگرد، نصبش کن، بعد منبع را عوض کن:
deb() { docker exec lx-deb "$@"; }deb sed -i 's|https://mirror.iranserver.com/debian$|http://deb.debian.org/debian|' /etc/apt/sources.list.d/debian.sourcesdeb apt-get update -qqdeb apt-get install -y -qq ca-certificates > /dev/nulldeb sed -i 's|http://deb.debian.org/debian$|https://mirror.iranserver.com/debian|' /etc/apt/sources.list.d/debian.sourcesecho "--- apt-get update با میرور:"deb apt-get update 2>&1 | tail -7echo "--- از کدام مخزن نصب میشود؟"deb apt-cache policy htop | head -6--- apt-get update با میرور:Get:1 https://mirror.iranserver.com/debian stable InRelease [140 kB]Hit:2 http://deb.debian.org/debian-security stable-security InReleaseGet:3 https://mirror.iranserver.com/debian stable-updates InRelease [47.3 kB]Get:4 https://mirror.iranserver.com/debian stable/main arm64 Packages [9614 kB]Get:5 https://mirror.iranserver.com/debian stable-updates/main arm64 Packages [4424 B]Fetched 9806 kB in 8s (1296 kB/s)Reading package lists...--- از کدام مخزن نصب میشود؟htop: Installed: (none) Candidate: 3.4.1-5 Version table: 3.4.1-5 500 500 https://mirror.iranserver.com/debian stable/main arm64 Packagesحالا Get: ها از آدرس میرور میآیند (خط stable و stable-updates). دقت کن مخزن امنیتی (debian-security) را عمداً دست نزدم و از منبع رسمی ماند. اگر آن را هم به این میرور ببریم:
deb() { docker exec lx-deb "$@"; }deb sed -i 's|http://deb.debian.org/debian-security|https://mirror.iranserver.com/debian-security|' /etc/apt/sources.list.d/debian.sourcesdeb apt-get update 2>&1 | grep -E '^E:'E: Release file for https://mirror.iranserver.com/debian-security/dists/stable-security/InRelease is expired (invalid since 12d 9h 10min 59s). Updates for this repository will not be applied.و تاریخ آخرین تازهشدن همان مخزن، در برابر منبع رسمی (همان تکنیک InRelease بالا):
for m in https://mirror.iranserver.com/debian-security http://deb.debian.org/debian-security; do echo "$(curl -sL -m 20 "$m/dists/stable-security/InRelease" | grep -m1 '^Date:') ← $m"doneDate: Mon, 14 Sep 2026 12:32:40 UTC ← https://mirror.iranserver.com/debian-securityDate: Sat, 03 Oct 2026 21:12:44 UTC ← http://deb.debian.org/debian-securityRelease file ... is expired: در لحظهی آزمایش، تاریخ مخزن امنیتی این میرور حدود دو هفته عقبتر از منبع رسمی بود، و apt (بهدرستی) نمیگذارد از فهرست منقضیشده استفاده شود. (این برای همان لحظه است؛ میرورها گاهی عقب میافتند و بعداً بهروز میشوند. به همین دلیل میرور را قبل از استفاده تست کن.) قاعده: بهروزرسانیهای امنیتی را از منبع رسمی بگیر مگر میرور را تازهبودنش را مرتب بسنجی. حالا به حالت سالم برمیگردانیم و htop را از میرور نصب میکنیم:
deb() { docker exec lx-deb "$@"; }deb sed -i 's|https://mirror.iranserver.com/debian-security|http://deb.debian.org/debian-security|' /etc/apt/sources.list.d/debian.sourcesdeb apt-get update -qqecho "--- نصب htop (از میرور):"deb apt-get install -y htop 2>&1 | grep -E '^(Get|Setting up htop)'deb htop --versiondocker rm -f lx-deb > /dev/null--- نصب htop (از میرور):Get:1 https://mirror.iranserver.com/debian stable/main arm64 libncursesw6 arm64 6.5+20250216-2 [124 kB]Get:2 https://mirror.iranserver.com/debian stable/main arm64 htop arm64 3.4.1-5 [164 kB]Get:3 https://mirror.iranserver.com/debian stable/main arm64 libgpm2 arm64 1.20.7-11+b2 [14.7 kB]Setting up htop (3.4.1-5) ...htop 3.4.1htop از https://mirror.iranserver.com/debian دانلود شد: همان تغییر منبع، با همان دستورهای apt. روی Ubuntu 24.04 (x86) فقط فایل و آدرسها فرق دارند. دستورهای زیر را روی ماشین x86 اجرا نکردهام (نمونه)، ولی ساختار همان است که بالا نشان دادم:
# مخزن اصلی را به میرور ببر، مخزن امنیتی را رسمی بگذارsudo sed -i 's|http://archive.ubuntu.com/ubuntu|https://mirror.arvancloud.ir/ubuntu|' /etc/apt/sources.list.d/ubuntu.sourcessudo apt updateبرای Ubuntu 22.04 و قدیمیتر فایل /etc/apt/sources.list است (همان sed روی آن). و بعد از هر تغییر یادت نرود apt update.
پشت پرده: apt و dpkg چطور کار میکنند؟
Section titled “پشت پرده: apt و dpkg چطور کار میکنند؟”dpkg بستهها را روی دیسک مینشاند و در یک پایگاه دادهی سادهی متنی (/var/lib/dpkg/status) ثبت میکند که چه چیزی نصب است. apt لایهی بالاتر است: فهرستهای مخزنها را در /var/lib/apt/lists نگه میدارد، گراف وابستگی را حل میکند و بعد dpkg را صدا میزند. هر بسته یک فایل .deb است که یک آرشیو ساده است:
echo "--- بستهی دانلودشده را بدون نصب باز میکنیم (dpkg-deb):"apt download figlet 2>&1 | tail -1f=$(ls figlet_*.deb)dpkg-deb -I "$f" | grep -E '^ (Package|Version|Architecture|Depends|Description):' | head -5echo "--- فایلهای داخلش (۶ تای اول):"dpkg-deb -c "$f" | awk 'NR <= 6 {print $1, $6}'rm -f "$f"echo "--- پایگاهدادهی dpkg و فهرستهای apt:"ls /var/lib/dpkg/statusls /var/lib/apt/lists | head -3--- بستهی دانلودشده را بدون نصب باز میکنیم (dpkg-deb):Fetched 130 kB in 1s (137 kB/s) Package: figlet Version: 2.2.5-3 Architecture: arm64 Depends: libc6 (>= 2.17) Description: Make large character ASCII banners out of ordinary text--- فایلهای داخلش (۶ تای اول):drwxr-xr-x ./drwxr-xr-x ./etc/drwxr-xr-x ./etc/emacs/drwxr-xr-x ./etc/emacs/site-start.d/-rw-r--r-- ./etc/emacs/site-start.d/50figlet.eldrwxr-xr-x ./usr/--- پایگاهدادهی dpkg و فهرستهای apt:/var/lib/dpkg/statusauxfileslockpartialdpkg-deb -I (info) متادیتا و dpkg-deb -c (contents) فهرست فایلها را بدون نصب نشان میدهند. و هنگام نصب هر .deb این اتفاق میافتد: بررسی امضا (apt)، باز کردن در مسیرها، اجرای اسکریپتهای postinst (تنظیمات)، ثبت در /var/lib/dpkg/status.
جدولهای مرجع
Section titled “جدولهای مرجع”| دستور | کار |
|---|---|
sudo apt update |
تازهکردن فهرست بستهها |
sudo apt upgrade |
بهروزکردن برنامههای نصبشده |
apt list --upgradable |
بستههای قابلبهروزرسانی |
apt search عبارت |
جستجو |
apt show بسته / apt-cache policy بسته |
جزئیات / نسخه و مخزن |
sudo apt install بسته |
نصب (-y تأیید خودکار) |
sudo apt install ./فایل.deb |
نصب یک .deb محلی با حل وابستگی |
sudo apt remove بسته |
حذف (تنظیمات میماند) |
sudo apt purge بسته |
حذف کامل با تنظیمات |
sudo apt autoremove |
پاککردن وابستگیهای بیصاحب |
sudo apt install -f |
رفع وابستگیهای ناقص |
apt download بسته |
دانلود .deb بدون نصب |
dpkg -l [الگو] |
فهرست بستههای نصبشده |
dpkg -L بسته / dpkg -S فایل |
فایلهای بسته / بستهی یک فایل |
dpkg -i فایل.deb |
نصب دستی (بدون حل وابستگی) |
وضعیت در dpkg -l |
معنی |
|---|---|
ii |
نصبشده |
rc |
حذفشده ولی فایلهای تنظیمات مانده |
un |
نصبنشده و بدون ردپا |
اشتباهات رایج
Section titled “اشتباهات رایج”۱) install بدون update
Section titled “۱) install بدون update”مثال ۲: E: Unable to locate package. راهحل: sudo apt update اول. (روی سرورهای زنده هم قبل از نصب update کن تا نسخهی قدیمی یا خطا نگیری.)
۲) فراموشکردن sudo
Section titled “۲) فراموشکردن sudo”apt install -y figletE: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?Permission denied و «are you root?»: نصب بسته روی کل سیستم اثر میگذارد و فقط root اجازه دارد. (پیام Unable to acquire the dpkg frontend lock هم برای همین است.) راهحل: sudo apt install ....
۳) «Waiting for cache lock»
Section titled “۳) «Waiting for cache lock»”( sudo apt-get install -y --reinstall figlet > /dev/null 2>&1 & )sleep 1sudo apt install -y figlet 2>&1 | head -2sleep 4Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 3857 (apt-get)...Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 3857 (apt-get)...هر زمان فقط یک apt/dpkg میتواند اجرا شود؛ دومی با این پیام منتظر میماند (همیشه یک قفل در /var/lib/dpkg/lock-frontend میگیرند). پیام میگوید قفل دست چه پروسهای است. راهحل: صبر کن تا اولی تمام شود (معمولاً بهروزرسانی خودکار پسزمینه است)؛ و هرگز فایلهای lock را دستی پاک نکن، چون ممکن است پایگاهدادهی بستهها خراب شود.
۴) dpkg -i برای نصب یک .deb با وابستگی
Section titled “۴) dpkg -i برای نصب یک .deb با وابستگی”مثال ۶: نصب نیمهکاره و «dependency problems». راهحل: sudo apt install ./فایل.deb یا بعد از dpkg -i، sudo apt install -f.
۵) میرور HTTPS بدون ca-certificates، یا میرور بیبهروز
Section titled “۵) میرور HTTPS بدون ca-certificates، یا میرور بیبهروز”مثال ۷: certificate verify failed و Release file ... is expired. راهحل: اول ca-certificates را نصب کن (یا موقتاً HTTP)، و تاریخ InRelease میرور را با منبع رسمی بسنج؛ امنیتی را از رسمی بگیر.
۶) فراموشکردن purge
Section titled “۶) فراموشکردن purge”بعد از remove، فایلهای تنظیمات میمانند (rc) و نصب مجدد با تنظیمات قدیمی بالا میآید که گاهی همان مشکلی است که میخواستی از شرش خلاص شوی. راهحل: برای شروع تمیز purge.
تعداد بستههای نصبشده روی سیستم را بشمار (فقط خطهایی که وضعیتشان ii است) و بررسی کن tmux نصب است یا نه.
دیدن جواب
echo "تعداد بستههای نصبشده: $(dpkg -l | grep -c '^ii')"dpkg -l tmux | tail -1تعداد بستههای نصبشده: 304ii tmux 3.4-1ubuntu0.1 arm64 terminal multiplexerتمرین اصلی: htop را نصب کن و منبع apt را به یک میرور داخلی تغییر بده. روی ماشین آزمایشی (ARM) میرور Ubuntu قابلاستفاده نیست، پس این را در یک کانتینر Debian دورریختنی انجام میدهم: میرور را بگذار، ca-certificates را فراموش نکن، htop را نصب کن و apt-cache policy htop را ببین تا مخزن را نشان دهد. (روی Ubuntu x86 فقط فایل ubuntu.sources و آدرس فرق دارند.)
دیدن جواب
docker rm -f lx-deb2 > /dev/null 2>&1docker run -d -e DEBIAN_FRONTEND=noninteractive --name lx-deb2 debian:stable-slim sleep 600 > /dev/nulld() { docker exec lx-deb2 "$@"; }d apt-get update -qqd apt-get install -y -qq ca-certificates > /dev/nulld sed -i 's|http://deb.debian.org/debian$|https://mirror.iranserver.com/debian|' /etc/apt/sources.list.d/debian.sourcesd apt-get update -qqd apt-get install -y -qq htop > /dev/nullecho "--- مخزن htop:"d apt-cache policy htop | sed -n '1,3p;5,6p'd dpkg -l htop | tail -1docker rm -f lx-deb2 > /dev/null--- مخزن htop:htop: Installed: 3.4.1-5 Candidate: 3.4.1-5 *** 3.4.1-5 500 500 https://mirror.iranserver.com/debian stable/main arm64 Packagesii htop 3.4.1-5 arm64 interactive processes viewerیک بسته را کامل «بررسی» کن: figlet را نصب کن، با dpkg -L تعداد فایلهایش را بشمار، با dpkg -S ثابت کن فایل /etc/emacs/site-start.d/50figlet.el مال همین بسته است، با purge پاکش کن و ثابت کن هیچ ردی نمانده (which و dpkg -l).
دیدن جواب
sudo apt install -y figlet > /dev/nullecho "تعداد فایلهای بسته: $(dpkg -L figlet | wc -l)"dpkg -S /etc/emacs/site-start.d/50figlet.elsudo apt purge -y figlet > /dev/nullsudo apt autoremove -y > /dev/nullwhich figlet || echo "figlet پیدا نشد"dpkg -l figlet | tail -1تعداد فایلهای بسته: 87figlet: /etc/emacs/site-start.d/50figlet.elfiglet پیدا نشدdpkg-query: no packages found matching figletآزمونک
Section titled “آزمونک”تفاوت apt update و apt upgrade؟
update فقط کاتالوگ است؛ upgrade برنامهها را عوض میکند.
روی ماشینی تازه apt install foo میگوید Unable to locate package. اول چه میزنی؟
فهرست بستهها خالی یا قدیمی است.
تفاوت apt remove و apt purge؟
وضعیت dpkg: بعد از remove میشود rc، بعد از purge un.
کدام دستور میگوید /usr/bin/ls مال کدام بسته است؟
dpkg -S از فایل به بسته میرسد.
چرا dpkg -i فایل.deb گاهی نصب را ناقص میگذارد و چه میکنی؟
apt میداند وابستگیها را از کجا بیاورد؛ dpkg نه.
هنگام انتخاب میرور، چه چیزی مهمتر از سرعت است؟
با curl فایل InRelease را بگیر و Date را با منبع رسمی مقایسه کن؛ امنیتی را از رسمی بگیر.
جمعبندی
Section titled “جمعبندی”- apt بستهها را از مخزنها (
/etc/apt/sources.list.d/ubuntu.sources؛URIs،Suites،Components) میگیرد و وابستگیها را خودش حل میکند؛ نصب واقعی کارdpkgاست. - همیشه
sudo apt update(فهرست)، بعدsudo apt upgrade(برنامهها).--dry-runبرای شبیهسازی. apt search،apt show،apt-cache policyبرای شناخت؛sudo apt install،remove(تنظیمات میماند)،purge(همهچیز)،autoremove(وابستگیهای بیصاحب).dpkg -l(فهرست، وضعیتii/rc/un)،dpkg -L(فایلهای بسته)،dpkg -S(بستهی یک فایل)؛ نصب.debباapt install ./فایل.deb.- میرور: آدرس
URIsرا عوض کن؛ قبلش باcurlدر دسترس بودن، سرعت و تاریخInReleaseرا بسنج؛ برای HTTPS بهca-certificatesنیاز است؛ امنیتی را از منبع رسمی بگیر. - هر زمان فقط یک apt اجرا میشود (
Waiting for cache lock)؛ قفل را دستی پاک نکن.
| دستور | کاری که میکند |
|---|---|
sudo apt update | تازهکردن فهرست بستهها |
sudo apt upgrade / sudo apt upgrade --dry-run | بهروزرسانی / شبیهسازی |
apt list --upgradable | بستههای قابلبهروزرسانی |
apt search عبارت / apt show بسته | جستجو و جزئیات |
apt-cache policy بسته | نسخه و مخزن |
sudo apt install -y بسته | نصب |
sudo apt remove بسته / sudo apt purge بسته | حذف / حذف با تنظیمات |
sudo apt autoremove | وابستگیهای بیصاحب |
sudo apt install ./فایل.deb | نصب فایل .deb با وابستگی |
dpkg -l | grep بسته | نصببودن و وضعیت |
dpkg -L بسته / dpkg -S /مسیر/فایل | فایلهای بسته / بستهی فایل |
curl -sL آدرس/dists/noble-security/InRelease | grep ^Date: | تازهبودن یک میرور |