کاربرد Claude در مدیریت سرور و لینوکس
با 6 کاربرد کلیدی Claude برای مدیران سیستم آشنا شوید. از تحلیل لاگ و نوشتن فایل systemd تا بررسی تنظیمات nginx و Docker Compose. یاد بگیرید چه اطلاعاتی را هرگز نباید در چت کپی کنید.
استفاده از Claude برای مدیران سیستم: اول مشاوره، بعد اجرا
مدل Claude برای مدیران سیستم در نقش یک بازبین بهترین عملکرد را دارد. شما بخشی از یک لاگ، یک فایل پیکربندی، دستوری که نمیشناسید یا یک رشته خطا را برای آن ارسال میکنید و توضیحی دریافت میکنید که میتوانید پیش از اعمال هرگونه تغییر روی سرور، آن را بررسی کنید. پاسخ اشتباه تا زمانی که آن را اجرا نکنید هزینهای برای شما ندارد، بنابراین حفظ مدل در جایگاه مشاور، کل مدل امنیتی این رویکرد است.
هر هفته 6 وظیفه در یک VPS (سرور مجازی) لینوکسی اجارهای پیش میآید. برای هر یک از موارد زیر، یک الگوی پرامپت کارآمد، دستوری که پاسخ را تایید میکند و حالت شکستی که باید انتظار داشته باشید، ارائه شده است. هیچکدام از این موارد نیازی به دسترسی مستقیم مدل به سرور شما ندارند.
ترتیب کار در سرور عملیاتی اهمیت دارد: ابتدا توضیحات را بخوانید، سپس خودتان بررسی را انجام دهید و در نهایت تصمیم بگیرید. خودمختاری مدل در یک VM آزمایشی مشکلی ندارد. اما در سروری که به مشتریان شما سرویس میدهد، بازبینی اولویت دارد، زیرا مدل نمیتواند وضعیت فعلی سرور را که درباره آن حدس میزند، مشاهده کند.
مواردی که هرگز نباید کپی کنید
هر چیزی که در این پرامپت وارد میکنید، از سرور شما خارج میشود. چهار دسته از اطلاعات باید همیشه روی سرور باقی بمانند:
- کلیدهای خصوصی:
~/.ssh/id_ed25519،/etc/ssh/ssh_host_*_keyو هر کلید TLS (امنیت لایه انتقال) در مسیر/etc/letsencrypt/live/. - فایلهای حاوی اعتبارنامه:
.env،~/.aws/credentials،/root/.docker/config.jsonو رمزهای عبور پایگاه داده در هر فایل یا خطی از لاگها. - دادههای حساب کاربری:
/etc/shadowو/etc/gshadow. هیچ پرسش مدیریتی برای پاسخدهی به هش رمز عبور نیاز ندارد. - هر چیزی که متعلق به کاربران شماست: آدرسهای ایمیل، ردیفهای سفارش، لاگهای درخواست که حاوی کوکیهای نشست یا PII (اطلاعات قابل شناسایی شخصی) هستند.
اشتراکگذاری کلیدهای عمومی بلامانع است. کلیدهای خصوصی نباید به اشتراک گذاشته شوند. این دو فایل در نگاه اول شبیه به هم هستند، بنابراین پیش از کپی کردن، خط اول را بخوانید: فایلی که خط اول آن شامل BEGIN OPENSSH PRIVATE KEY است، هرگز نباید در پرامپت قرار گیرد. مطالعه مدیریت صحیح کلیدهای SSH به اندازه 10 دقیقه وقت گذاشتن ارزش دارد.
پیش از کپی کردن، اطلاعات حساس را حذف (Redact) کنید؛ به جای اینکه به خودتان اعتماد کنید که یک توکن را در میان 200 خط پیدا میکنید:
sudo journalctl -u myapp -n 200 --no-pager | sed -E 's/(token|secret|password|api[_-]?key)[=:][^[:space:]]+/\1=REDACTED/gI'یک تلهٔ خاص در Docker وجود دارد. دستور docker compose config مقادیر .env شما را در خروجی چاپ میکند، بنابراین آن خروجی حاوی اطلاعات محرمانه است، حتی اگر فایل روی دیسک اینطور نباشد. از docker compose config -q استفاده کنید که فقط اعتبارسنجی را انجام میدهد و چیزی چاپ نمیکند. برای سیاستهای کلیتر در مورد آنچه یک عامل (Agent) مجاز به دیدن آن است، دور نگه داشتن اسرار از عاملهای هوش مصنوعی جنبههای مربوط به محیط (Environment) را پوشش میدهد.
وظیفه 1: چرا این سرویس با شکست مواجه شد؟
با دو دستوری شروع کنید که پاسخ را در خود دارند:
systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b -n 100 --no-pager -o short-isoهر دو را به همراه متنی که مدل نمیتواند حدس بزند جایگذاری کنید: توزیع و نسخه، آخرین تغییری که اعمال کردید، اینکه آیا قبلاً کار میکرده است، و چه مدت پیش از کار افتاده است. ابتدا درباره مکانیزم بپرسید.
Ubuntu 24.04.myapp.serviceتا زمانی که یک ساعت پیش unit را ویرایش کردم، بهخوبی کار میکرد. در اینجاsystemctl statusو 100 خط آخر journal آمده است. اولین خطای واقعی کدام است و چه معنایی دارد؟ هنوز هیچ اصلاحی انجام نشده است.
عبارت "هنوز هیچ اصلاحی انجام نشده است" در این درخواست نقش مهمی دارد. لاگها اولین خطا را زیر انبوهی از تلاشهای مجدد (retries) که ایجاد کرده است دفن میکنند، بنابراین اگر از مدل بخواهید که مشکل را اصلاح کند، آن مدل آخرین خطی را که دیده است توضیح میدهد. خطی که اهمیت دارد معمولاً بیست خط بالاتر از این نویزها قرار دارد.
نتیجه، خطی مانند Main PID: 1841 (code=exited, status=203/EXEC) است. وضعیت خروج 203/EXEC به این معنی است که هسته سیستمعامل نتوانسته فایلی را که در ExecStart نام برده شده اجرا کند: یا مسیر وجود ندارد، یا فایل وجود دارد اما قابلاجرا (executable) نیست. یک خط #! که مفسری را نام میبرد که نصب نشده است، وضعیت مشابهی ایجاد میکند. تمام این موارد با ls -l و head -1 قابل آزمایش هستند.
حالت شکست: یک علت ساختگی. اگر اطلاعات کمی جایگذاری کنید، مدل شکاف را با چیزی کلی پر میکند، مثلاً "پورت در حال استفاده است". درمان آن، بازگشت به یک پرسش است: "کدام خط در متنی که به شما دادم از این ادعا پشتیبانی میکند؟" علتی که هیچکس نتواند در متن به آن اشاره کند، صرفاً یک حدس است.
وظیفه 2: پیشنویس یک systemd unit یا یک ورودی cron
اطلاعات مورد نیاز برای یک فایل unit را فراهم کنید: دستور دقیق، کاربری که دستور با آن اجرا میشود، دایرکتوری کاری، اینکه آیا باید منتظر شبکه بماند یا خیر، و در صورت خروج با کد غیر صفر چه اتفاقی باید بیفتد. سپس پیش از فعالسازی هر چیزی، خروجی را بررسی کنید.
sudo systemd-analyze verify /etc/systemd/system/myapp.service
sudo systemctl daemon-reload
sudo systemctl start myapp.service
systemctl status myapp.service --no-pagersystemd-analyze verify فایل را دقیقاً به همان شکلی که systemd میخواند، تجزیه میکند؛ بنابراین خطاهایی را که از چشم انسان پنهان میماند، شناسایی میکند. یک دستورالعمل با غلط املایی، /etc/systemd/system/myapp.service:7: Unknown key name 'Enviroment' in section 'Service', ignoring. را چاپ میکند. یک فایل اجرایی گمشده، Command /usr/local/bin/myapp is not executable: No such file or directory را چاپ میکند. هر دو در حین daemon-reload ساکت میمانند، به همین دلیل است که یک unit ممکن است بدون خطا بارگذاری شود اما در لحظه اجرا شکست بخورد.
دو اشتباه در پیشنویسنویسی بارها و بارها تکرار میشوند. اولی After=network.target است که فقط به این معنی است که پشته شبکه پیکربندی شده، نه اینکه لزوماً آدرسی وجود داشته باشد. سرویسی که به یک IP خاص متصل میشود، در زمان بوت با bind: Cannot assign requested address شکست میخورد و راهحل آن استفاده از Wants=network-online.target به همراه After=network-online.target است. دومی استفاده از Type=simple برای برنامهای است که خود را به daemon تبدیل میکند: systemd اولین پردازش را به عنوان سرویس در نظر میگیرد، پردازش والد بلافاصله خارج میشود و unit به عنوان مرده علامتگذاری میشود، در حالی که پردازش اصلی همچنان بدون مدیریت به کار خود ادامه میدهد.
برای یک زمانبندی، به جای خواندن آن، آن را بررسی کنید:
systemd-analyze calendar 'Mon *-*-* 04:00:00'این دستور فرم استاندارد و زمان بعدی اجرای عبارت را چاپ میکند که به هر بحثی درباره معنای آن پایان میدهد. اگر بین یک timer و یک crontab مردد هستید، سرویسها و تایمرهای systemd روی یک VPS تفاوتهای آنها را پوشش میدهد.
Cron یک تله دارد که هیچ مدلی درباره آن به شما هشدار نمیدهد مگر اینکه خودتان بپرسید. Cron کارها را با یک محیط حداقلی اجرا میکند، بنابراین PATH تقریباً برابر با /usr/bin:/bin است و پروفایل shell شما هرگز خوانده نمیشود. کاری که وقتی آن را در ترمینال خود کپی میکنید کار میکند، در cron با /bin/sh: 1: docker: not found شکست میخورد، زیرا آن فایل اجرایی در /usr/local/bin قرار دارد. در crontabها از مسیرهای مطلق (absolute paths) استفاده کنید.
وظیفه 3: بررسی فایل Nginx یا Compose پیش از عملیاتیسازی
این وظیفه بیشترین بازدهی را دارد. فایل را جایگذاری کنید، هدف آن را شرح دهید و بخواهید خطبهخط توضیح دهد که در واقع چه کاری انجام میدهد.
این vhost بایدexample.comرا از طریق HTTPS ارائه دهد و/apiرا به یک سرویس محلی روی پورت 8080 پروکسی کند. آن را برای من بازخوانی کنید و هر موردی که با این توصیف مطابقت ندارد را نام ببرید.
سپس ابزاری را اجرا کنید که گرامر را میشناسد:
sudo nginx -t
docker compose config -qnginx -t خروجی nginx: configuration file /etc/nginx/nginx.conf test is successful را چاپ میکند، یا نام فایل و خط مربوطه را مانند nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12 مشخص مینماید. docker compose config -q در صورت صحت ساختار فایل چیزی چاپ نمیکند و در صورت بههمریختگی تورفتگی (indentation)، پیام صریحی مانند yaml: line 7: did not find expected key نمایش میدهد.
هیچکدام از این ابزارها قصد و نیت شما را بررسی نمیکنند. پیکربندیای که از nginx -t عبور میکند، همچنان ممکن است به پورت اشتباه پروکسی کند یا روی 0.0.0.0 گوش دهد، در حالی که منظور شما 127.0.0.1 بوده است. این همان شکافی است که مدل در آن جایگاه خود را تثبیت میکند، و البته همانجایی است که شکست میخورد: وقتی از آن خواسته میشود یک دستورالعمل را اصلاح کند، اغلب کل فایل را بازنویسی کرده و دو مورد از دستورالعملهای شما را بیسروصدا حذف میکند. از مدل بخواهید فقط خطوط تغییریافته و دلیل هر تغییر را ارائه دهد، سپس خودتان بهصورت دستی ویرایش کنید.
آنچه را که در واقع در معرض دید قرار دادهاید تأیید کنید:
sudo ss -tulpnبدون sudo شما سوکتهای در حال گوش دادن را میبینید اما فرآیندهایی که مالک آنها هستند را مشاهده نمیکنید. اگر آن خروجی شما را غافلگیر کرد، پورتها چیستند و لینوکس چگونه آنها را bind میکند مطالعه کوتاهتری است.
وظیفه 4: پیش از اجرای هر دستور ناآشنا، آن را تحلیل کنید
دستور را کپی کنید و چهار پرسش زیر را درباره آن مطرح کنید: هر فلگ چه کاری انجام میدهد، دستور چه چیزی را مینویسد، چه چیزی را حذف میکند و اگر آن را دو بار اجرا کنید چه اتفاقی میافتد؟ پرسش آخر، جلوی خسارات بیشتری را نسبت به سایر موارد میگیرد.
به find /var/log -name '*.gz' -mtime +7 -delete توجه کنید. یک پاسخ مناسب به شما میگوید که -mtime +7 بازههای کامل 24 ساعته را محاسبه کرده و کسر باقیمانده را نادیده میگیرد، بنابراین فایلهایی با حداقل هشت روز قدمت را پیدا میکند، نه هفت روز. همچنین به شما میگوید که find عبارت خود را از چپ به راست ارزیابی میکند، بنابراین جابهجا کردن -delete به قبل از -name، باعث حذف همه چیز در مسیر شروع میشود. این نکته دوم در صفحه راهنمای find به عنوان یک هشدار ذکر شده و باعث از دست رفتن /var/log بسیاری از کاربران شده است.
یا به rsync -a --delete /srv/app/ /backup/app/ نگاه کنید. اسلش انتهایی در مبدأ به معنای «محتویات این دایرکتوری» است. اگر آن را حذف کنید، نتیجه /backup/app/app/ خواهد بود. اگر --delete را اضافه کنید، هر فایلی که در مقصد باشد و در مبدأ وجود نداشته باشد حذف میشود؛ این رفتار برای ایجاد یک آینه (mirror) صحیح است، اما اگر مسیر مبدأ اشتباه باشد، یک فاجعه به بار میآورد.
با استفاده از ابزار تأیید کنید، نه با مدل:
rsync -a --delete --dry-run /srv/app/ /backup/app/ | head -20
find /var/log -name '*.gz' -mtime +7دستور find را بدون -delete اجرا کنید تا به جای از دست دادن دادهها، فقط لیستی از آنها را دریافت کنید.
حالت شکست: توهم در فلگها. مدل در مورد ابزارهایی که 30 سال مستندات دارند قابلاعتماد است، اما در مورد رابطهای خط فرمان (CLI) فروشندگان و زیردستورهای جدید ضعیفتر عمل میکند؛ جایی که ممکن است فلگی را پیشنهاد دهد که بسیار منطقی به نظر میرسد اما وجود خارجی ندارد. --help این موضوع را در یک ثانیه مشخص میکند. کوتیشنگذاری (Quoting) نقطه ضعف دیگر است، بنابراین وقتی یک دستور، عبارتی از $(...) را در بر میگیرد، به جای اعتماد به توضیحات، نحوه گسترش جایگزینی دستور پیش از اجرای آن را مطالعه کنید.
وظیفه 5: تبدیل تاریخچه شل به کتابچه راهنمای عملیاتی (Runbook)
شما بهتازگی دو ساعت وقت صرف کردهاید تا چیزی را به کار بیندازید. این دانش در اسکرولبک (scrollback) ترمینال شما باقی مانده و ماه آینده از بین خواهد رفت.
history 200 > /tmp/session.txtآن فایل را بخوانید و پیش از انتقال به هر جای دیگر، تمام خطوطی که حاوی رمز عبور، توکن یا شناسه مشتری هستند را حذف کنید. تاریخچه شل یکی از مطمئنترین مکانها برای یافتن اسرار در یک سیستم لینوکسی است، زیرا هر کسی حداقل یک بار رمز عبور را بهصورت مستقیم در خط فرمان تایپ میکند. متغیر HISTCONTROL=ignorespace را در فایل ~/.bashrc خود تنظیم کنید تا دستوری که با یک فاصله (space) شروع میشود، هرگز در تاریخچه ثبت نشود.
پرامپتی که یک کتابچه راهنمای عملیاتی کاربردی تولید میکند، علاوه بر مراحل، باید شامل بررسیها (checks) نیز باشد:
این یک نشست شل است که یک سرور خام Debian 13 را به یک نصب فعال Postgres رسانده است. آن را در قالب یک کتابچه راهنمای شمارهگذاریشده بنویس. هر مرحله شامل یک دستور باشد. پس از هر مرحله، دستوری که صحت عملکرد آن را اثبات میکند ارائه بده و خروجی سالم را توصیف کن. هر مرحلهای که به مشخصات خاص میزبان من وابسته بوده است را علامتگذاری کن.
حالت شکست: یک داستان مرتب و تمیز. نشست شما شامل مرحلهای بوده که دو بار قبل از اصلاح، اشتباه انجام شده است؛ مدل این مرحله را حذف میکند چون متن بدون آن تمیزتر به نظر میرسد. کتابچه راهنما را با تاریخچه خود مقایسه کنید و اصلاحات را بازگردانید. مدل همچنین ممکن است دستورات تأییدیه قابلقبولی اختراع کند، بنابراین پیش از ذخیره فایل، هر بررسی که نوشته است را اجرا کنید. اگر کتابچه راهنما مربوط به اولین بوت است، آن را با ده دقیقه اول روی یک VPS جدید مقایسه کنید تا نسخه بدتری از یک مشکل حلشده را ثبت نکنید.
وظیفه 6: تبدیل پیام خطا به یک راهکار
رشته دقیق خطا، دستوری که آن را تولید کرده و تنها تغییری که پیش از ظاهر شدن آن اعمال کردهاید را وارد کنید. از مدل بخواهید دلایل احتمالی را رتبهبندی کند و برای هر کدام یک دستور متمایز ارائه دهد تا پاسخ به چیزی قابل آزمایش تبدیل شود.
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use). دلایل احتمالی را رتبهبندی کنید و برای هر دلیل، یک دستور ارائه دهید که آن را تأیید یا رد کند.
برای این خطا، مکانیزم مبهم نیست: یک پردازش دیگر هماکنون پورت 80 را در اختیار دارد و sudo ss -tulpn | grep ':80 ' نام آن را مشخص میکند. اغلب این مشکل ناشی از یک master process دیگر از Nginx است که پس از یک reload ناموفق باقی مانده، یا Apache است که به عنوان یک وابستگی نصب شده و توسط پکیج خود شروع به کار کرده است.
حالت شکست: راهکاری که با پنهان کردن علت اصلی کار میکند. chmod 777، --privileged، غیرفعال کردن SELinux و اجرای سرویس با دسترسی root همگی باعث ناپدید شدن خطا میشوند. هر راهکاری که دسترسیها را بدون توضیح مدل درباره علت شکست دسترسی محدود، افزایش میدهد رد کنید. آن توضیح، پاسخ واقعی است. یک workaround فقط خطا را ساکت میکند.
مواردی که با اطمینان اشتباه تشخیص میدهد
- این مدل نمیتواند سرور شما را ببیند. هر پاسخ تابعی از متنی است که شما جایگذاری کردهاید و به شما اطلاع نمیدهد که قطعهکد ارسالی بیش از حد کوتاه بوده است.
- در مورد نسخهها دچار انحراف میشود. نام بستهها و فلگهای پیشفرض بین توزیعها و نسخههای مختلف تغییر میکنند و مدل میانگینی از تمام آنها را ارائه میدهد.
- هنگام اشتباهکردن نیز بسیار مسلط صحبت میکند. یک مکانیزم توهمی دقیقاً مانند یک مکانیزم صحیح خوانده میشود؛ به همین دلیل است که برای هر علت در بالا، دستوری برای تستکردن آن ارائه شده است.
- در نشستهای طولانی، رشتهٔ کلام را از دست میدهد. حقایقی که در ابتدای یک گفتگوی دو ساعته مطرح شدهاند، دیگر در پاسخهای انتهایی تأثیری ندارند.
مورد آخر بیشتر یک مشکل کاری است تا یک مشکل مدلی، و مدیریت محتوا در یک نشست طولانی Claude Code راهکار عملی آن است: نشستهای کوتاهتر، هر کدام برای یک وظیفهٔ مشخص.
اجرای عامل روی خود سرور
تمام موارد بالا به صورت کپی و پیست است، بنابراین مدل هرگز به ماشین شما دسترسی مستقیم ندارد. هنگامی که عامل روی سرور اجرا میشود و شروع به خواندن فایلها و اجرای دستورات میکند، ماهیت ریسک تغییر میکند: یک دستور اشتباه اکنون میتواند منجر به از کار افتادن یک سرویس شود. به جای کاربر root، یک کاربر بدون امتیاز (unprivileged) برای آن ایجاد کنید، تا زمانی که با رفتار آن آشنا نشدهاید آن را روی سرور عملیاتی (production) اجرا نکنید و ابتدا یک snapshot تهیه کنید. اجرای ایمن Claude Code روی یک VPS به بررسی محیط ایزوله (sandboxing) و مدل مجوزها میپردازد. اجرای Claude Code درون tmux نیمه دیگر این مشکل را حل میکند، زیرا قطع شدن نشست SSH (secure shell) باعث میشود عامل در میانه کار متوقف شود. حساب کاربری را همانطور بسازید که هر حساب سرویس دیگری را میسازید؛ موضوعی که در کاربران با حداقل امتیاز روی VPS به تفصیل توضیح داده شده است.
FAQ
آیا Claude میتواند لاگهای سرور من را مستقیماً بخواند؟
بهتنهایی خیر. رابط چت فقط متنی را میبیند که شما در آن کپی میکنید. ابزار Claude Code که بهعنوان یک ابزار خط فرمان روی سرور اجرا میشود، میتواند فایلها را بخواند و دستورات را با سطح دسترسی کاربری که آن را اجرا کرده است، اجرا کند؛ که این موضوع مستلزم تصمیمگیری جدیتری در مورد اعتماد به ابزار است. برای پرسشهای پشتیبانی معمولی، کپی کردن یک بخش 100 خطیِ ویرایششده (redacted) سریعتر و امنتر از دادن دسترسی shell به یک عامل (agent) است.
چه مواردی را هرگز نباید از سرور کپی و ارسال کنم؟
کلیدهای خصوصی (private keys)، فایلهای .env و سایر مخازن اعتبارنامه، /etc/shadow، و هرگونه دادهای که متعلق به کاربران شماست. پیش از ارسال بخشهایی از لاگ به پرامپت، توکنها را از متن حذف کنید. یک مورد غیربدیهی: خروجی docker compose config مقادیر .env شما را در خود جای داده است؛ بنابراین از docker compose config -q استفاده کنید که فایل را اعتبارسنجی میکند و هیچ خروجی چاپ نمیکند.
آیا اجازه دادن به Claude برای اجرای دستورات روی یک VPS عملیاتی (production) امن است؟
با آن مانند یک مدیر سیستم جدید که هیچ پیشزمینهای ندارد برخورد کنید: برای خواندن مناسب است، اما برای نوشتن نیاز به بازبینی دارد. در محیط عملیاتی، از او بخواهید توضیح دهد و سپس دستور را خودتان اجرا کنید. اگر میخواهید یک عامل (agent) دستورات را اجرا کند، یک حساب کاربری اختصاصی و بدون امتیاز (unprivileged) بدون دسترسی کامل sudo به آن بدهید و کار را روی یک محیط staging شروع کنید که در آن یک اشتباه، بهجای قطعی سرویس، فقط هزینه بازسازی محیط را به همراه داشته باشد.
چرا Claude فلگی را پیشنهاد میدهد که وجود ندارد؟
زیرا این مدل متنهای محتمل را پیشبینی میکند و یک فلگِ محتمل، مشابه یک فلگ واقعی به نظر میرسد. این اتفاق بیشتر در مورد CLIهای فروشندگان و زیردستورهای جدید رخ میدهد که مستندات پشت مدل برای آنها اندک است یا از آن زمان تغییر کردهاند. --help و man مرجع نهایی هستند و هر دستوری که باعث حذف یا بازنویسی فایلها میشود، ابتدا نیاز به یک اجرای آزمایشی (dry run) دارد.
چگونه پیش از فعالسازی یک unit در systemd، آن را بررسی کنم؟
دستور sudo systemd-analyze verify /etc/systemd/system/myapp.service را اجرا کنید. این دستور فایل را با استفاده از پارسر خودِ systemd تحلیل میکند، دستورالعملهای ناشناخته را همراه با شماره خط گزارش میدهد و اگر یک باینری ExecStart موجود نباشد یا قابل اجرا نباشد، آن را مشخص میکند. سپس daemon-reload و start را اجرا کنید و پیش از اینکه آن را enable کنید، systemctl status را بخوانید؛ زیرا یک unit که بهدرستی بارگذاری میشود، ممکن است در اولین اجرا با شکست مواجه شود.