آموزش سرور

آموزش tmux و screen؛ اجرای دستورهای طولانی روی سرور بدون ترس از قطع SSH

تهیه: کلودیفای (نگارش با کمک هوش مصنوعی) · انتشار: · زمان مطالعه: ۷ دقیقه

root@server: ~$ tmux new -s upgrade[detached (from session upgrade)]$ tmux lsupgrade: 1 windows (created ...)$ tmux attach -t upgradetmuxscreenSSHآموزش سرورآموزش tmux و screen؛اجرای دستورهای طولانی رویسرور بدون ترس از قطع SSHمجلهٔ کلودیفایclodify.net/blog
پاسخ کوتاه

وقتی اتصال SSH قطع می‌شود، دستورهایی که در آن اجرا کرده‌اید هم متوقف می‌شوند. tmux و screen نشست ترمینال را روی خود سرور نگه می‌دارند: با tmux new -s name نشست بسازید، کار طولانی را اجرا کنید، با Ctrl+b سپس d جدا شوید و بعداً با tmux attach -t name برگردید. برای کارهای موقت مثل انتقال فایل، ارتقای سیستم یا کامپایل عالی‌اند؛ اما برنامه‌هایی که باید همیشه اجرا شوند را با systemd اجرا کنید.

مشکل: قطع SSH یعنی توقف کار

فرض کنید در حال ارتقای سیستم‌عامل سرور، بازیابی یک دیتابیس بزرگ یا انتقال چند ده گیگابایت فایل هستید. وسط کار، اینترنت شما لحظه‌ای قطع می‌شود یا لپ‌تاپ به حالت خواب می‌رود. اتصال SSH می‌افتد و سیستم‌عامل به همهٔ فرایندهایی که از آن نشست اجرا شده بودند سیگنال قطع (SIGHUP) می‌فرستد؛ نتیجه، توقف کار در نیمهٔ راه است. در بدترین حالت، مثل وسط ارتقای بسته‌ها، این توقف می‌تواند سیستم را در وضعیت ناقص رها کند.

راه‌حل، «مالتی‌پلکسر ترمینال» است: برنامه‌ای که نشست ترمینال را روی خود سرور اجرا و نگهداری می‌کند. شما فقط به آن نشست وصل می‌شوید و اگر اتصالتان قطع شود، نشست و همهٔ برنامه‌های داخلش روی سرور به کار ادامه می‌دهند. دو ابزار معروف این دسته tmux و screen هستند. tmux جدیدتر و پرامکانات‌تر است و screen قدیمی‌تر و روی بسیاری از سیستم‌ها از قبل نصب است.

نشست tmux روی سرور زنده می‌ماند
attach / detachادامهٔ اجرالپ‌تاپ شمااتصال SSHنشست tmuxروی خود سرورکار طولانیارتقا، rsync، dumpattach / detachادامهٔ اجرالپ‌تاپ شمااتصال SSHنشست tmuxروی خود سرورکار طولانیارتقا، rsync، dump
شکل ۱ اگر SSH قطع شود، نشست tmux و برنامه‌های داخلش روی سرور ادامه می‌دهند و با attach به همان نقطه برمی‌گردید.

نصب

sudo apt install -y tmux screen       # اوبونتو و دبیان
sudo dnf install -y tmux screen       # AlmaLinux و Rocky

شروع سریع با tmux

یک نشست با نام دلخواه بسازید و کارتان را داخل آن اجرا کنید:

tmux new -s upgrade
# داخل نشست:
sudo apt update && sudo apt full-upgrade

حالا برای جدا شدن (Detach) از نشست بدون متوقف کردن آن، کلید ترکیبی پیشوند tmux یعنی Ctrl+b را بزنید، رها کنید و سپس d را بزنید. به ترمینال عادی برمی‌گردید، در حالی که کار در پس‌زمینه ادامه دارد. می‌توانید حتی SSH را ببندید.

برای برگشتن:

tmux ls                    # فهرست نشست‌ها
tmux attach -t upgrade     # اتصال دوباره

اگر اتصال SSH ناخواسته قطع شود، همین دستور attach شما را دقیقاً به همان نقطه برمی‌گرداند و خروجی‌ها را هم می‌بینید.

کلیدهای پرکاربرد tmux

همهٔ کلیدها با پیشوند Ctrl+b شروع می‌شوند (ابتدا پیشوند را بزنید و رها کنید، سپس کلید بعدی):

کلید کار
d جدا شدن از نشست
c ساخت پنجرهٔ جدید
n و p پنجرهٔ بعدی و قبلی
0 تا 9 رفتن به پنجرهٔ شماره‌دار
% تقسیم عمودی صفحه به دو پنل
" تقسیم افقی صفحه
کلیدهای جهت جابه‌جایی بین پنل‌ها
[ حالت اسکرول؛ با q خارج شوید
x بستن پنل فعلی
, تغییر نام پنجره

پنل‌ها برای پایش هم‌زمان بسیار کاربردی‌اند؛ مثلاً در یک پنل برنامه را اجرا کنید، در پنل دیگر لاگ را با tail -f ببینید و در سومی htop را باز نگه دارید.

root@server: ~
$ tmux new -s upgrade[detached (from session upgrade)]$ tmux lsupgrade: 1 windows (created ...)$ tmux attach -t upgrade$ 
شکل ۲ ساخت نشست، جدا شدن با Ctrl+b و d، دیدن فهرست و اتصال دوباره.

screen در چند دستور

اگر روی سروری هستید که tmux ندارد یا به screen عادت دارید، معادل‌ها این‌هاست. پیشوند screen کلید Ctrl+a است:

screen -S upgrade          # ساخت نشست با نام
# جدا شدن: Ctrl+a سپس d
screen -ls                 # فهرست نشست‌ها
screen -r upgrade          # اتصال دوباره
screen -d -r upgrade       # جدا کردن از جای دیگر و اتصال اینجا

اگر پیام «There is a screen on: ... (Attached)» دیدید، یعنی نشست هنوز به اتصال قبلی (احتمالاً قطع‌شده) وصل است؛ گزینهٔ -d -r آن را جدا و به شما وصل می‌کند. در tmux معادل آن tmux attach -d -t name است.

سفارشی‌سازی کوچک tmux

با یک فایل ~/.tmux.conf می‌توانید کار با tmux را راحت‌تر کنید. چند تنظیم رایج:

set -g mouse on              # اسکرول و انتخاب پنل با ماوس
set -g history-limit 50000   # تاریخچهٔ طولانی‌تر خروجی
set -g base-index 1          # شماره‌گذاری پنجره‌ها از ۱

پس از ذخیره، داخل tmux با Ctrl+b و سپس : و تایپ source-file ~/.tmux.conf تنظیمات را بارگذاری کنید.

کاربردهای واقعی روی سرور

  • ارتقای سیستم‌عامل یا بسته‌ها: همیشه داخل tmux انجام دهید تا قطع اتصال نیمه‌کاره‌اش نگذارد.
  • انتقال حجم زیاد داده: rsync یا scp طولانی را در tmux اجرا کنید؛ روش‌های انتقال را در آموزش SCP، SFTP و rsync ببینید.
  • بازیابی یا خروجی گرفتن از دیتابیس بزرگ که ساعت‌ها طول می‌کشد.
  • کامپایل یا ساخت ایمیج داکر روی سرورهای کم‌توان.
  • کار هم‌زمان چند نفر: دو نفر می‌توانند به یک نشست tmux وصل شوند و صفحهٔ یکسانی را ببینند؛ برای آموزش یا عیب‌یابی گروهی مفید است.

اجرای دستور در نشست جدا، بدون ورود به آن

گاهی می‌خواهید کاری را از درون یک اسکریپت یا با یک دستور کوتاه در پس‌زمینه شروع کنید، بدون اینکه وارد نشست شوید. tmux این امکان را دارد: با tmux new -d -s backup 'rsync -a /data/ root@203.0.113.20:/data/' یک نشست جدا ساخته می‌شود که همان دستور را اجرا می‌کند. هر وقت خواستید با attach وضعیتش را ببینید. همچنین با tmux send-keys -t backup 'ls -l' Enter می‌توانید به نشستی که از قبل وجود دارد دستور بفرستید.

یک نکتهٔ مهم: وقتی دستور تمام شود، نشستی که فقط برای آن ساخته شده هم بسته می‌شود و خروجی را از دست می‌دهید. اگر می‌خواهید نتیجه بماند، خروجی را به فایل هدایت کنید (مثلاً با tee به یک فایل لاگ) یا به‌جای دستور مستقیم، یک شل باز کنید و دستور را داخل آن اجرا کنید.

برای ثبت کامل هر آنچه در یک پنل نمایش داده می‌شود، tmux دستور pipe-pane دارد که خروجی پنل را هم‌زمان در فایل می‌نویسد؛ برای مستندسازی یک عملیات حساس، مثل مهاجرت سرور، مفید است تا بعداً بتوانید دقیقاً ببینید چه دستوری با چه نتیجه‌ای اجرا شده است.

tmux جایگزین systemd نیست

اشتباه رایجی که زیاد دیده می‌شود، اجرای دائمی ربات تلگرام، API یا سرویس وب داخل tmux یا screen است. این روش در ظاهر کار می‌کند، اما سه ضعف جدی دارد: اگر برنامه به خطا بخورد و متوقف شود، کسی آن را دوباره اجرا نمی‌کند؛ پس از ری‌استارت سرور نشست tmux از بین رفته و برنامه دیگر اجرا نمی‌شود؛ و لاگ‌ها فقط در بافر ترمینال هستند و با بسته شدن نشست گم می‌شوند.

قاعدهٔ ساده: کار موقت در tmux، سرویس دائمی در systemd. روش ساخت سرویس را در ساخت سرویس systemd و نمونهٔ ربات را در اجرای دائمی ربات تلگرام با systemd ببینید.

tmux یا systemd؟
tmux / screen
  • کارهای موقت و تعاملی
  • دیدن خروجی زنده و دادن ورودی
  • با ری‌استارت سرور از بین می‌رود
  • بدون اجرای دوبارهٔ خودکار
در برابر
systemd
  • سرویس‌های دائمی
  • اجرای خودکار پس از بوت
  • Restart پس از خطا
  • لاگ ماندگار در journalctl
شکل ۳ کار موقت در tmux و سرویس دائمی در systemd.

tmux، nohup یا &؟

برای اجرای یک دستور در پس‌زمینه گزینه‌های ساده‌تری هم هست. علامت & در انتهای دستور آن را در پس‌زمینه اجرا می‌کند، اما با بسته شدن SSH همچنان ممکن است متوقف شود. nohup command & سیگنال قطع را نادیده می‌گیرد و خروجی را در فایل nohup.out می‌نویسد؛ برای یک دستور ساده که نیازی به تعامل ندارد کافی است. اما اگر بخواهید بعداً خروجی زنده را ببینید، به برنامه ورودی بدهید یا چند کار را هم‌زمان مدیریت کنید، tmux بسیار راحت‌تر است.

نکته‌های پایانی

  • نشست‌هایی که دیگر لازم نیستند را ببندید (exit داخل نشست یا tmux kill-session -t name)؛ نشست‌های فراموش‌شده منابع کمی مصرف می‌کنند اما ممکن است برنامه‌های قدیمی را زنده نگه دارند.
  • نام معنادار برای نشست‌ها بگذارید تا بعداً بدانید هرکدام برای چه بوده است.
  • اگر اتصال SSH شما زیاد قطع می‌شود، علاوه بر tmux، علت را هم بررسی کنید؛ آموزش اتصال به سرور با SSH گزینه‌های KeepAlive را توضیح می‌دهد.

با این ابزار ساده، دیگر هیچ کار طولانی‌ای به کیفیت اینترنت شما وابسته نیست. اگر برای تمرین به سرور نیاز دارید، یک سرور ساعتی بسازید و پس از پایان کار حذفش کنید.

سؤالات متداول

tmux بهتر است یا screen؟

هر دو کار اصلی یعنی نگه داشتن نشست پس از قطع SSH را انجام می‌دهند. tmux امکانات بیشتری برای تقسیم صفحه و پیکربندی دارد و فعال‌تر توسعه می‌یابد؛ screen روی سیستم‌های قدیمی‌تر بیشتر پیدا می‌شود. برای شروع tmux پیشنهاد می‌شود.

اگر سرور ری‌استارت شود، نشست tmux می‌ماند؟

خیر. نشست tmux در حافظهٔ سرور است و با ری‌استارت از بین می‌رود. برای برنامه‌هایی که باید پس از ری‌استارت هم اجرا شوند، سرویس systemd بسازید.

چطور داخل tmux به بالا اسکرول کنم؟

کلید Ctrl+b و سپس [ را بزنید تا وارد حالت اسکرول شوید و با کلیدهای جهت یا Page Up حرکت کنید؛ با q خارج شوید. با فعال کردن set -g mouse on در فایل تنظیمات، اسکرول با ماوس هم ممکن می‌شود.

چطور یک نشست tmux را کاملاً ببندم؟

داخل نشست exit بزنید تا شل بسته شود یا از بیرون دستور tmux kill-session -t نام‌نشست را اجرا کنید. همهٔ برنامه‌های داخل آن نشست هم متوقف می‌شوند.

آماده‌اید؟ سرورتان را بسازید.

از ۱٬۲۰۰ تومان در ساعت · پرداخت ریالی

سرورتان را همین حالا بسازید.

ساعتی بپردازید. هر وقت خواستید حذف کنید.