tmux یک «مالتیپلکسر ترمینال» است: برنامهای که روی خود سرور اجرا میشود و ترمینالهای شما را نگه میدارد، حتی وقتی اتصال SSH قطع میشود. یعنی اگر وسط یک آپدیت طولانی، دامپ پایگاهداده یا build اینترنتتان قطع شد، کار روی سرور ادامه پیدا میکند و با دستور tmux attach دوباره به همان صفحه برمیگردید؛ با همان خروجی و همان دستورِ در حال اجرا. علاوه بر این، tmux اجازه میدهد یک پنجرهی ترمینال را به چند بخش تقسیم کنید و چند پنجره را در یک اتصال داشته باشید.
خلاصهی کار با tmux این است: tmux new -s work یک نشست میسازد، کلیدهای Ctrl+b و بعد d از آن جدا میشوند (بدون اینکه چیزی بسته شود) و tmux attach -t work شما را برمیگرداند. در ادامه اول میبینیم چرا این اتفاق میافتد، بعد مفاهیم نشست و پنجره و پنل را توضیح میدهیم، یک فایل تنظیمات کوچک مینویسیم و در آخر یک جدول خلاصه (cheat sheet) داریم. اگر هنوز با خود SSH راحت نیستید، اول اتصال به سرور با کلید SSH را بخوانید.
چرا قطع شدن SSH پروسسها را میکشد
وقتی با SSH وارد سرور میشوید، شل شما (معمولاً bash) فرزند همان اتصال است و هر دستوری که اجرا میکنید فرزند آن شل. اگر اتصال قطع شود، سیستم به شل سیگنال SIGHUP («خط قطع شد») میفرستد و شل هم آن را به فرزندانش میرساند. رفتار پیشفرض بیشتر برنامهها در برابر این سیگنال، بستهشدن است. نتیجه: apt upgrade نیمهکاره، مایگریشنی که وسطش ماند یا فایل فشردهای که ناقص شد.
راههای قدیمیتری هم هست، مثل nohup یا فرستادن کار به پسزمینه با & و disown. اینها پروسس را زنده نگه میدارند، ولی دیگر نمیتوانید خروجی زندهاش را ببینید یا اگر سؤالی پرسید (مثل «Do you want to continue?») جوابش را بدهید. tmux خود ترمینال را روی سرور نگه میدارد، نه فقط پروسس را.
برای سرویسهایی که باید همیشه بالا باشند (یک worker صف یا یک API)، tmux جای درستی نیست؛ آنها را سرویس systemd کنید. tmux برای کار دستیِ شماست.
نصب
روی Ubuntu 24.04 معمولاً tmux از قبل نصب است. اگر نبود:
sudo apt update && sudo apt install -y tmux
tmux -V
روی Debian هم همین دستور کار میکند و روی Rocky/AlmaLinux با sudo dnf install tmux نصب میشود. tmux را روی سرور نصب کنید، نه روی لپتاپ؛ نکتهی اصلی همین است که روی سرور بماند.
سه مفهوم: نشست، پنجره، پنل
- نشست (session): بالاترین سطح. یک مجموعهی کاری با نام، مثلاً
deployیاdb. نشست تا وقتی خودتان آن را نبندید یا سرور ریاستارت نشود، زنده میماند. - پنجره (window): هر نشست چند پنجره دارد، مثل تبهای مرورگر. فهرستشان در نوار سبز پایین صفحه دیده میشود.
- پنل (pane): هر پنجره را میشود به چند بخش افقی یا عمودی تقسیم کرد؛ مثلاً یک طرف
tail -fروی لاگ و طرف دیگر شل.
یک عادت خوب: برای هر کار یک نشست با نام معنادار بسازید، نه یک نشست بینام که همهچیز داخلش تلنبار شود.
کلید prefix
tmux باید بفهمد کدام کلیدها مال اوست و کدام مال برنامهی داخل ترمینال. برای همین همهی میانبرها با یک کلید پیشوند (prefix) شروع میشوند که پیشفرض آن Ctrl+b است. روش زدنش این است: Ctrl و b را با هم بزنید، رها کنید، بعد کلید فرمان را بزنید. مثلاً Ctrl+b سپس c یعنی «پنجرهی جدید».
در این مقاله prefix یعنی همان Ctrl+b (یا هر چیزی که بعداً جایش بگذارید).
جداشدن و برگشتن (detach و attach)
مهمترین چرخهی کار با tmux همین است:
# ساختن نشست با نام
tmux new -s deploy
# ... کار میکنید، مثلاً یک دستور طولانی اجرا میکنید
# با prefix سپس d از نشست جدا میشوید؛ دستور همچنان اجرا میشود
# فهرست نشستها
tmux ls
# برگشتن به نشست
tmux attach -t deploy
# اگر فقط یک نشست دارید، کوتاهترش:
tmux a
اگر اتصال SSH ناخواسته قطع شود، دقیقاً همان اتفاقی میافتد که با prefix d میافتاد: نشست در پسزمینه میماند. دوباره وارد سرور شوید و tmux attach بزنید.
یک ترفند کاربردی: دستور زیر اگر نشستی به نام main باشد به آن وصل میشود و اگر نباشد آن را میسازد. میتوانید آن را عادت کنید که همیشه بعد از ورود بزنید:
tmux new -A -s main
برای بستن یک نشست از بیرون:
tmux kill-session -t deploy
از داخل نشست هم کافی است در آخرین پنل exit بزنید؛ با بستهشدن آخرین پنل، نشست هم بسته میشود.
دو نفر روی یک نشست
اگر دو نفر با یک کاربر روی سرور باشند و هر دو tmux attach -t deploy بزنند، هر دو یک صفحه را میبینند و میتوانند تایپ کنند. برای نشاندادن یک مشکل به همکار یا کار جفتی روی سرور، از اشتراک صفحه سادهتر است.
کار با پنجرهها و پنلها
پنجرهها
prefix cپنجرهی جدید میسازد.prefix nوprefix pبه پنجرهی بعدی و قبلی میروند.prefix 0تاprefix 9مستقیم به پنجرهی آن شماره میروند.prefix ,نام پنجره را عوض میکند. نامگذاری (مثلاًlogs،shell،db) پیدا کردن را خیلی راحتتر میکند.prefix wفهرست همهی پنجرهها و نشستها را برای انتخاب نشان میدهد.
پنلها
prefix %پنجره را عمودی تقسیم میکند (دو پنل کنار هم).prefix "افقی تقسیم میکند (دو پنل بالا و پایین).prefixو یکی از کلیدهای جهتنما، بین پنلها جابهجا میشود.prefix zپنل فعلی را تمامصفحه میکند و دوباره زدنش آن را برمیگرداند.prefix xپنل فعلی را (بعد از تأیید) میبندد.
اسکرول و کپی
در tmux چرخ ماوس بهصورت پیشفرض تاریخچهی خروجی را اسکرول نمیکند. برای دیدن خروجیهای قبلی prefix [ را بزنید تا وارد حالت کپی (copy mode) شوید؛ با کلیدهای جهتنما یا PgUp/PgDn بالا و پایین بروید و با q خارج شوید. با فعالکردن ماوس در بخش بعد، اسکرول با چرخ هم کار میکند.
یک فایل ~/.tmux.conf کوچک
تنظیمات پیشفرض tmux قابلاستفاده است، ولی چند تغییر کوچک کار را راحتتر میکند. این فایل را روی سرور بسازید:
# prefix را Ctrl+a کن که با یک دست راحتتر است
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# ماوس: انتخاب پنل، تغییر اندازه و اسکرول با چرخ
set -g mouse on
# شمارهگذاری پنجرهها و پنلها از ۱، که روی کیبورد کنار هماند
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
# تاریخچهی بیشتر برای اسکرول
set -g history-limit 50000
# تقسیم پنل با کلیدهای بهیادماندنی، در همان پوشهی فعلی
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# بارگذاری دوبارهی همین فایل با prefix r
bind r source-file ~/.tmux.conf \; display-message "tmux.conf reloaded"
نشستهایی که از قبل باز هستند تنظیمات جدید را خودکار نمیخوانند. یک بار از داخل tmux این را بزنید (بعد از آن prefix r کافی است):
tmux source-file ~/.tmux.conf
چند نکته دربارهی این تنظیمات:
Ctrl+aدر bash میانبر «رفتن به ابتدای خط» است. خطbind C-a send-prefixباعث میشود با دو بار زدنCtrl+aهمان کار انجام شود. اگر به این میانبر عادت دارید، prefix را همانCtrl+bنگه دارید.- با
mouse on، انتخاب متن با ماوس را tmux در اختیار میگیرد. برای انتخاب و کپی با ترمینال خودتان، کلیدShiftرا هنگام کشیدن ماوس نگه دارید (در بیشتر ترمینالها؛ در iTerm2 کلیدOption). - اگر روی چند سرور کار میکنید، این فایل را در یک مخزن dotfiles نگه دارید تا همهجا یکسان باشد.
چند اشتباه رایج
- tmux داخل tmux. اگر روی سرور A داخل tmux باشید و از آنجا به سرور B بروید و آنجا هم tmux باز کنید، prefix به tmux بیرونی میرسد. یا روی سرور میانی tmux نزنید، یا برای tmux درونی prefix را دو بار بفرستید.
- فراموشکردن نشستهای قدیمی. هر نشست بازی که دستوری در آن در حال اجراست حافظه مصرف میکند. گاهی
tmux lsبزنید و نشستهای بیاستفاده را ببندید. - انتظار ماندن بعد از ریاستارت. tmux نشستها را در حافظه نگه میدارد، نه روی دیسک. ریاستارت سرور همه را میبندد.
- اجرای سرویس دائمی در tmux. اگر سرور ریاستارت شود یا پروسس بمیرد، کسی آن را دوباره بالا نمیآورد. این کار systemd است.
جدول خلاصه (tmux cheat sheet)
| کار | دستور یا کلید |
|---|---|
| نشست جدید با نام | tmux new -s name |
| وصل شدن یا ساختن | tmux new -A -s name |
| فهرست نشستها | tmux ls |
| برگشتن به نشست | tmux attach -t name یا tmux a |
| بستن نشست از بیرون | tmux kill-session -t name |
| جداشدن از نشست | prefix d |
| انتخاب نشست از فهرست | prefix s |
| تغییر نام نشست | prefix $ |
| پنجرهی جدید | prefix c |
| پنجرهی بعدی / قبلی | prefix n / prefix p |
| رفتن به پنجرهی شمارهی N | prefix N |
| تغییر نام پنجره | prefix , |
| تقسیم عمودی (کنار هم) | prefix % |
| تقسیم افقی (بالا و پایین) | prefix " |
| جابهجایی بین پنلها | prefix + کلید جهتنما |
| تمامصفحه کردن پنل | prefix z |
| بستن پنل | prefix x |
| حالت کپی و اسکرول | prefix [ (خروج با q) |
| فهرست همهی کلیدها | prefix ? |
جمعبندی
tmux یکی از آن ابزارهایی است که بعد از یک بار از دست دادن کار نیمهتمام، دیگر بدون آن وارد سرور نمیشوید. حداقلش را یاد بگیرید: tmux new -A -s main بعد از ورود، prefix d برای جداشدن و tmux a برای برگشتن. پنجره و پنل و فایل تنظیمات را کمکم اضافه کنید. کارهای دائمی را به systemd بسپارید و tmux را برای کار دستی خودتان نگه دارید. اگر دنبال دستورهای روزمرهی دیگر هستید، دستورهای پرکاربرد لینوکس برای مدیریت سرور را ببینید.