۱۱ – محیط (Environment)

همان‌طور که پیش‌تر گفتیم، شِل در طول یک نشست (Session) مجموعه‌ای از اطلاعات را نگه می‌دارد که به آن «محیط» یا Environment گفته می‌شود. داده‌هایی که در این محیط ذخیره می‌شوند، توسط برنامه‌ها برای تشخیص جزئیاتی از پیکربندی سیستم استفاده می‌شوند.
در حالی که بیشتر برنامه‌ها تنظیمات خود را در فایل‌های پیکربندی (configuration files) ذخیره می‌کنند، برخی برنامه‌ها برای تنظیم رفتارشان از مقادیر ذخیره‌شده در محیط نیز استفاده می‌کنند. دانستن این موضوع به ما اجازه می‌دهد تجربهٔ کار با شِل را مطابق سلیقهٔ خود سفارشی کنیم.

در این فصل با دستورات زیر کار خواهیم کرد:


چه چیزهایی در محیط ذخیره می‌شوند؟

شِل دو نوع دادهٔ اصلی را در محیط ذخیره می‌کند، هرچند در bash تفاوت میان آن‌ها تقریباً از بین رفته است:

متغیرهای شِل داده‌هایی هستند که خود bash آن‌ها را می‌سازد، در حالی که متغیرهای محیطی شامل سایر مقادیر هستند.
علاوه بر این متغیرها، شِل داده‌های برنامه‌نویسی دیگری مانند aliasها و توابع شِل (Shell Functions) را نیز نگه می‌دارد.
در فصل ۵ دربارهٔ alias صحبت کردیم و توابع شِل را در بخش چهارم کتاب بررسی خواهیم کرد.


بررسی محیط

برای مشاهدهٔ محتویات محیط می‌توان از دستور داخلی set در bash یا برنامهٔ printenv استفاده کرد.

از آن‌جا که فهرست این متغیرها طولانی است، بهتر است خروجی را به دستور less ارسال کنیم:

[me@linuxbox ~]$ printenv | less

با اجرای این دستور، خروجی چیزی شبیه زیر خواهد بود:

KDE_MULTIHEAD=false
SSH_AGENT_PID=6666
HOSTNAME=linuxbox
GPG_AGENT_INFO=/tmp/gpg-PdOt7g/S.gpg-agent:6689:1
SHELL=/bin/bash
TERM=xterm
...
USER=me

در اینجا مجموعه‌ای از متغیرهای محیطی و مقادیرشان را می‌بینیم.
برای مثال، متغیر USER دارای مقدار "me" است.
می‌توانیم مقدار یک متغیر خاص را نیز با دستور زیر ببینیم:

[me@linuxbox ~]$ printenv USER
me

اگر دستور set را بدون گزینه یا آرگومان اجرا کنیم، هم متغیرهای محیطی و شِل و هم توابع تعریف‌شده را نمایش می‌دهد.
برخلاف printenv، خروجی آن به‌صورت مرتب‌شده بر اساس حروف الفبا است:

[me@linuxbox ~]$ set | less

همچنین می‌توان مقدار یک متغیر را با استفاده از echo مشاهده کرد:

[me@linuxbox ~]$ echo $HOME
/home/me

یکی از اجزای محیط که نه set و نه printenv آن را نمایش نمی‌دهند، alias‌ها هستند.
برای دیدن آن‌ها، کافی است دستور alias را بدون هیچ آرگومانی اجرا کنید:

[me@linuxbox ~]$ alias
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

چند متغیر جالب

محیط شامل تعداد زیادی متغیر است. ممکن است محیط سیستم شما با این مثال تفاوت‌هایی داشته باشد،
اما معمولاً متغیرهای زیر را در بیشتر سیستم‌ها خواهید دید:

متغیر توضیح
DISPLAY نام نمایشگر (Display) شما زمانی که در محیط گرافیکی کار می‌کنید. معمولاً مقدار آن :0 است، یعنی اولین نمایشگر ایجادشده توسط X Server.
EDITOR نام برنامه‌ای که برای ویرایش متن‌ها استفاده می‌شود.
SHELL مسیر برنامهٔ شِل مورد استفاده (مثلاً /bin/bash).
HOME مسیر پوشهٔ خانگی (home directory) شما.
LANG زبان سیستم و ترتیب مرتب‌سازی (Collation Order) را مشخص می‌کند.
OLD_PWD مسیر دایرکتوری کاری قبلی.
PAGER برنامه‌ای که برای نمایش صفحه‌به‌صفحهٔ خروجی استفاده می‌شود (معمولاً /usr/bin/less).
PATH فهرستی از مسیرهای جداشده با دونقطه : که هنگام اجرای یک دستور، سیستم در آن‌ها به دنبال فایل اجرایی می‌گردد.
PS1 رشتهٔ نمایش خط فرمان (Prompt String 1). می‌توان آن را کاملاً شخصی‌سازی کرد.
PWD مسیر دایرکتوری کاری فعلی.
TERM نوع ترمینال مورد استفاده. سیستم‌های شبه یونیکس از پروتکل‌های مختلفی پشتیبانی می‌کنند؛ این متغیر مشخص می‌کند کدام پروتکل برای شبیه‌ساز ترمینال شما استفاده شود.
TZ منطقهٔ زمانی (Time Zone) شما را مشخص می‌کند. سیستم معمولاً ساعت داخلی را با زمان UTC نگه می‌دارد و زمان محلی را با توجه به این متغیر محاسبه می‌کند.
USER نام کاربری فعلی شما.

نگران نباشید اگر بعضی از این متغیرها در محیط شما وجود ندارند؛ مقدار آن‌ها بسته به توزیع لینوکس فرق می‌کند.


چگونه محیط ساخته می‌شود؟

وقتی وارد سیستم می‌شویم، برنامهٔ bash اجرا شده و مجموعه‌ای از اسکریپت‌های پیکربندی به نام startup files را می‌خواند.
این فایل‌ها محیط پیش‌فرض را تعریف می‌کنند که بین همهٔ کاربران مشترک است.
سپس فایل‌های آغازین مخصوص کاربر (در مسیر home) خوانده می‌شوند که محیط شخصی هر کاربر را تنظیم می‌کنند.

دنبالهٔ دقیق خواندن این فایل‌ها بستگی به نوع نشست شِل دارد.
دو نوع نشست وجود دارد:


فایل‌های راه‌انداز در نشست‌های ورود (Login)

فایل توضیح
/etc/profile اسکریپت پیکربندی عمومی برای همهٔ کاربران.
~/.bash_profile فایل شخصی کاربر. می‌تواند تنظیمات عمومی را گسترش دهد یا بازنویسی کند.
~/.bash_login اگر ~/.bash_profile وجود نداشته باشد، bash این فایل را می‌خواند.
~/.profile اگر هیچ‌کدام از دو فایل قبلی نباشند، bash این فایل را می‌خواند (در توزیع‌های مبتنی بر Debian مثل Ubuntu پیش‌فرض است).

فایل‌های راه‌انداز در نشست‌های غیرورود (Non-Login)

فایل توضیح
/etc/bash.bashrc اسکریپت پیکربندی عمومی برای همهٔ کاربران.
~/.bashrc فایل شخصی کاربر برای تنظیمات شِل. می‌تواند تنظیمات عمومی را بازنویسی کند.

نشست‌های غیرورود علاوه بر خواندن این فایل‌ها، محیط را از فرآیند والد خود (معمولاً شِل ورود) به ارث می‌برند.

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

ls -a ~

در میان این فایل‌ها، معمولاً ~/.bashrc مهم‌ترین است،
زیرا تقریباً همیشه اجرا می‌شود — نشست‌های غیرورود آن را مستقیماً می‌خوانند
و بیشتر فایل‌های آغازین نشست‌های ورود هم طوری نوشته شده‌اند که این فایل را فراخوانی کنند.

داخل یک فایل راه‌انداز (Startup File) چه می‌گذرد؟

اگر به درون یک فایل معمولی .bash_profile (برای مثال در سیستم CentOS 4) نگاه کنیم، معمولاً چیزی شبیه این می‌بینیم:

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH

توضیح خطوط و ساختار فایل

خط‌هایی که با # شروع می‌شوند توضیح (comment) هستند و توسط شِل اجرا نمی‌شوند؛ فقط برای خوانایی انسان قرار داده شده‌اند.

اما بخش اصلی از خط چهارم آغاز می‌شود:

if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

این یک دستور ترکیبی if است.
در ساده‌ترین ترجمه می‌گوید:

اگر فایل ~/.bashrc وجود دارد، آن را بخوان.

در واقع این همان بخشی است که باعث می‌شود شِل ورود (login shell) فایل ~/.bashrc را نیز بارگذاری کند.
بنابراین تنظیمات تعریف‌شده در .bashrc برای هر نشست ورود نیز فعال می‌شوند.


نقش متغیر PATH

در ادامه فایل، بخش مربوط به متغیر PATH را می‌بینیم.
حتماً تا به حال از خود پرسیده‌اید شِل چگونه مسیر اجرای دستوراتی مانند ls را پیدا می‌کند؟
وقتی شما ls را در ترمینال می‌نویسید، bash کل سیستم را جستجو نمی‌کند تا /bin/ls را بیابد؛ بلکه فقط در مسیرهایی که در متغیر PATH تعریف شده‌اند جستجو می‌کند.

در این فایل، PATH معمولاً (اما نه همیشه) در /etc/profile مقداردهی اولیه می‌شود،
و سپس با دستور زیر گسترش می‌یابد:

PATH=$PATH:$HOME/bin

این خط مقدار موجود در PATH را گرفته و مسیر $HOME/bin را به انتهای آن اضافه می‌کند.

این عمل نمونه‌ای از گسترش پارامتر (Parameter Expansion) است.

برای درک بهتر، به مثال زیر توجه کنید:

[me@linuxbox ~]$ foo="This is some "
[me@linuxbox ~]$ echo $foo
This is some
[me@linuxbox ~]$ foo=$foo"text."
[me@linuxbox ~]$ echo $foo
This is some text.

همان‌طور که می‌بینید، با این روش می‌توانیم به انتهای محتوای یک متغیر، متن جدیدی اضافه کنیم.
در مورد PATH هم دقیقاً همین اتفاق می‌افتد: مسیر $HOME/bin به انتهای فهرست مسیرهای موجود افزوده می‌شود.


کاربرد عملی

با این کار، اگر بخواهیم برنامه‌های شخصی خود را در مسیر خانگی‌مان ذخیره کنیم،
کافی است پوشه‌ای به نام bin در مسیر خانگی بسازیم، چون شِل به طور خودکار هنگام اجرای دستورها آن را بررسی خواهد کرد:

mkdir ~/bin

در بسیاری از توزیع‌ها (از جمله بعضی نسخه‌های Debian و Ubuntu)، این رفتار به‌صورت خودکار انجام می‌شود؛
سیستم در هنگام ورود بررسی می‌کند اگر پوشه‌ی ~/bin وجود داشت، آن را به PATH اضافه کند.


دستور export

در انتهای فایل می‌بینیم:

export PATH

دستور export به شِل می‌گوید که مقدار متغیر PATH را به فرایندهای فرزند (child processes) نیز انتقال دهد.
به عبارت دیگر، هر برنامه یا شِل جدیدی که از این شِل فعلی اجرا شود، همان PATH را به ارث خواهد برد.

تغییر محیط (Modifying the Environment)

حالا که می‌دانیم فایل‌های راه‌انداز (startup files) کجا هستند و چه کار می‌کنند،
می‌توانیم آن‌ها را ویرایش کنیم تا محیط خود را شخصی‌سازی کنیم.


کدام فایل‌ها را باید تغییر دهیم؟

به‌صورت کلی:

تا زمانی که مدیر سیستم نیستید و قصد ندارید تنظیمات پیش‌فرض همهٔ کاربران را تغییر دهید،
فقط فایل‌های پوشهٔ خانگی خودتان را ویرایش کنید.
درست است که فایل‌های /etc مثل profile هم قابل تغییرند،
اما بهتر است فعلاً سمت آن‌ها نروید — ایمن‌تر است که فقط تنظیمات شخصی خودتان را تغییر دهید.


ویرایشگرهای متنی (Text Editors)

برای ویرایش فایل‌های پیکربندی شِل (و به‌طور کلی، بیشتر فایل‌های تنظیمات در لینوکس)،
از برنامه‌ای به نام ویرایشگر متن (Text Editor) استفاده می‌کنیم.

ویرایشگر متن تا حدی شبیه واژه‌پردازهاست (مثل Word) اما فقط از متن ساده (Plain Text) پشتیبانی می‌کند
و هیچ قالب‌بندی (فونت، اندازه، رنگ و...) ندارد.
همچنین معمولاً ابزارهایی مخصوص برنامه‌نویسی دارند.

ویرایشگرهای متن یکی از ابزارهای اصلی برنامه‌نویسان و مدیران سیستم هستند؛
برنامه‌نویسان برای نوشتن کد و مدیران برای پیکربندی سیستم از آن‌ها استفاده می‌کنند.

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


دسته‌بندی کلی ویرایشگرها

ویرایشگرها به دو نوع اصلی تقسیم می‌شوند:

  1. گرافیکی (Graphical Editors):

    • در محیط GNOME معمولاً برنامه‌ای به نام gedit (با عنوان “Text Editor”) وجود دارد.
    • در KDE معمولاً سه گزینه دیده می‌شود:
      kedit, kwrite و kate (به ترتیب از ساده به پیشرفته).
  2. متنی (Text-based Editors):

    • معروف‌ترین‌ها: nano, vi/vim, و emacs
    • nano ساده‌ترین و کاربرپسندترین گزینه است، جایگزینی برای ویرایشگر قدیمی pico.
    • vi یا نسخهٔ پیشرفته‌ترش vim (مخفف Vi IMproved) ویرایشگر سنتی سیستم‌های شبه‌یونیکس است.
    • emacs (نوشتهٔ Richard Stallman) محیطی بسیار بزرگ و همه‌کاره است که تقریباً هر کاری می‌تواند انجام دهد،
      ولی به‌صورت پیش‌فرض در بسیاری از توزیع‌ها نصب نیست.

اجرای ویرایشگر از خط فرمان

تمام ویرایشگرها را می‌توان از Command Line اجرا کرد:
کافی است نام ویرایشگر را بنویسید و نام فایلی را که می‌خواهید ویرایش کنید، به آن بدهید.

مثلاً:

[me@linuxbox ~]$ gedit some_file

اگر فایل some_file وجود داشته باشد، باز می‌شود؛
در غیر این صورت، برنامه فرض می‌کند می‌خواهید فایل جدیدی بسازید.


ویرایش امن فایل‌های پیکربندی

قبل از اینکه فایل‌های مهمی مثل .bashrc را ویرایش کنید، همیشه یک نسخهٔ پشتیبان (Backup) تهیه کنید.
این کار جلوی دردسرهای احتمالی را می‌گیرد اگر وسط کار چیزی را خراب کنید.

مثلاً:

[me@linuxbox ~]$ cp .bashrc .bashrc.bak

فرقی نمی‌کند فایل پشتیبان را چه بنامید،
ولی پسوندهایی مثل .bak, .sav, .old, یا .orig رایج هستند.
فقط حواستان باشد که دستور cp بدون هشدار، فایل همنام را بازنویسی می‌کند.


باز کردن فایل برای ویرایش با nano

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

[me@linuxbox ~]$ nano .bashrc

این دستور ویرایشگر متنی nano را باز می‌کند و فایل .bashrc را بارگذاری می‌کند.
از اینجا می‌توانید aliasها، تنظیمات رنگ، یا متغیرهای دلخواه خود را اضافه کنید.

وقتی ویرایشگر nano را اجرا می‌کنیم، صفحه‌ای شبیه زیر نمایش داده می‌شود:

GNU nano 2.0.3           File: .bashrc
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi
# User specific aliases and functions
                         [ Read 8 lines ]
^G Get Help ^O WriteOut ^R Read File ^Y Prev Page ^K Cut Text ^C Cur Pos
^X Exit     ^J Justify  ^W Where Is  ^V Next Page ^U UnCut Text ^T To Spell

ساختار صفحه‌ی nano

صفحه شامل سه بخش است:

  1. سربرگ (Header) در بالای صفحه (نمایش نام فایل و نسخهٔ برنامه)،
  2. متن فایل در وسط،
  3. منوی دستورات کلیدی در پایین (دستورات اصلی با کلیدهای ترکیبی).

نکته: اگر سیستم شما nano ندارد، می‌توانید از یکی از ویرایشگرهای گرافیکی مثل gedit یا kate استفاده کنید.


آشنایی با کلیدهای اصلی nano

از آن‌جایی که nano برای جایگزینی ویرایشگر سادهٔ ایمیل طراحی شده، امکاناتش کم ولی کاربردی است.

اولین دستوری که باید در هر ویرایشگر یاد بگیرید:
خروج (Exit) → ترکیب Ctrl + X
در منوی پایین، عبارت “^X” به معنی همین ترکیب است. علامت ^ نشان‌دهنده‌ی کلید Ctrl است.
(مثلاً ^O یعنی Ctrl+O، و ^W یعنی Ctrl+W)

دومین دستور مهم:
ذخیره تغییرات (Save)Ctrl + O

با این دو دستور می‌توانید با خیال راحت ویرایش را شروع کنید.


افزودن تنظیمات جدید به .bashrc

با استفاده از کلیدهای (پیکان پایین) یا PageDown به انتهای فایل بروید،
سپس خطوط زیر را به فایل اضافه کنید:

umask 0002
export HISTCONTROL=ignoredups
export HISTSIZE=1000
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'

🔸 نکته: ممکن است برخی از این خطوط از قبل در فایل وجود داشته باشند — وجود تکراری‌ها مشکلی ایجاد نمی‌کند.


توضیح خطوط جدید

خط دستور توضیح و کاربرد
umask 0002 تنظیم umask برای رفع مشکل مجوزها در دایرکتوری‌های اشتراکی (اشاره‌شده در فصل ۹).
export HISTCONTROL=ignoredups باعث می‌شود شِل دستوری را در تاریخچه ذخیره نکند اگر دقیقاً همان دستور قبلاً ثبت شده باشد.
export HISTSIZE=1000 اندازهٔ تاریخچهٔ دستورات (history) را از مقدار پیش‌فرض ۵۰۰ به ۱۰۰۰ خط افزایش می‌دهد.
alias l.='ls -d . --color=auto'* دستور جدیدی به نام l. ایجاد می‌کند که تمام فایل‌ها و پوشه‌هایی را که با نقطه شروع می‌شوند (فایل‌های مخفی) نمایش می‌دهد.
alias ll='ls -l --color=auto' دستور جدیدی به نام ll می‌سازد که فهرست فایل‌ها را با جزئیات (long format) و رنگ‌بندی نشان می‌دهد.

افزودن توضیحات (Comments)

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

# Set default permissions for new files
umask 0002

# Avoid duplicate commands in history
export HISTCONTROL=ignoredups

# Increase history size
export HISTSIZE=1000

# Aliases for easier directory listings
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'

این کار نه‌تنها فایل را خواناتر می‌کند، بلکه در آینده هنگام اشکال‌زدایی یا پیکربندی مجدد، کار را برای خودتان یا سایر کاربران بسیار ساده‌تر می‌کند.

با استفاده از ویرایشگر (nano یا هر ویرایشگر دلخواه دیگر)، حالا می‌خواهیم تغییراتی که قبلاً در .bashrc اضافه کردیم را مرتب و خواناتر کنیم. ساختار نهایی باید به این شکل باشد:

# Change umask to make directory sharing easier
umask 0002

# Ignore duplicates in command history and increase
# history size to 1000 lines
export HISTCONTROL=ignoredups
export HISTSIZE=1000

# Add some helpful aliases
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'

وقتی ویرایش تمام شد:


چرا نوشتن کامنت‌ها مهم است؟

وقتی فایل‌های تنظیمات (configuration files) را تغییر می‌دهید، حتماً کامنت بگذارید تا مشخص شود چه کاری انجام داده‌اید و چرا.
ممکن است امروز دقیقاً به خاطر داشته باشید چه کردید، اما شش ماه بعد احتمالاً فراموش می‌کنید.

بنابراین:

در شِل و اسکریپت‌های bash، برای نوشتن توضیح از علامت # استفاده می‌شود.
در دیگر فایل‌های پیکربندی ممکن است علامت‌های متفاوتی به کار برود (مثل ; یا // در برخی برنامه‌ها).
تقریباً در تمام فایل‌های سیستمی، مثال‌ها و توضیحاتی به شکل کامنت وجود دارد — از آن‌ها یاد بگیرید.


خطوط کامنت‌شده و فعال‌سازی آن‌ها

گاهی می‌بینید خطوطی در فایل‌های تنظیمات با # شروع شده‌اند.
این یعنی آن خط غیرفعال است، ولی برای یادآوری یا مثال در فایل نگه داشته شده.

برای نمونه، در فایل .bashrc نسخهٔ Ubuntu 8.04 چنین بخش‌هایی وجود دارد:

# some more ls aliases
#alias ll='ls -l'
#alias la='ls -A'
#alias l='ls -CF'

سه خط آخر دستورهای واقعی alias هستند، اما به دلیل وجود # در ابتدای‌شان، فعلاً فعال نیستند.
اگر علامت # را حذف کنید (عملی به نام uncommenting)، آن‌ها فعال می‌شوند.
برعکس، اگر بخواهید خطی را موقتاً غیرفعال کنید، کافی است در ابتدای آن # بگذارید.

این کار باعث می‌شود تنظیمات را غیرفعال کنید بدون اینکه اطلاعات‌شان را از دست بدهید.


فعال‌سازی تغییرات جدید

تغییراتی که در .bashrc ایجاد کردیم تا زمانی که جلسهٔ فعلی ترمینال بسته و دوباره باز نشود، فعال نمی‌شوند،
چون bash فقط در ابتدای هر نشست (session) این فایل را می‌خواند.

اما می‌توانیم بدون بستن ترمینال، bash را وادار کنیم همین حالا فایل را دوباره بخواند:

[me@linuxbox ~]$ source .bashrc

بعد از اجرای این دستور، تغییرات بلافاصله اعمال می‌شوند.

برای تست، یکی از alias‌های جدید را امتحان کنید:

[me@linuxbox ~]$ ll

اگر لیست فایل‌ها با رنگ و قالب‌بندی بلند (long format) نمایش داده شد، یعنی همه چیز درست کار می‌کند ✅


جمع‌بندی

در این فصل یاد گرفتیم چطور فایل‌های پیکربندی را با ویرایشگر متنی ویرایش کنیم —
مهارتی حیاتی برای هر کاربر لینوکس.

از این پس، هنگام خواندن man pageها، به بخش متغیرهای محیطی (environment variables) توجه کنید؛
بسیاری از دستورات تنظیماتی دارند که از طریق همین متغیرها قابل کنترل‌اند.

در فصل‌های بعدی یاد می‌گیریم چگونه با توابع شِل (shell functions) کار کنیم،
تا بتوانیم دستورات سفارشی خودمان را به bash اضافه کنیم و محیط کاری‌مان را کاملاً شخصی‌سازی نماییم.


منابع بیشتر برای مطالعه