
مقدمه
هنگام تعامل با سرور خود از طریق یک نشست شل (Shell Session)، اطلاعات زیادی وجود دارد که شل برای تعیین رفتار و دسترسی به منابع آنها را جمعآوری میکند. برخی از این تنظیمات در پیکربندیهای سیستم وجود دارند و برخی دیگر توسط ورودی کاربر تعیین میشوند.
یکی از روشهایی که شل برای پیگیری تمام این تنظیمات استفاده میکند، استفاده از فضایی به نام «محیط» (Environment) است. محیط ناحیهای است که شل هر بار هنگام شروع یک نشست میسازد و شامل متغیرهایی است که ویژگیهای سیستم را تعریف میکنند.
در این راهنما، نحوه تعامل با محیط و خواندن یا تنظیم متغیرهای محیطی و شل را به صورت تعاملی و از طریق فایلهای پیکربندی بررسی خواهیم کرد.
نکته: این آموزش بر روی جدیدترین توزیعهای لینوکس از جمله اوبونتو 22.04 LTS، اوبونتو 24.04 LTS، دبیان 12، CentOS Stream 9 و Rocky Linux 9 تست و اعتبارسنجی شده است. تمام دستورات و مثالها بر روی سیستمهای مدرن لینوکس با Bash نسخه 5.x به بعد به درستی کار میکنند. اگر میخواهید از سرورهای پارمین کلود (Parmin Cloud) برای پیگیری این آموزش استفاده کنید، کافیست یک ترمینال باز کرده و دستورات را در آن اجرا کنید.
نکات کلیدی
پیش از ورود به جزئیات، در اینجا نکات اساسی درباره متغیرهای محیطی و شل در لینوکس آورده شده است:
- متغیرهای محیطی (Environmental Variables) توسط پردازشهای فرزند به ارث برده میشوند و بر رفتار کل سیستم تأثیر میگذارند، در حالی که متغیرهای شل (Shell Variables) فقط محدود به نشست شل فعلی هستند.
- برای مشاهده متغیرهای محیطی از دستورات
printenvیاenvاستفاده کنید و برای دیدن تمام متغیرهای شل و محیطی ازsetاستفاده نمایید. - دستور
exportمتغیرهای شل را به متغیرهای محیطی تبدیل میکند تا برای پردازشهای فرزند در دسترس قرار گیرند. - برای ماندگار کردن متغیرها در نشستهای مختلف، آنها را به فایلهای پیکربندی شل مانند
~/.bashrcیا~/.profileاضافه کنید. - درک محدوده (Scope) و ارثبری متغیرها برای مدیریت پیکربندی و امنیت بسیار حیاتی است.
محیط و متغیرهای محیطی چگونه کار میکنند؟
هر بار که یک نشست شل شروع میشود، فرآیندی انجام میشود تا اطلاعاتی که باید برای فرآیند شل و فرآیندهای فرزند آن در دسترس باشد، جمعآوری و تدوین شود.
محیط به عنوان واسطهای عمل میکند که فرآیند شل از طریق آن میتواند تنظیمات را دریافت یا اعمال کرده و در نهایت آنها را به پردازشهای فرزند خود منتقل کند.
محیط به صورت رشتههایی پیادهسازی میشود که جفتهای کلید-مقدار (Key-Value) را نشان میدهند. اگر چندین مقدار ارسال شود، معمولاً با کاراکتر دو نقطه (:) از هم جدا میشوند. هر جفت به این شکل است:KEY=value1:value2:...
اگر مقدار شامل فاصله باشد، از علامت نقلقول استفاده میشود:KEY="value with spaces"
کلیدها در این حالت متغیر هستند و به دو دسته تقسیم میشوند: متغیرهای محیطی و متغیرهای شل.
- متغیرهای محیطی: متغیرهایی هستند که برای شل فعلی تعریف میشوند و توسط هر شل یا پردازش فرزندی به ارث برده میشوند.
- متغیرهای شل: متغیرهایی هستند که منحصراً درون همان شلی که تعریف شدهاند باقی میمانند و به پردازشهای فرزند منتقل نمیشوند (مگر اینکه صراحتاً export شوند).
برای تمایز بهتر، این متغیرها معمولاً با حروف بزرگ نوشته میشوند.
چاپ متغیرهای شل و محیطی
میتوانیم با استفاده از دستورات env یا printenv لیستی از تمام متغیرهای محیطی خود را ببینیم:
printenv
خروجی شما چیزی شبیه به این خواهد بود:
SHELL=/bin/bash
TERM=xterm
USER=demouser
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
PWD=/home/demouser
HOME=/home/demouser
تفاوت این دو دستور در کاربردهای تخصصیتر آنها مشخص میشود. مثلاً با printenv میتوانید مقدار یک متغیر خاص را درخواست کنید:
printenv PATH
خروجی:
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
از طرفی، دستور env به شما اجازه میدهد محیط اجرای برنامهها را با ارسال تعریف متغیرهای جدید تغییر دهید:
env VAR1="value" command_to_run command_options
برای مشاهده متغیرهای شل، از دستور set استفاده میکنیم. اگر set را بدون پارامتر تایپ کنید، لیستی از تمام متغیرهای شل، متغیرهای محیطی، متغیرهای محلی و توابع شل دریافت میکنید:
set | less
برای تمیزتر کردن خروجی، میتوانید آن را در حالت POSIX اجرا کنید تا توابع شل نمایش داده نشوند:
(set -o posix; set)
متغیرهای متداول محیطی و شل
برخی از این متغیرها بسیار پرکاربرد هستند:
| متغیر | نوع | توضیح |
|---|---|---|
SHELL | محیطی | شلی که دستورات شما را تفسیر میکند (معمولاً bash). |
USER | محیطی | کاربر فعلی که وارد سیستم شده است. |
PWD | محیطی | دایرکتوری کاری فعلی. |
PATH | محیطی | لیستی از دایرکتوریها (جداشده با 🙂 که سیستم برای یافتن دستورات آنها را جستجو میکند. |
HOME | محیطی | دایرکتوری خانه کاربر فعلی. |
PS1 | شل | قالب پرامپت فرمان شما. |
HISTSIZE | شل | تعداد خطوط تاریخچه دستورات که در حافظه نگه داشته میشود. |
تنظیم متغیرهای شل و محیطی
ایجاد متغیرهای شل
برای تعریف یک متغیر شل در نشست فعلی، کافی است یک نام و یک مقدار مشخص کنید:
TEST_VAR='Hello World!'
اکنون یک متغیر شل داریم. این متغیر در نشست فعلی در دسترس است اما به پردازشهای فرزند منتقل نمیشود. با استفاده از echo میتوانیم به مقدار آن دسترسی داشته باشیم:
echo $TEST_VAR
خروجی:
Hello World!
اگر یک شل فرزند (مثلاً با تایپ دستور bash) باز کنیم و echo $TEST_VAR را اجرا کنیم، چیزی چاپ نمیشود زیرا متغیرهای شل ارثبری نمیشوند.
ایجاد متغیرهای محیطی
اکنون متغیر شل خود را به یک متغیر محیطی تبدیل میکنیم. این کار را با دستور export انجام میدهیم:
export TEST_VAR
اگر دوباره یک شل فرزند ایجاد کنیم، میبینیم که متغیر به ارث برده شده است:
bash
echo $TEST_VAR
خروجی:
Hello World!
تنزل دادن و حذف متغیرها
برای تبدیل دوباره یک متغیر محیطی به متغیر شل:
export -n TEST_VAR
برای حذف کامل یک متغیر (چه شل و چه محیطی):
unset TEST_VAR
تنظیم متغیرهای محیطی هنگام ورود (Login)
برای اینکه متغیرها هر بار که یک نشست جدید شروع میشود به طور خودکار تنظیم شوند، باید آنها را در فایلهای پیکربندی قرار دهیم.
شلهای لینوکس به دو دسته کلی تقسیم میشوند:
۱. شلهای ورود (Login Shells): نشستهایی که با احراز هویت کاربر شروع میشوند (مانند اتصال از طریق SSH). این شلها فایل /etc/profile و سپس اولین فایل موجود از بین ~/.bash_profile، ~/.bash_login یا ~/.profile را میخوانند.
۲. شلهای غیر ورود (Non-login Shells): نشستهایی که درون یک شل از قبل احراز هویت شده باز میشوند (مثلاً باز کردن یک ترمینال جدید در محیط گرافیکی). این شلها فایل ~/.bashrc را میخوانند.
از آنجایی که اکثر توزیعهای مدرن لینوکس فایلهای ورود را طوری پیکربندی میکنند که فایل ~/.bashrc را فراخوانی (source) کنند، بهترین مکان برای تعریف متغیرهای محیطی کاربر، فایل ~/.bashrc است تا در هر دو حالت در دسترس باشد.
فایل را باز کنید:
nano ~/.bashrc
متغیرهای خود را به این شکل اضافه کنید:
export VARNAME=value
فایل را ذخیره کرده و ببندید. برای اعمال تغییرات در نشست فعلی:
source ~/.bashrc
اگر نیاز به تنظیم متغیرها برای کل سیستم (تمام کاربران) دارید، میتوانید آنها را در /etc/profile، /etc/bash.bashrc یا /etc/environment اضافه کنید.
ملاحظات امنیتی متغیرهای محیطی
متغیرهای محیطی میتوانند حاوی اطلاعات حساسی مانند کلیدهای API، رمزهای عبور دیتابیس و توکنهای احراز هویت باشند. درک پیامدهای امنیتی برای محافظت از سیستم شما ضروری است.
بهترین روشهای امنیتی:
- هرگز دادههای حساس را به صورت متن ساده (Plain text) در فایلهایی که به سیستم کنترل نسخه (مثل گیتهاب) ارسال میشوند، ذخیره نکنید.
- برای فایلهای پیکربندی حاوی متغیرهای محیطی، مجوزهای فایل مناسب تنظیم کنید (معمولاً
600برای فایلهای کاربر). - از export کردن متغیرهای حساس除非 در صورت نیاز مطلق خودداری کنید.
- برای فایل
~/.bashrcخود مجوزهای محدودکننده تنظیم کنید:chmod 600 ~/.bashrc
رفع مشکلات رایج
- متغیر در اسکریپتها در دسترس نیست: مطمئن شوید که متغیر
exportشده است. اسکریپتها معمولاً در شلهای غیر تعاملی اجرا میشوند که فایل~/.bashrcرا نمیخوانند. میتوانید متغیرها را در~/.profileقرار دهید یا فایل پیکربندی را درون اسکریپت فراخوانی (source) کنید. - متغیرها پس از بستن ترمینال از بین میروند: مطمئن شوید که متغیرها را در فایل پیکربندی صحیح (مانند
~/.bashrc) ذخیره کردهاید و خطای نحوی (Syntax Error) در فایل وجود ندارد. - مشکلات متغیر PATH: اگر دستوراتی پس از اضافه کردن دایرکتوری به PATH پیدا نمیشوند، ترتیب دایرکتوریها را بررسی کنید و مطمئن شوید که کاراکتر دو نقطه (
:) به درستی قرار گرفته است.
نتیجهگیری
متغیرهای محیطی و شل همیشه در نشستهای شل شما حضور دارند و بسیار مفید هستند. آنها راهی برای تنظیم پیکربندی توسط یک پردازس والد برای فرزندانش فراهم میکنند و روشی برای تنظیم گزینهها خارج از فایلها ارائه میدهند. درک محدوده متغیرها، ارثبری و پیامدهای امنیتی به شما کمک میکند تا سیستم لینوکس خود را به طور مؤثری پیکربندی کنید و در عین حال روشهای امنیتی مناسب را رعایت نمایید.




