تاریخچه دستورات (Command History) در Bash: history، HISTFILE، HISTSIZE و HISTCONTROL
تاریخچه دستورات (Command History) یکی از قابلیتهای کلیدی Bash است که تمام دستورات واردشده در شل را ذخیره میکند. این ویژگی نهتنها به شما امکان بازبینی کارهای قبلی را میدهد، بلکه با استفاده از میانبرهای هوشمند، سرعت کار با خط فرمان را به طرز چشمگیری افزایش میدهد. در این درس، با دستور اصلی history و متغیرهای محیطی کنترلکننده آن آشنا میشوید.
دستور history
دستور history، لیست دستورات ذخیرهشده در حافظه جاری شل (In-Memory History) را نمایش میدهد.
سینتکس پایه:
history
خروجی نمونه (هر خط شامل یک شماره و خود دستور است):
1 ls 2 cd /etc 3 vim ~/.bashrc 4 history
گزینههای پرکاربرد history
| گزینه | توضیح |
|---|---|
-c | پاک کردن تمام تاریخچه ذخیرهشده در حافظه جاری (نه فایل) |
-d <شماره> | حذف یک خط خاص از تاریخچه با استفاده از شماره آن |
-a | افزودن دستورات جدید تاریخچه جاری به انتهای فایل تاریخچه (HISTFILE) |
-w | نوشتن کل تاریخچه جاری در فایل تاریخچه (بازنویسی کامل فایل) |
-r | خواندن محتوای فایل تاریخچه و افزودن آن به تاریخچه جاری |
مثالها:
# حذف دستور شماره 5 از تاریخچه جاری history -d 5 # نوشتن تاریخچه جاری در فایل (معمولاً ~/.bash_history) و بازنویسی آن history -w
نکته حرفهای: برای اجرای مجدد یک دستور خاص از تاریخچه، از علامت
!استفاده کنید. مثلاً!123دستور شماره ۱۲۳ را اجرا میکند و!!آخرین دستور اجراشده را تکرار میکند.
متغیر HISTFILE (مسیر فایل تاریخچه)
این متغیر، مسیر فایلی را مشخص میکند که تاریخچه دستورات بهصورت دائمی در آن ذخیره میشود.
مشاهده مقدار پیشفرض:
echo $HISTFILE
خروجی نمونه:
/home/username/.bash_history
نکات کلیدی:
-
بهطور پیشفرض، فایل تاریخچه در دایرکتوری خانه کاربر با نام
.bash_historyذخیره میشود. -
هنگام خروج از شل (با دستور
exitیا بستن ترمینال)، محتوای تاریخچه حافظه به این فایل افزوده (Append) میشود. -
اگر مسیر این فایل را تغییر دهید، تاریخچه در مکان جدید ذخیره خواهد شد:
export HISTFILE="$HOME/.my_custom_history"
متغیر HISTSIZE (تعداد دستورات در حافظه)
این متغیر تعیین میکند که چند دستور آخر در حافظه شل جاری (RAM) نگهداری شوند.
مشاهده مقدار پیشفرض:
echo $HISTSIZE
خروجی معمولاً 1000 یا 500 است.
تغییر مقدار (موقت):
export HISTSIZE=2000
توجه: این متغیر فقط اندازه حافظه موقت را کنترل میکند و بر تعداد دستورات ذخیرهشده در فایل (دیسک) تأثیری ندارد. برای کنترل تعداد دستورات ذخیرهشده در فایل، از متغیر
HISTFILESIZEاستفاده میشود که معمولاً همان مقدارHISTSIZEیا بیشتر تنظیم میشود.
متغیر HISTCONTROL (کنترل محتوای تاریخچه)
این متغیر، مهمترین ابزار برای مدیریت نحوه ذخیرهسازی دستورات است و از ورود دستورات تکراری، بیمحتوا یا حساس به تاریخچه جلوگیری میکند.
مقادیر قابل قبول برای HISTCONTROL
| مقدار | رفتار |
|---|---|
ignorespace | دستوراتی که با فاصله (Space) شروع میشوند، در تاریخچه ذخیره نمیشوند. |
ignoredups | اگر دستور جدید، دقیقاً برابر با آخرین دستور ذخیرهشده باشد، ذخیره نمیشود. |
ignoreboth | ترکیبی از دو حالت بالا (ignorespace + ignoredups). |
erasedups | تمام تکرارهای قبلی (در کل تاریخچه) آن دستور خاص را پاک میکند و سپس دستور جدید را ذخیره میکند. |
مثالهای عملی
۱. استفاده از ignorespace (مخفیسازی پسوردها)
فرض کنید باید دستوری با رمز عبور صریح اجرا کنید. با قراردادن یک فاصله در ابتدای دستور، آن را از تاریخچه حذف کنید:
# این دستور در تاریخچه ذخیره نمیشود (چون با فاصله شروع شده است) mysql -u root -pMySecretPassword
سپس متغیر را بهصورت زیر تنظیم کنید:
export HISTCONTROL=ignorespace
۲. استفاده از ignoredups (حذف تکرارهای پشت سر هم)
اگر مکرراً یک دستور را تکرار میکنید (مثلاً ls)، فقط یک بار در تاریخچه ذخیره میشود:
export HISTCONTROL=ignoredups ls ls # این خط دوم ذخیره نمیشود چون دقیقاً برابر با آخرین دستور است
۳. استفاده از erasedups (حذف کلیه تکرارها)
این گزینه قدرتمند، تمام رخدادهای قبلی یک دستور را از تاریخچه پاک میکند و فقط آخرین اجرا را نگه میدارد:
export HISTCONTROL=erasedups cd /tmp cd /var cd /tmp # این دستور اجرا شد؛ حالا /tmp قبلی (خط اول) پاک میشود و فقط این یکی میماند
۴. مقدار پیشنهادی برای اکثر کاربران
export HISTCONTROL=ignoreboth
این تنظیمات باعث میشود هم دستورات تکراری پشت سر هم حذف شوند و هم دستورات شروعشونده با فاصله ذخیره نشوند.
تنظیمات پایدار (Persistent Configuration)
برای اینکه تغییرات متغیرهای بالا پس از بستن ترمینال نیز باقی بمانند، آنها را به فایل ~/.bashrc اضافه کنید:
# تنظیمات تاریخچه export HISTSIZE=5000 export HISTFILESIZE=10000 export HISTFILE="$HOME/.bash_history" export HISTCONTROL=ignoreboth # (اختیاری) افزودن زمانامضاء به تاریخچه export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "
پس از ذخیره فایل، با دستور زیر اعمال کنید:
source ~/.bashrc
نکته حرفهای: متغیر
HISTTIMEFORMATدر لیست سؤال نبود اما یک مکمل حیاتی است. با تنظیم آن، خروجیhistoryبههمراه تاریخ و زمان دقیق اجرای هر دستور نمایش داده میشود.
جستجو و استفاده مجدد از تاریخچه
نیازی به شمارهگذاری و تایپ دستی !123 همیشه نیست. دو روش کارآمدتر:
۱. جستجوی معکوس (Reverse Search) با Ctrl+R
-
کلیدهای
Ctrl + Rرا بزنید. -
شروع به تایپ بخشی از دستور مدنظر کنید.
-
Bash بهصورت پویا آخرین دستور منطبق را نمایش میدهد.
-
برای رفتن به دستورات قدیمیتر، دوباره
Ctrl+Rرا بزنید. -
با
Enterاجرا کنید یا باEscیاCtrl+Gاز جستجو خارج شوید.
۲. میانبرهای سریع (!)
| میانبر | عملکرد |
|---|---|
!! | تکرار آخرین دستور اجراشده |
!$ | استفاده از آخرین آرگومان دستور قبلی |
!^ | استفاده از اولین آرگومان دستور قبلی |
!string | اجرای آخرین دستوری که با string شروع میشود |
!?string | اجرای آخرین دستوری که شامل string است |
مثال کاربردی برای !$:
mkdir my_project cd !$ # معادل cd my_project است
هشدار امنیتی مهم
فایل تاریخچه (.bash_history) یک فایل متنی ساده است و تمام دستورات شما را در خود ذخیره میکند.
-
هرگز دستوراتی که شامل رمز عبور صریح، توکنهای API، یا کلیدهای خصوصی هستند را بدون پیشوند
spaceاجرا نکنید. -
در محیطهای اشتراکی، از
history -cبرای پاک کردن حافظه قبل از خروج استفاده کنید. -
برای پاک کردن کامل یک خط خاص از فایل روی دیسک، ابتدا آن را از حافظه حذف کنید (
history -d <number>) و سپس تاریخچه را روی دیسک بازنویسی کنید (history -w).
راهکار امنیتی: دستور زیر را بهعنوان یک Alias یا تابع تعریف کنید تا بهسرعت آخرین دستور حساس را از تاریخچه پاک کنید:
alias histdel='history -d $(history 1 | awk "{print \$1}")'(این دستور، آخرین خط تاریخچه را حذف میکند).