شِل چیست؟ تفاوت bash و zsh در لینوکس
تعریف Shell، نقش login/interactive، تفاوت bash و zsh، اسکریپتنویسی قابلحمل، و فایلهای rc — با ارجاع GNU Bash manual و مستندات zsh.
بنیانگذار و مهندس محصول

شِل (Shell) برنامهای است که فرمانهای متنی شما را میخواند، آنها را تفسیر میکند، و فرایندها را روی سیستم اجرا میکند. ترمینال کانال ورودی/خروجی است؛ شِل مغز تفسیر است. وقتی مینویسید ls -la | grep conf، این شِل است که pipe را میفهمد، دو فرایند میسازد، و خروجی یکی را به ورودی دیگری وصل میکند — نه خودِ برنامهٔ ls.
روی تقریباً همهٔ سرورهای لینوکس، bash (Bourne Again SHell) شِل پیشفرض رایج برای اسکریپت و کاربر است. zsh (Z Shell) روی دسکتاپ و لپتاپ توسعهدهندهها محبوب شده چون تکمیل فرمان، غلطیابی و سفارشیسازی قویتری دارد. بحث «کدام بهتر است» بدون جدا کردن کار تعاملی از اسکریپت Production گمراهکننده است.
مقالهٔ ۱۴۴ ترمینال را ساخت؛ اینجا شِل را باز میکنیم: انواع نشست، تفاوت bash/zsh، قابلحمل بودن اسکریپت، و فایلهای پیکربندی. جزئیات .bashrc و profile در ۱۷۰ میآید.

پاسخ کوتاه
شِل مفسر خط فرمان و زبان اسکریپت سبک سیستم است. برای اسکریپت روی سرورهای لینوکس، bash (یا گاهی sh سازگار با POSIX) انتخاب امن و قابلپیشبینی است. برای کار تعاملی روزمره روی لپتاپ، zsh با تکمیل بهتر و افزونهها راحتتر است — به شرطی که اسکریپتهای مشترک تیم را به ویژگیهای فقط-zsh وابسته نکنید. یک قانون عملی: تعاملی را شخصیسازی کنید؛ اتوماسیون را قابلحمل نگه دارید.
شِل زیبا روی لپتاپ هیچ سرویسی را نجات نمیدهد اگر اسکریپت استقرار روی سرور با set -e و مسیر درست نوشته نشده باشد.
شِل دقیقاً چه کار میکند؟
- خواندن خط فرمان و شکستن به کلمات (با قواعد نقلقول و escape).
- گسترش متغیر، نام فایل (glob)، و جایگزینی فرمان.
- اعمال pipe، redirection و پسزمینه (&).
- اجرای برنامهٔ خارجی یا تابع/builtin داخلی.
- مدیریت job control در نشست تعاملی (fg، bg، Ctrl+Z).
- اجرای فایل اسکریپت بهعنوان برنامهٔ متنی با shebang.
builtinهایی مثل cd، export و read داخل خودِ شِل پیاده شدهاند. برنامههایی مثل grep فرایند جدا هستند. این تفکیک توضیح میدهد چرا بعضی فرمانها در همهٔ شِلها یکساناند و بعضی فقط در bash یا zsh معنی دارند.
انواع نشست: interactive، login، اسکریپت
نشست تعاملی (interactive) همانی است که prompt میبینید و تایپ میکنید. نشست login معمولاً وقتی رخ میدهد که از طریق ورود سیستم یا بعضی پیکربندیهای SSH شِل بهعنوان login shell شروع شود؛ فایلهای profile متفاوتی خوانده میشوند. اسکریپت غیرتعاملی است: بدون prompt، مناسب CI و cron.
اشتباه رایج: گذاشتن تنظیمات ضروری PATH فقط در فایل مخصوص تعاملی و بعد تعجب از اینکه cron فرمان را پیدا نمیکند. برای اتوماسیون، وابستگی به «همان محیطی که در ترمینال شخصی دارم» خطرناک است. مسیرها را صریح کنید یا محیط را در واحد systemd/CI تعریف کنید.
bash: زبان مشترک سرور
مستندات رسمی GNU Bash آن را شِل سازگار با sh میداند که برای استاندارد POSIX و فراتر از آن گسترش یافته است. روی Ubuntu/Debian، /bin/sh اغلب dash است نه bash — نکتهٔ مهم برای shebang. اگر اسکریپت را با #!/bin/bash شروع کنید، رفتار bash را میخواهید؛ اگر #!/bin/sh بگذارید، باید به ساختارهای POSIX وفادار بمانید یا غافلگیر شوید.
bash
#!/usr/bin/env bash set -euo pipefail echo "hello from $BASH_VERSION"
set -euo pipefail الگوی رایج اسکریپتهای جدی است: خروج روی خطا، خطای متغیر تعریفنشده، و شکست در pipeline. جادو نیست و همهٔ گوشهها را نمیپوشاند، ولی از سکوت خطرناک جلوگیری میکند. قبل از کپی کور، معنی هر گزینه را در man bash بخوانید.
bash در سرورها همهجا هست، در مثالهای اینترنت غالب است، و برای تیمهایی که اسکریپت مشترک مینویسند هزینهٔ هماهنگی را کم میکند. ضعف نسبی در برابر zsh در تجربهٔ تعاملی است: تکمیل و غلطیابی پیشفرض سادهتر.
zsh: راحتی تعاملی
مستندات zsh قابلیتهای گستردهٔ تکمیل، glob پیشرفته، و سفارشیسازی prompt را برجسته میکند. بسیاری توسعهدهندهها با فریمورکهایی مثل Oh My Zsh تم و افزونه نصب میکنند. این برای سرعت کار محلی عالی است؛ برای سرور Production معمولاً لازم نیست zsh را شِل پیشفرض همهٔ کاربران کنید.
اگر اسکریپت را با zsh مینویسید و از آرایهها یا globهای خاص zsh استفاده میکنید، روی سروری که فقط bash دارد میشکند. قانون: اسکریپت مخزن و CI را bash/POSIX نگه دارید؛ dotfiles شخصی را zsh کنید.
جدول مقایسهٔ عملی
| موضوع | bash | zsh |
|---|---|---|
| حضور روی سرور لینوکس | بسیار رایج | گاهی باید نصب شود |
| اسکریپت تیمی / CI | انتخاب پیشفرض خوب | فقط اگر همه توافق کنند |
| تکمیل تعاملی | خوب با تنظیم | عالی پیشفرض/افزونه |
| منحنی سفارشیسازی | متوسط | بالا (افزونهها) |
| سازگاری POSIX | با shebang درست قابلکنترل | فرقها را باید بشناسید |
| مناسب دسکتاپ dev | کاملاً کافی | اغلب ترجیح شخصی |
shebang، قابلحمل بودن و /bin/sh
خط اول اسکریپت با #! مشخص میکند کدام مفسر اجرا شود. #!/usr/bin/env bash در محیطهایی که bash در PATH است انعطاف دارد؛ روی سیستمهای قفلشده گاهی مسیر مطلق بهتر است. هرگز فرض نکنید sh برابر bash است — روی دبیان/اوبونتو sh میتواند dash باشد و [[ ]] یا آرایهٔ bash را نفهمد.
قابلحمل بودن یعنی اسکریپت روی تصویر CI، لپتاپ همکار، و سرور Production بدون «روی ماشین من کار میکند» اجرا شود. وابستگی به aliasهای تعاملی، تابعهای .zshrc، و ابزارهای فقط دسکتاپ ضد قابلحمل بودن است.
مثالهای روزمره در شِل
bash
# متغیر و نقلقول name="Soheil" echo "hello $name" echo 'hello $name' # بدون گسترش # بررسی موفقیت فرمان if command -v curl >/dev/null; then curl -I https://example.com | head -n1 fi # حلقه روی فایلها (با nullglob در bash دقت کنید) for f in *.conf; do [ -e "$f" ] || continue echo "found $f" done
نقلقول دور متغیرها عادت حیاتی است تا فاصله در نام فایل استدلال را نشکند. بسیاری باگهای اسکریپت از همین یک نکته میآیند.
پیکربندی: rc در برابر profile
فایلهایی مثل ~/.bashrc، ~/.zshrc برای نشست تعاملیاند؛ profileها برای login. توزیع و شِل دقیقاً کدام فایل را میخوانند فرق دارد. اگر PATH را در جای غلط بگذارید، ترمینال IDE یک چیز میبیند و SSH چیز دیگر. وقتی رفتار عجیب دیدید، با echo $SHELL و بررسی فایلهای rc شروع کنید؛ جزئیات در مقالهٔ ۱۷۰.
چه زمانی bash، چه زمانی zsh، چه زمانی هیچکدام؟
bash: اسکریپت استقرار، cloud-init، مثالهای مستند سرور، شِل پیشفرض کاربر روی VPS. zsh: لپتاپ شخصی، تکمیل مسیرهای طولانی، کار تعاملی سنگین. هیچکدام: وقتی ابزار تخصصی بهتر است — مثلاً منطق پیچیده را در Python بگذارید و شِل را به orchestrator نازک محدود کنید. شِل برای چسباندن ابزارهای سیستم عالی است؛ برای دامنهٔ تجاری پیچیده، زبان با تست و تایپ معمولاً ارزانتر تمام میشود.
اشتباههای رایج
- نوشتن اسکریپت با فرض اینکه sh همان bash است.
- وابسته کردن CI به aliasهای Oh My Zsh.
- اجرای اسکریپت بدون set -u و بعد عیبیابی متغیر خالی مخرب.
- کپی کردن یکخطیهای اینترنت بدون نقلقول متغیر.
- عوض کردن شِل پیشفرض root به zsh سفارشی روی سرور مشترک بدون توافق تیم.
- نگه داشتن Secret در فایل rc که به مخزن عمومی push میشود.
سوالات متداول
آیا باید از bash به zsh مهاجرت کنم؟
برای لپتاپ اگر تکمیل بهتر میخواهید، بله میتوانید. برای سرور و اسکریپت تیمی، اجباری نیست و گاهی مضر است.
fish چطور؟
fish تجربهٔ تعاملی قوی دارد ولی با POSIX سازگار نیست. برای اسکریپت قابلحمل، انتخاب سختتری است. اگر فقط تعاملی است و تیم موافق است، انتخاب شخصی است.
آیا یادگیری شِل همان یادگیری لینوکس است؟
بخشی از آن است. لینوکس یعنی فایلسیستم، فرایند، مجوز، شبکه و سرویسها؛ شِل واسط اصلی شما به آنهاست.
چرا اسکریپتم در cron خطا میدهد ولی در ترمینال نه؟
محیط فرق دارد: PATH کوتاهتر، شِل غیرتعاملی، نبود rc تعاملی. مسیر مطلق و تعریف صریح محیط را امتحان کنید.
Oh My Zsh روی سرور لازم است؟
معمولاً خیر. سطح حمله و پیچیدگی را بالا میبرد بدون نیاز Production.
تکمیل فرمان، تاریخچه و سرعت کار تعاملی
در کار تعاملی، بخش بزرگی از ارزش شِل از تکمیل با Tab، جستجوی تاریخچه، و ویرایش خط میآید. bash با readline اینها را میدهد؛ zsh معمولاً پیشنهادهای غنیتری برای مسیر و زیرفرمان دارد. این تفاوت در روز اول یادگیری شگفتانگیز به نظر میرسد، اما بعد از چند ماه، عادتهای شخصی (alias، تابع، prompt) بیشتر از نام شِل تعیین میکنند چقدر سریعید.
تاریخچه میتواند نجاتدهنده و خطرناک باشد. فرمانهای دارای توکن، رمز، یا آدرس داخلی را در history نگه ندارید. گزینههایی برای نادیده گرفتن خطوط با فاصلهٔ پیشوند یا حذف انتخابی وجود دارد؛ مستند همان شِل را بخوانید و سیاست تیم را یکخطی کنید: «Secret در history ممنوع».
برای تیمهایی که روی سرور مشترک کار میکنند، یکسانسازی حداقل aliasهای بیخطر مفید است؛ اما هل دادن همه به یک تم زرقوبرق zsh بدون مستند، onboarding را سنگین میکند.
اشکالزدایی اسکریپت شِل
وقتی اسکریپت میشکند، اول کد خروج و خط خطا را ببینید. اجرای آزمایشی با bash -x اسکریپت ردگیری دستورات را چاپ میکند و نشان میدهد کدام شاخه اجرا شده. برای اسکریپتهای طولانی، لاگ ساختاریافته با echo به stderr و استفاده از توابع کوچک بهتر از یک فایل ۲۰۰ خطی تو در تو است.
bash
bash -n deploy.sh # فقط بررسی نحو bash -x deploy.sh 2> deploy.trace tail -n 50 deploy.trace
تست روی کپی داده و در محیط staging را جدی بگیرید. اسکریپتهایی که مسیر را از ورودی کاربر میسازند، بدون اعتبارسنجی، به پیمایش مسیر و حذف اشتباه حساساند. اگر منطق از حد چند شاخه و حلقه گذشت، مهاجرت تدریجی به Python با تست واحد معمولاً ارزانتر از شِل زیرکانه است.
شِل در CI و کانتینر
Imageهای Docker اغلب bash یا فقط sh دارند. Alpine ممکن است ash/busybox ash بدهد. قبل از فرض #!/bin/bash، در Dockerfile پایه را چک کنید یا bash را صریح نصب کنید. در GitHub Actions و مشابه، runner معمولاً bash دارد، ولی قابلحملنویسی همچنان ارزش دارد.
در CI، نشست غیرتعاملی است: رنگ، prompt و پرسش yes/no را غیرفعال کنید، flagهای --yes را به ابزارها بدهید، و به tty وابسته نباشید. خروجی را طوری بنویسید که در لاگ خام خوانا باشد.
چکلیست انتخاب برای تیم
- اسکریپتهای مخزن: bash با shebang صریح و set معقول.
- لپتاپ شخصی: zsh یا bash با dotfiles جدا از مخزن اپ.
- کاربر روی VPS: bash مگر دلیل مستند داشته باشید.
- آموزش تازهوارد: اول bash و مفاهیم pipe/مجوز، بعد افزونههای zsh.
- مرور PR اسکریپت: نقلقول متغیر، مسیر مطلق حساس، و نبود Secret.
خلاصه
شِل مفسر فرمان و زبان چسب سیستم است. bash زبان مشترک امن برای اسکریپت سرور است؛ zsh برای تعامل محلی درخشان است اگر مرز اسکریپت را حفظ کنید. shebang، نقلقول، و جدا کردن محیط تعاملی از اتوماسیون، بیشتر دردهای روزمره را کم میکند.
قدم بعد: ساختار فایلسیستم را در ۱۴۶ ببینید تا بدانید اسکریپتها روی کجا اثر میگذارند؛ سپس مجوز و chmod را در ۱۴۷–۱۴۸ جدی بگیرید.
منابع و مراجع
- GNU Bash Reference Manual — https://www.gnu.org/software/bash/manual/
- Zsh Documentation — https://zsh.sourceforge.io/Doc/
- man7.org — bash(1) — https://man7.org/linux/man-pages/man1/bash.1.html
- man7.org — zsh(1) — https://man7.org/linux/man-pages/man1/zsh.1.html
- Debian dash manpage context for /bin/sh — https://manpages.debian.org/bookworm/dash/dash.1.en.html
- Ubuntu Server documentation — https://documentation.ubuntu.com/server/
نویسنده
سهیل ابراهیمپور بنیانگذار FutureForge است. روی طراحی محصول، معماری و استقرار نرمافزار سفارشی کار میکند.
یادداشتهای مرتبط
اگر در انتخاب معماری یا مسیر توسعه مطمئن نیستید، میتوانید درباره پروژه صحبت کنیم.
مسئله و محدودیت را بنویسید. اگر تطابق داشته باشیم، برای گفتگو هماهنگ میکنیم.




