پرش به محتوای اصلی
پرش به محتوای مقاله

«محدودیت پنهان TTY»؛ عاملی برای شکست پرامپت‌های طولانی در محیط مک

·۲۳ مهر ۱۴۰۵۸ دقیقه مطالعه
چسباندن ۲۰۰۰ کاراکتر در خط فرمان مک‌اواس، ۱۰۲۴ کاراکتر نگه می‌دارد: مقصر TTY است
چسباندن ۲۰۰۰ کاراکتر در خط فرمان مک‌اواس، ۱۰۲۴ کاراکتر نگه می‌دارد: مقصر TTY است
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

شناسایی دقیق علت شکست دستورات طولانی در macOS که نه در لایه اپلیکیشن، بلکه در ثابت‌های سخت‌افزاری هسته (MAX_CANON) ریشه دارد.

تصور کنید یک برنامه‌نویس هستید که یک گزارش خطای حجیم (Stack Trace) یا یک لینک پیچیده و طولانی را در ترمینال مک خود جای‌گذاری می‌کند، اما دستور بدون هیچ پیامی قطع شده و اجرا نمی‌شود. شما با یک باگ در اپلیکیشن ترمینال نمی‌جنگید، بلکه با محدودیت سخت‌گیرانهٔ «نظم خط» (Line Discipline) در هستهٔ سیستم‌عامل درگیر هستید. در واقع، یک دیوار ۱,۰۲۴ بایتی در هسته macOS به‌طور بی‌صدا در حال کشتن دستورات طولانی ترمینال و مختل کردن جریان‌های کاری عامل‌های هوش مصنوعی است.

این موضوع در ژوئیه ۲۰۲۶ برملا شد؛ زمانی که کاربران گزارش دادند جلسات Claude Code هرگاه دستور اجرا بیش از ۱,۰۲۴ بایت باشد، بدون هشدار شکست می‌خورد. طبق گزارش کاربران، دستور در خط فرمان باقی می‌ماند اما چون کاراکتر «خط جدید» (Newline) در انتهای آن حذف شده است، هیچ اتفاقی نمی‌افتد و کاربر با چیزی جز صدای زنگ ترمینال (Terminal Bell) مواجه نمی‌شود.

برای درک این اتفاق باید به لایه‌ای بین اپلیکیشن ترمینال و برنامه نگاه کنیم: پسیودو-ترمینال (pty). اکثر توسعه‌دهندگان تصور می‌کنند اپلیکیشن ترمینال متن را مستقیماً به برنامه ارسال می‌کند، اما در واقع داده‌ها از دستگاهی در هسته به نام نظم خط عبور می‌کنند. این لایه به‌صورت پیش‌فرض در «حالت استاندارد» (Canonical Mode) عمل می‌کند؛ به این معنا که هسته ورودی‌ها را بافر کرده و تنها زمانی آن‌ها را به برنامه تحویل می‌دهد که شما دکمهٔ Enter را فشار دهید.

سقف ۱,۰۲۴ بایتی

در macOS این بافر محدودیت شدیدی دارد. بر اساس مستندات فایل bsd/sys/syslimits.h در هستهٔ XNU، ثابت‌های MAX_CANON و MAX_INPUT هر دو روی ۱,۰۲۴ بایت تنظیم شده‌اند. به محض اینکه ورودی شما به این حد برسد، هستهٔ سیستم‌عامل به‌سادگی هر کاراکتر جدیدی را دور می‌اندازد.

این وضعیت یک الگوی شکست خاص ایجاد می‌کند:

  • کلیدهای سیگنال مثل Ctrl-C و Backspace همچنان کار می‌کنند چون قبل از بررسی سرریز (Overflow Check) پردازش می‌شوند.
  • کلید Enter و Ctrl-D بعد از این بررسی پردازش می‌شوند؛ بنابراین اگر بافر پر باشد، این کلیدها حذف می‌شوند.
  • چون کلید Enter هرگز به مقصد نمی‌رسد، برنامه هرگز دستور اجرا را دریافت نمی‌کند.

تایپ ۲۰۰۰ کاراکتر در خط فرمان مک‌او‌اس، فقط ۱۰۲۴ تا را نگه می‌دارد؛ مقصر TTY است.

این مسئله یک باگ در Terminal.app یا iTerm2 نیست، بلکه یک انتخاب طراحی بنیادین در هستهٔ macOS است. به نقل از یک مهندس Apple DTS در تالارهای گفتگو در سال ۲۰۲۴، این محدودیت از نحوهٔ مدیریت ورودی/خروجی (I/O) در TTY نشأت می‌گیرد و ربطی به لایه اپلیکیشن ندارد.

همان‌طور که در تحلیل‌های قبلی ما دربارهٔ زیرساخت‌های ابری و محیط‌های توسعه اشاره کردیم، تفاوت‌های ریز در سطح هسته می‌تواند منجر به شکست‌های بزرگ در مقیاس عملیاتی شود.

تفاوت macOS و لینوکس

لینوکس این موضوع را متفاوت مدیریت می‌کند و سقف بسیار بالاتری ارائه می‌دهد. طبق مستندات termios(3) در لینوکس، حداکثر طول خط ۴,۰۹۶ کاراکتر است. در حالی که لینوکس نیز داده‌ها را بعد از ۴,۰۹۵ کاراکتر دور می‌اندازد، اما نکتهٔ حیاتی این است که کاراکتر پایانی (Newline) را حفظ می‌کند.

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

مشکل انجماد ترمینال

علاوه بر قطع شدن متن، حالت شکست دومی وجود دارد: انجماد ترمینال. این اتفاق زمانی می‌افتد که هزاران خط متن را در برنامه‌ای جای‌گذاری می‌کنید که بیش از حد مشغول است تا آن‌ها را بخواند — مثلاً پردازشی که در یک کامپایل طولانی گیر کرده یا در حالت خواب (Sleep State) قرار دارد.

در لینوکس، این بایت‌ها بافر ۴,۰۹۶ بایتی نظم خط را پر کرده و سپس به بافرهای flip در pty منتقل می‌شوند. وقتی حد حافظه TTYB_DEFAULT_MEM_LIMIT پر شود، عملیات نوشتن (Write Operation) اپلیکیشن ترمینال مسدود (Block) می‌شود. اگر این عملیات روی رشته‌ای (Thread) باشد که برای به‌روزرسانی رابط کاربری (UI) لازم است، کل پنجره هنگام تغییر اندازه یا تقسیم‌بندی منجمد می‌شود.

Hermes IDE در به‌روزرسانی ۱۲ اکتبر ۲۰۲۶ (نسخه v2.2.9) این دسته از باگ‌ها را برطرف کرد. این آپدیت تضمین می‌کند که جای‌گذاری مقادیر حجیم متن در یک ترمینال غیرپاسخ، دیگر باعث انجماد توابع مدیریت پنجره در IDE نشود.

عامل‌های AI چگونه این سد را دور می‌زنند

رابط‌های خط فرمان (CLI) مدرن و عامل‌های هوش مصنوعی (AI Agents) برای اجتناب از این تله‌ها به «حالت خام» (Raw Mode) تغییر وضعیت می‌دهند. برای مثال در Node.js با فراخوانی setRawMode(true)، برنامه پردازش‌های خاص و اسمبل کردن خطوط در هسته را غیرفعال می‌کند. این کار به عامل اجازه می‌دهد بایت‌ها را تک‌تک و به‌محض رسیدن بخواند و به‌طور کامل از بافر ۱,۰۲۴ بایتی هسته عبور کند. این بهینه‌سازی در لایه ارتباطی برای کاهش خطاهای عملیاتی حیاتی است، چرا که هزینه‌های بالای توکن‌ها در فراخوانی‌های API باعث می‌شود هر اجرای شکست‌خورده یا تکراری در عامل‌های کدنویس، فشار مالی قابل‌توجهی وارد کند.

با این حال، حالت خام مشکل جدید ایجاد می‌کند: متن‌های جای‌گذاری شده (Paste) مانند تایپ بسیار سریع کاربر تلقی می‌شوند. برای حل این مشکل، عامل‌ها از «حالت جای‌گذاری براکتی» (Bracketed Paste Mode) استفاده می‌کنند. برنامه یک توالی کنترلی خاص (ESC [ ? 2004 h) ارسال می‌کند و ترمینال متن‌های جای‌گذاری شده را بین دو نشانگر (ESC [ 200 ~ و ESC [ 201 ~) قرار می‌دهد. این سازوکار به عامل اجازه می‌دهد تفاوت بین تایپ دستی کاربر و جای‌گذاری یک فایل لاگ ۱۰,۰۰۰ خطی را تشخیص دهد.

گام بعدی شما

اگر در اسکریپت‌های خود یا جریان‌های کاری با این محدودیت‌ها مواجه شدید، سه راهکار اصلی وجود دارد:

۱. اجتناب از حالت استاندارد: از دستور stty -icanon برای غیرفعال کردن اسمبل خطوط برای یک دستور خاص استفاده کنید تا برنامه بتواند بایت‌ها را فوراً بخواند.
۲. استفاده از لوله‌ها یا فایل‌ها: به‌جای Paste کردن، از pbpaste | ./tool یا ./tool < trace.txt استفاده کنید. لوله‌ها (Pipes) و فایل‌ها به‌طور کامل نظم خط TTY را دور می‌زنند. این رویکرد مشابه استفاده از متد Idempotency برای حذف تکرار داده‌ها در خط لوله‌های داده است تا از پردازش‌های تکراری و خطاها جلوگیری شود.
۳. پیاده‌سازی Bracketed Paste: اگر در حال ساخت یک CLI هستید، از ویرایشگرهای خطی استفاده کنید که از حالت غیر-استاندارد پشتیبانی می‌کنند و Bracketed Paste را برای مدیریت ایمن ورودی‌های حجیم فعال کنید.

برای کسانی که میزبان‌های ترمینال (Terminal Hosts) می‌سازند، درس این است: با عملیات نوشتن در PTY به‌گونه‌ای برخورد کنید که انگار ممکن است برای همیشه مسدود شوند. هرگز اجازه ندهید یک عملیات نوشتن در PTY، قفل (Lock) را در اختیار بگیرد که بقیه اپلیکیشن برای پاسخگو ماندن به آن نیاز دارد.

اما داستان سخت‌افزاری این تحول حتی شگفت‌انگیزتر است — به تحلیل ما درباره‌ی تراشه‌های Blackwell مراجعه کنید.

چرا این موضوع مهم است؟

این یافته بر اساس تحلیل معماری هسته XNU نشان می‌دهد که توسعه‌دهندگان عامل‌های AI نمی‌توانند به رفتارهای پیش‌فرض ترمینال اعتماد کنند. عدم آگاهی از این محدودیت منجر به شکست‌های خاموش (Silent Failures) در اتوماسیون‌های پیچیده می‌شود که عیب‌یابی آن‌ها بسیار دشوار است.

تأثیر برای ایران

این موضوع برای توسعه‌دهندگان ایرانی که از macOS برای ساخت ابزارهای CLI یا کار با عامل‌های AI استفاده می‌کنند اهمیت فنی دارد و راهکار دور زدن آن از طریق stty در دسترس است.

·نگاه ما
تحریریه دات‌هوش

این محدودیت نشان می‌دهد که حتی پیشرفته‌ترین ابزارهای توسعهٔ امروز بر روی لایه‌هایی از کد بنا شده‌اند که متعلق به دوران ترمینال‌های قدیمی است. تکیه بر حالت Raw Mode برای عامل‌های AI، در واقع یک دور زدنِ مهندسی برای جبران نقص‌های معماری سیستم‌عامل است که می‌تواند در آینده منجر به ناسازگاری‌های پیش‌بینی‌نشده در محیط‌های مختلف شود.

منابع

این گزارش با خط‌لولهٔ خودکار دات‌هوش از منابع معتبر جهانی تدوین و زیر نظر تحریریه منتشر شده است. روش کار ما

گفتگو

پنج‌شنبه‌های هوش‌محور

بسته‌ی هفتگی دات‌هوش

۵ خبر، ۲ ابزار، ۱ پرامپت در هر شماره. به‌زودی راه‌اندازی می‌شود — هر پنج‌شنبه صبح.

خبر کلیدی
ابزار کاربردی
پرامپت حرفه‌ای
تحلیل پژوهش
به‌زودی
زاویه‌ی ایرانی
به‌زودی
تمرین این هفته
به‌زودی

راهنماهای دات‌هوش

راهنماهای کاربردیِ دات‌هوش برای کار با هوش مصنوعی — از همین‌جا شروع کنید:

دات‌هوش

راهنمای فارسی هوش مصنوعی — با نگاه به ایران

اخبار روزانه، معرفی ابزارها و مدل‌ها، و آموزشِ کار با هوش مصنوعی؛ همیشه با این پرسش که از ایران چه چیزی کار می‌کند و چه چیزی نه.