این نوشته فرض میکند شما در حال استفاده از bash به عنوان پوسته نشست login خود هستید و از لینوکس استفاده میکنید، مگر اینکه طور دیگری تصریح شده باشد.
روش رفتار سیستم شما هنگام لاگین، در مراجعه برای خواندن فایلهای نقطهای، برقراری مستعارها، تنظیم متغیرهای محیط، و غیره ، همگی به اندازه زیادی وابسته به آن است که واقعاً چطور به سیستم متصل میشوید.
بیایید با سادهترین پیکربندی شروع کنیم: یک اتصال محلی در کنسول متنی لینوکس، ابداً بدون هرگونه محیط گرافیکی. در این حالت، موقعی که کامپیوتر را راهاندازی میکنید، شما سرانجام یک اعلان "login:" مشاهده میکنید. این اعلان توسط برنامهای به نام getty(8) تولید میگردد که روی دستگاه tty (ترمینال) اجرا میشود. وقتی شما یک نام کاربری را تایپ میکنید، getty آن را میخواند و به برنامهای به نام login(1) عبور میدهد. برنامه login بانک اطلاعات کلمه عبور را میخواند و تصمیم میگیرد که آیا از شما یک کلمه عبور درخواست کند.وقتی شما کلمه عبور خود را تأمین کردهاید، login پوسته لاگین شما، bash راexec(2) میکند.
اکنون، چون bash به عنوان یک پوسته لاگین دارد فراخوانی میشود(با نام "-bash"، یک ترفند ویژه قدیمی)، اول فایل /etc/profile را میخواند. سپس به دایرکتوری خانگی برای یافتن .bash_profile نگاه میکند، و اگر آن را پیدا کند، میخواند. اگر فایل .bash_profile را پیدا نکند، برای .bash_login جستجو میکند، و اگر آنرا پیدا نکند، فایل .profile (فایل پیکربندی استاندارد پوسته بورن و Korn)را جستجو میکند. در غیر اینصورت، جستجو برای فایلهای نقطهای را متوقف میکند، و اعلان فرمان را به شما میدهد.
بسیاری از سیستمهای لینوکس دارای یک لایه دیگری به نام زیرنویس PAM هستند که مربوط به اینجا میباشد. قبل از اجرای bash، برنامه login فایل /etc/pam.d/login (یا معادل آن در سیستم شما) را خواهد خواند، که شاید به او بگوید فایلهای مختلف دیگری از قبیل /etc/environment را بخواند. سیستمهای دیگر از قبیل OpenBSD دارای یک فایل /etc/login.conf هستند که محدودیتهای منابع برای کلاسهای مختلف حسابهای کاربری را کنترل میکند. بنابراین ممکن است، قبل از اینکه پوسته شما /etc/profile را بخواند، شما دارای متغیرهای اضافی محیط، محدودیتهای پردازش، و غیره، باشید.
ممکن است شما توجه نموده باشید که در این وضعیت فایل .bashrc خوانده نمیشود. بنابراین شما همواره باید سطر source ~/.bashrc را در انتهای فایل .bash_profile خود، به منظور تحمیل خوانده شدن آن به وسیله پوسته لاگین داشته باشید.
پس چرا .bashrc یک فایل مجزا از .bash_profile است؟ دو دلیل وجود دارد. اول به دلیل کارایی است -- زمانی که ماشینها در مقایسه با ایستگاههای کاری امروزی بیش از حد آهسته بودند، پردازش فرمانهای .profile یا .bash_profile میتوانست واقعاً زمان طولانی را صرف کند، مخصوصاً روی ماشینهایی که در آنها باید کار بسیاری توسط فرمانهای خارجی انجام میگردید(قبل از پوستههای Korn وBash ). بنابراین دستورات برپاسازی سختگیر اولیه، که متغیرهای محیط که میتوانند به پردازشهای فرزند عبور داده شوند، را تولید مینمودند در .bash_profile قرار داده میشوند. تنظیمات موقتی، مستعارها یا توابع که به ارث نمیرسند در .bashrc قرار داده میشوند به طوری که میتوانند توسط هر پوسته فرعی بازخوانی بشوند.
دومین دلیل که چرا .bashrc مجزا میباشد، ناشی از عادتهای کاری است. اگر شما در ادارهای با یک ترمینال قرار گرفته روی میزتان کار کنید، احتمالاً یکبار در شروع هر روز لاگین میکنید و در پایان روز از سیستم خارج میشوید. شما میتوانید دستورات ویژه مختلفی که میخواهید در ابتدای هر روز موقعی که به سیستم متصل میشود، اجرا شوند -- کنترل آگهیهای مدیریت و غیره -- را در فایل .bash_profile خودتان قرار بدهید. شما نمیخواهید در هر نوبت که پوسته جدیدی را شروع میکنید آنها اجرا بشوند. بنابراین، داشتن این تمایز مقداری قابلیت انعطاف برای شما فراهم میکند.
اجازه بدهید مرور کنیم. یک مدیر سیستم، یک سیستم دبیان(که مبتنی بر لینوکس است و از PAM استفاده میکند) تنظیم نموده و یک تنظیم منطقه LANG=en_US در /etc/environment دارد. یک کاربر محلی به نام pierre ترجیح میدهد به جای آن از تنظیم منطقه fr_CA استفاده کند، از این جهت او سطر export LANG=fr_CA را در فایل .bash_profile خود قرار میدهد. او همچنین سطر source ~/.bashrc را در همان فایل میگذارد، و سپس set +o histexpand را در فایل .bashrc خودش قرار میدهد. اکنون از طریق کنسول به این سیستم دبیان متصل میشود. login(1) (از طریق PAM) فایل /etc/environment را میخواند و LANG=en_US را در محیط قرار میدهد. سپس login پوسته bash را اجرا میکند، که فایل /etc/profile و .bash_profile را میخواند. فرمان export در فایل .bash_profile موجب میگردد متغیر محیط LANG از en_US به fr_CA تغییر کند. عاقبت، فرمان source باعث میشود bash فایل .bashrc را بخواند، به طوری که فرمان set +o histexpand برای این پوسته اجرا میشود. بعد از تمام اینها، pierre اعلان فرمان خود را به دست میآورد و آماده تایپ دستورات به صورت محاورهای میباشد.
حالا اجازه بدهید به دومین مثال ساده بپردازیم: یک لاگین ssh. این مورد بسیار مشابه اتصال از طریق کنسول متنی میباشد، به استثنای آن که به جای استفاده از برنامه getty و login برای اداره خوشآمد گویی اولیه و تصدیق اعتبار کلمه عبور، برنامه sshd(8) آن را اداره میکند. sshd در دبیان به PAM نیز پیوند شده، و فایل /etc/pam.d/ssh را(به جای /etc/pam.d/login) خواهد خواند. و گر نه، اداره کردن همانطور است. وقتی که sshd به سرعت مراحل PAM را طی کرده است( اگر در سیستم شما قابل اجرا باشد)، bash را به عنوان پوسته لاگین اجرا میکند، که باعث خواندن /etc/profile و سپس یکی از فایلهای .bash_profile یا .bash_login یا .profile میگردد.
تفاوت اصل موقعی که یک پوسته لاگین راه دور به جای لاگین کنسول محلی استفاده میکنید آن است که، یک پردازش سرویسگیرنده ssh در سیستم محلی شما( یا هر جایی که شما از آن ssh نمودهاید) در حال اجرا است که متغیرهای محیط خودش را از قبل دارد -- و شاید برخی از آنها به sshd روی سیستمی که شما در حال اتصال به آن هستید، فرستاده شده باشند. مخصوصاً، برای متغیرهای LANG و LC_* مطلوب است توسط پوسته راه دور محافظت بشوند. متأسفانه، فایلهای پیکربندی روی سرویسدهنده ممکن است آنها را باطل کنند. به دست آوردن این تنظیم برای کار کردن صحیح در تمام وضعیتها مهارتآمیز است. (این یک نمونه فرایند برای دبیان است.)
Bash دارای یک گزینه ویژه زمان کامپایل میباشد که باعث خواهد شد در نشستهای ssh غیر محاورهای بدون لاگین فایل .bashrc منبع بشود(مترجم: یعنی آن را بخواند و در محیط جاری اجرا کند.). این ویژگی فقط توسط برخی ازفروشندگان سیستمعامل فعال میشود (اکثر توزیع کنندگان لینوکس). این گزینه در یک Bash ساخته شده پیشفرض نگهدارنده اصلی فعال نیست، و (بر اساس تجربه) در OpenBSD هم نیست.
اگر این ویژگی روی سیستم شما فعال شده باشد، Bash تشخیص میدهد که SSH_CLIENT یا SSH_CLIENT2 در محیط است و در این حالت فایل .bashrc را منبع میکند. برای مثال فرض کنید شما سطر var=foo را در فایل .bashrc راه دور خود دارید و این را ssh remotehost echo \$var را انجام میدهید، foo را چاپ خواهد نمود.
این پوسته غیر محاورهای است، بنابراین اگر شما نمیخواهید موارد .bashrc به این طریق اجرا بشوند میتوانید $- یا $PS1 را بررسی کنید.
بدون این گزینه bash بررسی خواهد نمود که اگر stdin به یک سوکت وصل شده است در این حالت نیز .bashrc را منبع میکند، اما اگر شما از یک سرویسدهنده openssh جدید(>5.0) استفاده کنید این بررسی ناموفق میشود، که احتمالاً شما این مورد را فقط درسیستمهای قدیمیتر مشاهده میکنید.
توجه نمایید که یک بررسی روی SHLVL نیز انجام میشود، بنابراین اگر ssh remotehost bash -c echo را انجام بدهید، آنوقت اولین bash فایل .bashrc را منبع میکند، اما دومی خیر(آن bash صریح در سطر فرمان که echo را اجرا میکند).
بیایید فرض کنیم pierre (کاربر کنسول ما) تصمیم میگیرد که برای مدتی X را راهاندای کند. او startx را تایپ میکند، که هر یک از مجموعه سرویس گیرندههای X که او میپسندد را فراخوانی میکند. startx یک روکش پیرامون xinit است، که سرویسدهنده X را راهاندازی میکند، و سپس به سرعت فایل .xinitrc یا .xsession (هر یک که موجود باشد) کاربر pierre، یا در غیر اینصورت Xsession پیشفرض عمومی سیستم را مرور میکند. اجازه بدهید فرض کنیم pierre دارای فرمان exec fluxbox (و هیچ چیز دیگر) در این فایل .xsession میباشد. وقتی سیاهی از بین میرود، او یک پردازش در حال اجرای سرویسدهنده X (به عنوان root)، و یک پردازش fluxbox (به عنوان pierre) دارد. fluxbox به عنوان فرزند xinit ایجاد شده، که فرزند startx بود، که یک فرزند bash بود، چنانکه LANG pierre و سایر متغیرهای محیط را ارث میبرد. موقعی که pierre موردی را از منوی مدیر پنجره راهاندازی میکند، آن فرمان جدید یک فرزند fluxbox خواهد بود، چنانکه به همان اندازه LANG، PATH، MAIL، وغیره را ارث میبرد. علاوه بر تمام آنها، fluxbox متغیر محیط DISPLAY را که به او میگوید کدام سرویسدهنده X متصل است را به ارث میبرد(در این حالت، احتمالاً :0).
پس موقعی که pierre یک xterm را اجرا میکند، چه رخ میدهد؟ fluxbox یک پردازش xterm را "fork" و "exec" میکند، که DISPLAY ومانند آن را ارث میبرد. xterm به سرویسدهنده X متصل میشود، اگر لازم باشد اعتبارسنجی میشود، و سپس خودش را در نمایشگر رسم میکند. علاوه بر DISPLAY، از متغیر SHELL کاربر pierre که احتمالاً شامل /bin/bash است ارث میبرد، بنابراین یک شِبه-ترمینال برقرار میکند، و آنوقت یک پردازش /bin/bash برای اجرا در آن تولید میکند. چون /bin/bash با یک - شروع نشده است، یک پوسته لاگین نخواهد بود.یک پوسته معمولی خواهد بود که فایل /etc/profile یا .bash_profile یا .profile را نخواهد خواند. به جای آن،فایل .bashrc که در مثال ما محتوی سطر set +o histexpand میباشد را میخواند. بنابراین xterm جدید او در حال اجرای یک پوشته bash، با تمام مجموعه متغیرهای محیط او میباشد(به خاطر بیاورید، آنها از پوسته لاگین کنسول متنی اولیه او به ارث رسیدهاند)، و گزینش انتخابی پوستهاش فعال شده است(از فایل .bashrc).
آنچه تا اینجا دیدهایم، تنظیم عادی یونیکس است. بسیاری اشخاص راهاندازی سیستمهایشان به این طریق را انتخاب میکنند، و به خوبی کار میکند. همچنین یک دفعه که مفاهیم اصلی را نشان داده باشید، به طور مساعدی برای فهمیدن ساده است. اگر بخواهید موردی را تغییر بدهید، به طور دقیق میدانید کدام فایل را برای تحقق آن ویرایش کنید -- مستعارها و گزینههای موقتی پوسته در .bashrc، و برای متغیرهای محیط، محدودیتهای فرایند، و مانند آن فایل .bash_profile را ویرایش کنید. اگر میخواهید قبل از اینکه مدیر پنجره یا محیط میز کارتان فراخوانی بشود، فرمانهای مختلف سرویسگیرنده X اجرا بشود( به عنوان مثال، xterm & یا xmodmap -e 'keysym Super_R = Multi_key')، میتوانید آنها را درفایل .xsession قبل از سطر exec YourWindowManager قرار بدهید.
به هر حال بعضی اشخاص دوست دارند یک لاگین گرافیکی(مدیر نمایش) داشته باشند، و این هر چیزی را که تا اینجا دیدهایم تغییر میدهد. به جای getty و login، یک پردازش اداره اعتبارسنجی xdm (یا gdm یا kdm یا wdm یا ...) وجو دارد. و بزرگترین تفاوت همگی آن است که وقتی پردازش *dm ما اعتبار سنجی کاربر را به پایان میرساند، یک پوسته لاگین "exec" نمیکند. به جای آن، مستقیماً یک نشست X را "exec" میکند. بنابراین، ابداً هیچ کدام از فایلهای پیکربندی کاربر خوانده نمیشوند -- نه /etc/profile، نه .bash_profile و نه .profile. (اما /etc/environment باز هم بواسطه PAM خواند میشود، /etc/pam.d/*dm برای به کار بردن محدودیتهای pam پیکربندی میشود، حالتی که در دبیان است.)
اجازه بدهید xdm را به عنوان یک مثال در نظر بگیریم. Pierre یک روز بعد از مرخصی باز میگردد و پی میبرد مدیر سیستم او xdm را روی سیستم دبیان نصب کرده است. او خیلی خوب به سیستم متصل میشود و xdm فایل .xsession او را میخواند و fluxbox را اجرا میکند.به نظر میرسد همه چیز درست است تا آنکه یک پیغام خطا با زبان منطقه اشتباه دریافت میکند! چون متغیر LANG در فایل .bash_profile او باطل میشود، و از آنجایی کهxdm هرگز فایل .bash_profile را نمیخواند، متغیر LANG او اکنون به جای fr_CA به en_US تنظیم گردید است.
حال، راه حل خام برای این مشکل آن است که به جای راهاندازی xterm، او میتواند مدیر پنجره خود را برای راهاندازی xterm -ls پیکربندی نماید. این نشانه به xterm میگوید که به جای راهاندازی یک پوسته معمولی، باید یک پوسته لاگین اجرا کند. تحت این تنظیم، xterm یک /bin/bash تولید میکند، اما -/bin/bash (یا شاید -bash) را در حامل شناسه میگذارد، چنانکه bash مانند یک پوسته لاگین عمل میکند. این به معنای آن است که هر دفعه که او xterm جدیدی باز میکند، فایل /etc/profile و .bash_profile را خواهد خواند(رفتار داخلی bash ) ، و سپس .bashrc را (زیرافایل .bash_profile او میگوید که این کار را انجام بدهد). ممکن است ابتدا به نظر برسد که این مورد به خوبی کار میکند -- فایلهای نقطهای او سنگین نیستند، بنابراین هرگز متوجه تأخیر نمیشود -- اما مسئله محیلتری وجود دارد. او همچنین یک مرورگر وب را مستقیماً از منوی fluxbox اجرا میکند، و مرورگرش متغیر LANG را از fluxbox ارث میبرد، که بازهم به منطقه اشتباه تنظیم میباشد. بنابراین در حالیکه شاید xterm هایش خوب باشند، و هر موردی که از xterm هایش راهاندازی شود ممکن است خوب باشد، مرورگر وب بازهم صفحهها را با زبان منطقه اشتباه به او میدهد.
بنابراین، بهترین راه حل برای این مشکل چیست؟ واقعاً یک راه حل همگانی وجود ندارد. یک راهکار ویرایش فایل .xsession به موردی مانند این است:
[ -r /etc/profile ] && source /etc/profile [ -r ~/.bash_profile ] && source ~/.bash_profile xmodmap -e 'keysym Super_R = Multi_key' xterm & exec fluxbox
این باعث میشود پوستهای که اسکریپت .xsession را تفسیر میکند، اگر فایلهای /etc/profile و .bash_profile موجود و قابل خواندن باشند، قبل از اجرای xmodmap یا xterm یا اجرای مدیر پنجره، آنها را بخواند. به هر حال، یک اشکال بالقوه در این راهکار وجود دارد: تحت xdm، پوستهای که .xsession را میخواند بدون یک کنترل ترمینال اجرا میشود. اگر یکی از فایلهای /etc/profile یا .bash_profile هر فرمانی را استفاده نماید که وجود یک ترمینال را فرض میکند(از قبیل fortune یا stty)، آن فرمان ممکن است ناموفق گردد. این است دلیل اصلی آنکه چرا xdm به طور پیشفرض آن فایلها را نمیخواند. اگر تصمیم دارید از این راهکار استفاده کنید، باید مطمئن شوید که تمام فرمانها در فایلهای نقطهای شما، وقتی ترمینال وجود ندارد مصون میباشند.
یک روش برای انجام آن، اما بازهم از دست ندادن آن فرمانها برای استفاده موقعی که با ssh لاگین میکنید،محافظت ازبلوکهای مناسب کد با یک جمله if است. برای مثال:
## Sample .bash_profile
export PATH=$HOME/bin:$PATH
export MAIL=$HOME/Maildir/
export LESS=-X
export EDITOR=vim VISUAL=vim
export LANG=fr_CA
# Begin protected block
if [ -t 0 ]; then # check for a terminal
[ x"$TERM" = x"wy30" ] && stty erase ^h # sample legacy environment
echo "Welcome to Debian, $LOGNAME"
/usr/games/fortune
fi
# End protected block
[ -r ~/.bashrc ] && source ~/.bashrc
متأسفانه، سایر برنامههای مدیر نمایش (kdm، gdm، و غیره) همگی همان فایلهای پیکربندی را به کار نمیبرند که xdm استفاده میکند. بنابراین شاید این رویکرد برای آنها کار نکند. ممکن است لازم باشد شما مستندات برنامه مدیر نمایش خود را کنکاش کنید، که پی ببرید کدام فایلها را باید برای کنترل نشستهای خود استفاده کنید.
فایلهای نقطهای (آخرین ویرایش 2011-04-21 19:06:11 توسط ppp-94-64-90-90)
مترجم: Pluggable Authentication Modules: مدولهای تصدیق اعتبار قابل تعویض کاربر برای امنیت سیستم. یک مجموعه کتابخانههای مشترک که تعین میکند کاربر چگونه اعتبار سنجی خواهد شد، به عنوان مثال، مطابق قرارداد یونیکس کاربران پس از تایپ نام کاربری خود در اعلان login با عرضه نمودن یک کلمه عبور در اعلان password خودشان را تصدیق اعتبار میکنند. در بسیاری از رویدادها از قبیل دسترسی داخلی به یک ایستگاه کاری این شکل اعتبار سنجی کافی در نظر گرفته شده است. در سایر حالتها اطلاعات بیشتری لازم میشود. اگر کاربری از یک منبع خارجی مانند اینترنت به سیستم داخلی متصل گردد، ممکن است اطلاعات بیشتر یا متناوبی لازم بشود، شاید یک کلمه عبور یکبار مصرف. PAM اینگونه توانایی و خیلی بیشتر را فراهم میکند. مهمتر از همه مدولهای pam به شما اجازه میدهند محیط خود را برای سطوح مختلف امنیتی پیکربندی کنید. (بازگشت)