درس آموزشی درس ۲ از ۵

ترمینال لینوکس چیست؟ آموزش Bash و خط فرمان از صفر با تمرین عملی

تازه ترمینال لینوکس رو باز کردی و نمی‌دونی از کجا شروع کنی؟ با یک پروژه زیرنویس، Bash، مسیرها، فایل‌ها و خطاهای رایج رو قدم‌به‌قدم یاد بگیر.

مقدماتی ۲۹ دقیقه مطالعه بروزرسانی ۲۳ مهر ۱۴۰۵
فهرست این درس

ببین، وقتی اولین‌بار ترمینال لینوکس رو باز می‌کنی، احتمالاً یه پنجره ساده می‌بینی که فقط چند کلمه و یه نشانگر چشمک‌زن داره. ممکنه بپرسی وقتی می‌شه با ماوس کار کرد، چرا باید دستور تایپ کنم؟ چون بعضی کارها رو می‌تونی با چند کلمه دقیق‌تر انجام بدی؛ مخصوصاً وقتی پای تعداد زیادی فایل، سرور یا کارهای تکراری وسط باشه. ترمینال ابزار عجیب هکرها نیست، یه روش دیگه برای کار کردن با سیستمه.

توی این آموزش ترمینال لینوکس قرار نیست یه عالمه دستور بی‌ربط رو حفظ کنی. یه گروه فرضی داره زیرنویس ویدیوهای آموزشی رو آماده می‌کنه و ما باید فایل‌هایی رو که هنوز تأیید نشدن جدا کنیم. قدم‌به‌قدم همین مسئله رو حل می‌کنیم و توی مسیر، تفاوت ترمینال و Bash، مسیر فایل‌ها، ورودی و خروجی دستورها و تشخیص خطا رو یاد می‌گیریم. همه‌چیز داخل یه پوشه تمرینی توی حساب خودت انجام می‌شه؛ نه sudo می‌خوایم، نه به فایل‌های سیستم دست می‌زنیم.

اگه دنبال آموزش لینوکس برای مبتدیان هستی، اول از پایه‌ها شروع کن؛ مخصوصاً اگه هنوز تفاوت لینوکس، اوبونتو و توزیع رو نمی‌دونی، اول درس «لینوکس چیست؟» رو بخون. این درس قدم دوم مسیر آموزش Linux Essentials هست؛ یعنی فرض می‌کنیم یک توزیع لینوکس یا محیط سازگار با اون در اختیار داری و می‌خوای اولین تجربه درستت رو در خط فرمان بسازی.

ترمینال لینوکس

ترمینال لینوکس چیست و چرا هنوز استفاده می‌شود؟

اول جواب «ترمینال لینوکس چیست؟» رو روشن کنیم. چیزی که معمولاً بهش ترمینال می‌گیم یه برنامه‌ست که متن دستور رو می‌گیره و نتیجه رو نشون می‌ده. این پنجره خودش همه کارها رو انجام نمی‌ده؛ شل و برنامه‌هایی که اجرا می‌شن بخش اصلی کار رو پیش می‌برن.

مزیتش هم فقط سریع‌تر بودن از کلیک کردن نیست؛ می‌تونی چند فرمان رو کنار هم بذاری، خروجی یکی رو به بعدی بدی و یه کار قابل تکرار بسازی. برای همین توی سرور و توسعه نرم‌افزار زیاد می‌بینیش.

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

تفاوت Terminal، Shell، Bash و CLI دقیقاً چیه؟

اینجا معمولاً اسم چهار چیز رو قاطی می‌کنیم: Terminal، Shell، Bash و CLI. تفاوت شل و ترمینال اینه که ترمینال محیط گفت‌وگوی متنی رو فراهم می‌کنه، اما شل دستور رو می‌فهمه و اجراش می‌کنه. Shell چیست؟ یه برنامه برای تفسیر فرمان‌ها. Bash چیست؟ یکی از همین شل‌ها که برای نوشتن اسکریپت هم به کار می‌ره. CLI هم به‌طور کلی یعنی رابط خط فرمان. پس می‌تونی توی یک ترمینال از Bash یا Zsh استفاده کنی، بدون اینکه ظاهر پنجره خیلی فرق کنه.

اصطلاحمعنی سادهنمونه یا نکته
Terminalمحیطی برای وارد کردن دستور و دیدن نتیجهGNOME Terminal یا Konsole
Shellتفسیرکننده و اجراکننده فرمان‌هاBash و Zsh
Bashیک شل مشخص و زبان اسکریپت‌نویسیفرمان داخلی cd و قواعد نقل‌قول‌ها
CLIشیوه تعامل با برنامه از راه متناجرای یک برنامه با گزینه‌ها و آرگومان‌ها
Promptبخشی از نمایش که آماده دریافت دستورهممکن است با $ تمام شود

برای تصور بهتر، فرض کن داری به مسئول آرشیو می‌گی «فایل‌های نیازمند بازبینی رو پیدا کن». صفحه گفت‌وگو نقش ترمینال لینوکس رو داره، کسی که درخواستت رو می‌فهمه نقش شل رو بازی می‌کنه و خود عملیات پیدا کردن فایل‌ها توسط فرمان‌ها یا برنامه‌های مربوط انجام می‌شه. این فقط یک تشبیه برای جدا کردن مفهوم‌هاست، نه شرح فنی دقیق فرایندهای سیستم‌عامل؛ در عمل شل برنامه‌ها رو با قواعد مشخص اجرا می‌کنه و خروجی و وضعیت برگشتشون رو دریافت می‌کنه.

برای آموزش ترمینال لینوکس به چه محیطی نیاز داریم؟

برای آموزش ترمینال اوبونتو یا هر توزیع دیگه، فقط یه محیط لینوکسی با Bash لازم داریم. می‌تونی از لینوکس نصب‌شده روی کامپیوتر، ماشین مجازی یا WSL استفاده کنی. توی خیلی از دسکتاپ‌های اوبونتو با Ctrl+Alt+T ترمینال باز می‌شه؛ البته بسته به تنظیمات ممکنه میان‌بر فرق داشته باشه. روی Mint یا Fedora هم دنبال برنامه Terminal بگرد. اسم و ظاهرش مهم نیست، مهم اینه که فرمان‌ها رو داخل محیط درست اجرا کنی.

اگه سیستم اصلیت ویندوزه، لازم نیست برای یادگیری لینوکس پاکش کنی. با WSL یا ماشین مجازی می‌تونی یه محیط لینوکسی داشته باشی و تمرین کنی. فقط حواست باشه PowerShell و Command Prompt همون Bash نیستن؛ فرمان‌های این درس رو داخل شل توزیع لینوکسی اجرا کن. روی macOS هم Terminal داری، ولی شل پیش‌فرض اغلب Zshـه و بعضی ابزارها یا گزینه‌ها با نسخه GNU در لینوکس فرق دارن.

قبل از هر کاری، محیط فعلی رو بشناس

اول ترمینال لینوکس رو باز کن و این چند فرمان رو یکی‌یکی وارد کن. علامت‌هایی مثل $ که ممکنه سمت چپ Prompt ببینی جزو دستور نیستن؛ قرار نیست اون‌ها رو تایپ کنی. هر فرمان رو بنویس و Enter بزن.

whoami
pwd
printf 'HOME=%s\n' "$HOME"
printf 'SHELL=%s\n' "$SHELL"
command -v bash

ببین هرکدوم از فرمان‌های بالا چی گفتن: whoami نام کاربر فعلی رو چاپ می‌کنه و pwd می‌گه توی کدوم پوشه‌ای. مقدار $HOME معمولاً آدرس پوشه خانگیه، اما $SHELL بیشتر شل تنظیم‌شده برای ورود کاربر رو نشون می‌ده؛ لزوماً شلی که همین لحظه داخلش هستی نیست. اگه می‌خوای مطمئن بشی تمرین‌ها با Bash جلو می‌رن، توی همون محیط لینوکسی bash رو اجرا کن و آخر کار با exit برگرد. دستور command -v bash هم فقط پیدا شدن Bash رو بررسی می‌کنه.

خط فرمان لینوکس چطور دستورها رو اجرا می‌کنه؟

حتی اگر با اسم انگلیسی Linux Terminal بهش برخورد کردی، منظور همین محیط دستوره. توی خیلی از محیط‌ها یه چیزی شبیه student@laptop:~$ می‌بینی. بخش اول معمولاً اسم کاربره، بخش دوم اسم دستگاه و ~ نشون می‌ده توی پوشه خانگی هستی. اما Prompt قابل شخصی‌سازیه؛ پس اگه شکلش با آموزش فرق داشت، فوراً نتیجه نگیر مشکلی پیش اومده. علامت‌های $ یا # هم به‌تنهایی مدرک قطعی سطح دسترسی نیستن.

بیا یه دستور رو تکه‌تکه کنیم: ls -la /tmp. اینجا ls اسم فرمانه، -la گزینه‌هاش هستن و /tmp مسیریه که می‌خوای فهرستش رو ببینی. شل قبل از اجرا متن رو طبق قواعد خودش تفسیر می‌کنه؛ برای همین فاصله، نقل‌قول یا علامت‌های خاص گاهی معنی دستور رو عوض می‌کنن. توی آموزش خط فرمان لینوکس همین دقت به جزئیات خیلی مهم‌تر از حفظ کردن دستورهای طولانیه.

بخش فرماننقشمثال
نام فرمانمشخص می‌کند چه عملی انجام شودls
گزینه یا Optionرفتار فرمان را تغییر می‌دهد-l یا -a
آرگومانداده یا مسیری که فرمان روی آن کار می‌کند/tmp
خروجی استانداردنتیجه معمول عملیاتفهرست فایل‌ها
خطای استانداردپیام‌های خطا و هشدارNo such file or directory
کد خروجوضعیت پایان فرمانصفر یا غیرصفر

یک فرق کوچک اما مهم وجود داره : همه دستورهایی که در ترمینال لینوکس می‌زنی برنامه مستقل روی دیسک نیستن. بعضی مثل cd فرمان داخلی یا Builtin شل هستن، چون باید محل کاری همون نشست شل رو تغییر بدن. بعضی مثل ls معمولاً یک برنامه اجرایی جداگانه هستن. اگر از همون اول این فرق رو بفهمی، بعدها با سؤال‌هایی مثل «چرا cd در اسکریپت روی ترمینال من اثر نداشت؟» کمتر سردرگم می‌شی.

پرونده عملی : یک آرشیو زیرنویس بسازیم

حالا بریم سراغ پروژه. یه گروه فرضی فایل‌های زیرنویس چند ویدیوی آموزشی رو بررسی می‌کنه و برای هر فایل وضعیت «تأیید شده» یا «نیازمند بازبینی» داره. می‌خوایم با دستورات اولیه لینوکس یه پوشه بسازیم، اطلاعات چند فایل رو ثبت کنیم و فقط موردهای نیازمند بازبینی رو بیرون بکشیم. این سناریو کاملاً ساختگیه، ولی خود دستورها واقعی هستن و می‌تونی نتیجه هر مرحله رو روی سیستم خودت بررسی کنی.

برای اینکه تمرین به اطلاعات شخصی یا فایل‌های سیستم دست نزنه، تمام کارها رو داخل ~/nabegheha-shell-lab انجام می‌دیم. هرجا در ادامه اسم فایلی رو می‌بینی، بدون که متعلق به همین فضای آزمایشیه. دستورهای این بخش به اینترنت وصل نمی‌شن و نیازی به دسترسی مدیر ندارن. بهتره فرمان‌ها رو به ترتیب اجرا کنی؛ چون خروجی هر مرحله ورودی مرحله بعدیه.

قدم اول : دستور cd در لینوکس و ساخت پوشه پروژه

mkdir -p "$HOME/nabegheha-shell-lab/inbox" "$HOME/nabegheha-shell-lab/review"
cd "$HOME/nabegheha-shell-lab"
pwd
ls -la

با mkdir -p پوشه‌های inbox و review رو ساختیم. بعد نوبت دستور cd در لینوکس بود تا وارد پوشه پروژه بشیم. دستور pwd در لینوکس هم همون لحظه مسیر فعلی رو نشون داد و ls -la محتویات پوشه رو نمایش داد. اگه همه‌چیز درست پیش رفته باشه، باید دو پوشه‌ای که ساختیم رو ببینی؛ البته ترتیب نمایش و مشخصات مالکیت روی سیستم تو ممکنه متفاوت باشه.

یه عادت خیلی مهم از همین قدم اول بساز: قبل از ایجاد، جابه‌جایی یا بازنویسی فایل‌ها، pwd رو بزن و ببین دقیقاً کجایی. خیلی وقت‌ها فرمان درست نوشته شده، ولی توی پوشه اشتباه اجرا شده. توی ترمینال لینوکس، فهمیدن مسیر فعلی نصف راه عیب‌یابیه.

قدم دوم : متن رو به فایل تبدیل کن

printf '%s\n' \
  'clip-01 | needs-check' \
  'clip-02 | approved' \
  'clip-03 | needs-check' > inbox/scenes.txt
cat inbox/scenes.txt

اینجا با printf سه خط متن ساختیم. به‌جای چاپ روی صفحه، با علامت > فرستادیمش داخل inbox/scenes.txt و بعد با cat خوندیمش. فقط این نکته رو جدی بگیر: > در حالت معمول، محتوای قبلی فایل مقصد رو جایگزین می‌کنه. توی آزمایش ما این کار عمدیه تا هر بار فایل نمونه از یه وضعیت مشخص شروع بشه؛ برای فایل مهم خودت این‌طور سرسری عمل نکن.

خروجی cat باید همین سه ردیف باشه. شماره‌ها و وضعیت‌ها داده واقعی هیچ شرکتی نیستن؛ صرفاً برچسب‌های تمرینی هستن. نکته ارزشمند این مرحله اینه که فرمان printf متن رو تولید کرده، شل با > مقصد رو تعیین کرده و cat فقط محتوا رو خونده. یعنی سه کار متفاوت با هم انجام شدن. وقتی این تقسیم مسئولیت رو بفهمی، کار با گزارش‌ها و خروجی برنامه‌ها خیلی راحت‌تر می‌شه.

clip-01 | needs-check
clip-02 | approved
clip-03 | needs-check

قدم سوم : فقط ردیف‌هایی رو پیدا کن که هنوز تأیید نشدن

grep -n 'needs-check' inbox/scenes.txt
grep -c 'needs-check' inbox/scenes.txt

برای جدا کردن فایل‌های نیازمند بررسی از grep کمک گرفتیم. گزینه -n شماره خط هر مورد رو هم نشون می‌ده و -c تعداد خط‌های مطابق رو حساب می‌کنه، نه تعداد تکرار عبارت داخل هر خط. پس باید دو مورد پیدا بشه. حواست باشه برنامه قرار نیست کیفیت زیرنویس رو تشخیص بده؛ فقط ردیف‌هایی رو پیدا می‌کنه که خودمون توشون needs-check نوشته‌ایم.

1:clip-01 | needs-check
3:clip-03 | needs-check
2

اینجا می‌تونی یک اشتباه معمول رو از همین حالا یاد بگیری : اگر یک نام در فایل با حروف بزرگ نوشته شده باشه و در الگوی جست‌وجو با حروف کوچک دنبالش بگردی، در حالت معمول ممکنه پیدا نشه. لینوکس و ابزارهای خط فرمان در خیلی از موقعیت‌ها نسبت به حروف بزرگ و کوچک حساسن. پس وقتی توی ترمینال لینوکس فرمانی «هیچی پیدا نمی‌کنه»، اول مطمئن شو داده و الگوی جست‌وجو دقیقاً با هم مطابقت دارن؛ قبل از اینکه فکر کنی ابزار خرابه.

قدم چهارم : خروجی یک فرمان رو به فایل تحویل بده

grep -n 'needs-check' inbox/scenes.txt > review/todo.txt
cat review/todo.txt
wc -l < review/todo.txt

با این سه فرمان، موارد نیازمند بازبینی رو توی review/todo.txt ذخیره کردی، فایل رو خوندی و تعداد خط‌هاش رو حساب کردی. wc -l خط‌ها رو می‌شمره و علامت < محتوای فایل رو به ورودی استانداردش می‌ده. اینجا اسم فایل معمولاً کنار تعداد چاپ نمی‌شه؛ چون داده از ورودی استاندارد اومده، نه از آرگومان نام فایل. این تفاوت کوچیک بعداً توی گزارش‌گیری حسابی به کارت میاد.

در این لحظه شاید حس کنی فقط چند فرمان ساده نوشتی؛ ولی در عمل یک جریان کار کوچک ساختی : ورودی خام، انتخاب داده، ساخت فایل خروجی و کنترل تعداد رکوردها. همین منطق پایه بعدها در تحلیل لاگ، اتوماسیون، پردازش فایل‌های CSV و گزارش‌گیری استفاده می‌شه. فعلاً لازم نیست سراغ اسکریپت‌نویسی حرفه‌ای بریم؛ مهم اینه که بدونی یک خروجی چطور تبدیل به ورودی مرحله بعد می‌شه.

قدم پنجم : وقتی یک صحنه جدید اضافه شد چه اتفاقی می‌افته؟

printf '%s\n' 'clip-04 | approved' >> inbox/scenes.txt
cat inbox/scenes.txt
grep -c 'needs-check' inbox/scenes.txt

اینجا >> رو داریم که با > فرق می‌کنه: متن جدید رو به آخر فایل اضافه می‌کنه، نه اینکه قبلی رو جایگزین کنه. بعد از افزودن clip-04 تعداد کل ردیف‌ها چهار تا می‌شه، ولی هنوز فقط دو ردیف needs-check داریم. یه نکته هم درباره فایل گزارش: review/todo.txt خودش خودکار آپدیت نمی‌شه. هر وقت داده ورودی عوض شد، برای گرفتن گزارش تازه باید فرمان تولید گزارش رو دوباره اجرا کنی.

قدم ششم : اگر نام فایل فاصله داشته باشد چه؟

printf '%s\n' 'first review' > 'review/team notes.txt'
cat 'review/team notes.txt'

عمداً اسم فایل رو team notes.txt گذاشتیم تا یه فاصله وسطش باشه. اگه مسیر رو بدون نقل‌قول وارد کنی، شل ممکنه اون رو چند آرگومان جدا بفهمه. با نوشتن 'review/team notes.txt' کل مسیر یه آرگومان می‌مونه. این همون چیزیه که موقع کار با فایل‌های واقعی نجاتت می‌ده: به‌جای حدس زدن، مسیر رو درست نقل‌قول‌گذاری کن.

مسیر مطلق، مسیر نسبی و علامت‌های / و ~ در لینوکس

یکی از دلیل‌های رایج خطا توی خط فرمان لینوکس اینه که نمی‌دونیم فرمان دنبال فایل می‌گرده کجا. مسیر مطلق و نسبی لینوکس رو با همین پروژه یاد بگیر: inbox/scenes.txt یه مسیر نسبیه و از پوشه فعلی حساب می‌شه؛ ولی مسیری که با / شروع بشه از ریشه فایل‌سیستم تفسیر می‌شه. پس ممکنه فایل سالم باشه، اما چون جای دیگه‌ای ایستادی، cat پیداش نکنه.

علامت ~ هم در Bash معمولاً به پوشه خانگی کاربر گسترش پیدا می‌کنه. این علامت با / یکی نیست؛ / ریشه فایل‌سیستمه، ولی خانه کاربر ممکنه مثلاً /home/student باشه. علامت . به پوشه فعلی و .. به پوشه والد اشاره می‌کنه. حالا تصور کن در review هستی و می‌خوای فایل پوشه inbox رو بخونی. می‌تونی اول یک سطح بالاتر بری یا مسیر نسبی رو با .. بسازی.

cd "$HOME/nabegheha-shell-lab/review"
pwd
cat ../inbox/scenes.txt
cd ..
pwd

با اجرای این فرمان‌ها اول وارد پوشه review می‌شی، فایل پوشه همسایه رو از طریق مسیر نسبی می‌خونی و بعد به ریشه پروژه برمی‌گردی. اگر با وجود تایپ درست فرمان، خطای «No such file or directory» دیدی، اولین سؤال باید این باشه : الان واقعاً کجا هستم؟ از همین‌جا می‌فهمیم چرا pwd فقط یک دستور مقدماتی نیست؛ ابزار تشخیص خطای خیلی از فرمان‌های دیگه‌ست.

نمادمعنینمونه در همین پروژه
/شروع مسیر مطلق از ریشه فایل‌سیستم/home/student
~پوشه خانگی کاربر در Bash~/nabegheha-shell-lab
.پوشه فعلی./inbox/scenes.txt
..پوشه والد../inbox/scenes.txt
$HOMEمتغیر محیطی مسیر خانه کاربر“$HOME/nabegheha-shell-lab”

چرا نام فایل با حروف بزرگ و کوچک فرق می‌کند؟

وقتی توی ترمینال لینوکس با فایل‌ها کار می‌کنی، روی خیلی از فایل‌سیستم‌ها، اسم Scenes.txt با scenes.txt فرق داره. این رفتار رو نباید بدون استثنا به هر فایل‌سیستم و هر شیوه اتصال نسبت بدیم، چون ممکنه فایل‌هایی روی یک فضای اشتراکی یا دیسک با رفتار متفاوت قرار داشته باشن. ولی برای تمرین لینوکسی بهتره دقیقاً همون حروفی رو وارد کنی که اسم فایل باهاش ساخته شده. همین دقت کوچک در اسکریپت‌های واقعی جلوی دردسرهای بزرگ‌تر رو می‌گیره.

آموزش لینوکس برای مبتدیان

آموزش Bash از صفر؛ Shell چطور دستورها رو می‌فهمه؟

تا اینجا دیدی که Bash فقط دستور رو به برنامه منتقل نمی‌کنه؛ قبلش متن رو تفسیر می‌کنه. توی این بخش از آموزش Bash از صفر با سه چیز کار داریم: نقل‌قول، متغیر و تغییر مسیر خروجی. هرکدوم از این‌ها می‌تونن معنی یه فرمان رو عوض کنن. پس وقتی فرمانی اون چیزی که انتظار داشتی رو انجام نداد، همیشه لازم نیست دنبال یه دستور جدید بگردی؛ شاید شل متن فعلی رو جور دیگه‌ای فهمیده باشه. از همین‌جا معلوم می‌شه چرا آموزش Bash فقط یاد گرفتن اسم چند فرمان نیست.

نقل‌قول تکی و دوتایی یکی نیستند

در Bash، نقل‌قول تکی معمولاً متن داخلش رو تقریباً بدون گسترش متغیر نگه می‌داره، ولی نقل‌قول دوتایی اجازه می‌ده متغیرهایی مثل $HOME گسترش پیدا کنن. این تفاوت رو با یک آزمایش ساده ببین :

printf '%s\n' '$HOME'
printf '%s\n' "$HOME"

خط اول باید متن $HOME رو عیناً چاپ کنه، اما خط دوم معمولاً مسیر واقعی خانه کاربر رو نشون می‌ده. این دقیقاً همون دلیلیه که وقتی در دستور ساخت پوشه از "$HOME/..." استفاده کردیم، متغیر باز شد و در عین حال مسیر به‌صورت یک آرگومان واحد باقی موند. در اسکریپت‌نویسی، نقل‌قول درست یکی از عادت‌های مهم برای جلوگیری از شکسته شدن نام فایل‌ها و تفسیر ناخواسته داده‌هاست.

متغیر محیطی و متغیر شل چه فرقی دارند؟

متغیر شل رو می‌تونی یه اسم برای نگه داشتن مقدار در نظر بگیری. مثلاً HOME معمولاً مسیر خونه کاربره و PATH به پیدا شدن برنامه‌های اجرایی کمک می‌کنه. اما هر متغیری که توی شل ساختی، خودکار به برنامه‌های فرزند منتقل نمی‌شه؛ معمولاً باید Export شده باشه. برای این درس فقط همین اندازه رو بدون که بعضی رفتارهای عجیب فرمان‌ها از مسیرها و تنظیمات محیط میاد، نه از خراب بودن برنامه.

printf 'Project=%s\n' "$HOME/nabegheha-shell-lab"
printf 'PATH=%s\n' "$PATH"
command -v ls

فرمان command -v کمک می‌کنه بفهمی نام یک دستور در محیط فعلی به چه چیزی ارجاع داده می‌شه. برای فرمانی مثل ls معمولاً مسیر فایل اجرایی رو می‌بینی؛ برای Builtinها ممکنه نوع دیگه‌ای از نتیجه بگیری. پس این ابزار از حدس زدن مسیر اجرای فرمان بهتره، ولی نباید هر خروجی اون رو لزوماً «آدرس یک فایل روی دیسک» فرض کنی.

تفاوت «دیدن نتیجه» با «ذخیره کردن نتیجه»

تا حالا بیشتر خروجی عادی رو دیدیم، ولی برنامه‌ها معمولاً سه جریان مهم دارن: ورودی استاندارد (stdin)، خروجی استاندارد (stdout) و خطای استاندارد (stderr). برای همین گاهی یه فرمان خطا می‌ده، اما پیامش داخل فایلی که با > ساخته‌ای نمیاد. توی مستندات، این سه جریان رو معمولاً کنار هم با اسم‌های stdin stdout stderr می‌بینی. توی مثال بعدی عمداً خطا می‌سازیم تا فرقشون رو ببینی.

نشانهکار اصلی در Bashاحتیاط
>نوشتن stdout در فایل و جایگزینی محتوای معمولمقصد را دوباره چک کن
>>افزودن stdout به انتهای فایلممکن است با اجرای تکراری داده تکرار شود
<دادن محتوای فایل به stdinبه‌معنای اجرای فایل نیست
2>نوشتن stderr در فایلصرفاً خطا را تغییر مسیر می‌دهد
|وصل کردن stdout فرمان اول به stdin فرمان بعدوضعیت خروج نیاز به دقت دارد

خطای عمدی بسازیم؛ اما فقط در محیط آزمایش

برای تمرینِ عیب‌یابی لازم نیست سیستم خراب کنیم. کافیه از فرمان cat بخوایم یک فایل نمونه‌ای رو بخونه که اصلاً ایجادش نکردیم. توجه کن این کد از اول برای ساختن خطای قابل کنترل نوشته شده، بنابراین اگر پیام خطا دیدی نشانه درست اجرا شدن آزمایش است.

cd "$HOME/nabegheha-shell-lab"
cat inbox/missing.txt 2> review/errors.log
printf 'exit=%s\n' "$?"
cat review/errors.log

اینجا عمداً خواستیم یه فایل ناموجود رو بخونیم. متن خطا با 2> رفت داخل review/errors.log و با $? وضعیت آخرین فرمان رو هم دیدیم. مقدار غیرصفر یعنی اون فرمان موفق نبوده؛ توی بعضی سیستم‌ها برای این آزمایش عدد 1 می‌بینی. یادت باشه $? همیشه وضعیت آخرین فرمانه؛ اگه بین خطا و بررسیش یه فرمان دیگه بزنی، نتیجه قبلی رو از دست می‌دی.

توی ترمینال لینوکس برای تشخیص خطا، این روال ساده رو داشته باش : اول «کد خروج» رو ببین، بعد «پیام خطا» رو بخون، بعد «پوشه جاری» و «مسیر مورد انتظار» رو بررسی کن. خیلی وقت‌ها تازه‌کارها از همون اول دستور رو با sudo تکرار می‌کنن تا شاید مشکل حل بشه؛ درحالی‌که اگر مسیر رو اشتباه نوشته باشی، دسترسی مدیر هیچ کمکی به پیدا شدن فایل نمی‌کنه و فقط دامنه خطر رو بزرگ‌تر می‌کنه.

آموزش Bash

Pipe در ترمینال لینوکس چیست و چرا مهمه؟

بعضی وقت‌ها اصلاً لازم نیست خروجی رو توی فایل ذخیره کنیم؛ می‌خوایم همون لحظه به یه فرمان دیگه بدیم. علامت | یا Pipe دقیقاً همین کار رو می‌کنه. توی مثال بعدی grep ردیف‌های موردنظر رو پیدا می‌کنه و wc -l تعدادشون رو می‌شمره. این دو برنامه کار خودشون رو انجام می‌دن، ولی با هم یه خروجی مفیدتر می‌سازن.

cd "$HOME/nabegheha-shell-lab"
grep 'needs-check' inbox/scenes.txt | wc -l

برای فایل نمونه باید عدد 2 ببینی. بااین‌حال چاپ شدن این عدد به این معنی نیست که همه مرحله‌های Pipe حتماً موفق بودن. توی Bash وضعیت خروج خط لوله به‌صورت پیش‌فرض از آخرین فرمان گرفته می‌شه، مگر اینکه تنظیمی مثل pipefail فعال باشه. فعلاً نیازی نیست تنظیمات شل رو عوض کنی؛ فقط یادت بمونه «خروجی دیدم» همیشه مساوی «همه‌چیز درست اجرا شد» نیست.

ترمینال لینوکس به این دلیل برای توسعه‌دهنده‌ها محبوبه که ابزارهای کوچک می‌تونن کنار هم قرار بگیرن و کار نسبتاً بزرگی بسازن. ولی همین انعطاف باعث می‌شه خطاها هم زنجیره‌ای بشن. از این به بعد، وقتی فرمانی چند بخش داشت، به‌جای حفظ کردن کل خط، از خودت بپرس هر بخش چه چیزی دریافت می‌کنه و چه چیزی تحویل می‌ده. این روش فهم دستورها خیلی ماندگارتر از کپی کردن فرمان‌های آماده از اینترنت خواهد بود.

میان‌برهای ترمینال لینوکس که واقعاً به کار میان

لازم نیست همین امروز همه میان‌برهای ترمینال لینوکس رو حفظ کنی. چند مورد واقعاً کاربردی‌ان: Tab معمولاً برای کامل کردن نام دستور یا مسیره، کلیدهای بالا و پایین تاریخچه فرمان‌ها رو نشون می‌دن و Ctrl+C معمولاً درخواست توقف برنامه جلوی دست رو می‌فرسته. Ctrl+L هم اغلب صفحه ترمینال رو مرتب می‌کنه، نه اینکه فایل‌ها رو پاک کنه. رفتار دقیق به شل، برنامه و تنظیمات بستگی داره.

میان‌بر یا فرمانکاربرد رایجنکته مهم
Tabکامل کردن نام دستور یا مسیرممکن است چند انتخاب نشان داده شود
↑ و ↓مرور تاریخچه فرمان‌هابه تنظیمات Shell وابسته است
Ctrl+Cدرخواست توقف برنامه جلوی دستهمیشه تضمین توقف فوری نیست
Ctrl+Lپاک‌سازی نمایش ترمینالفایل‌ها و فرمان‌های قبلی را حذف نمی‌کند
Ctrl+Dفرستادن EOF یا پایان ورودیدر شل خالی ممکن است نشست را ببندد
historyدیدن تاریخچه برخی فرمان‌ها در Bashمحتوای تاریخچه می‌تواند حساس باشد

یک موضوع امنیتی کوچک ولی جدی رو فراموش نکن : تاریخچه شل ممکنه فرمان‌های قبلی رو نگه داره. اگر رمز عبور، توکن API یا اطلاعات محرمانه رو مستقیم داخل یک فرمان بنویسی، بسته به تنظیمات، ممکنه در تاریخچه یا حتی در فهرست فرایندهای سیستم ردپا باقی بمونه. بنابراین از همون ابتدای آموزش خط فرمان لینوکس یاد بگیر داده حساس رو مثل یک متن معمولی وارد هر دستور نکنی و فرمان‌هایی که از منابع ناشناس کپی می‌کنی رو قبل از اجرا بفهمی.

چرا بعضی دستورها روی سیستم من جواب نمی‌دن؟

فرض کن دستور رو اجرا می‌کنی و پیام command not found میاد. قرار نیست فوری ده تا بسته نصب کنی یا تصور کنی لینوکس خراب شده. شاید اسم فرمان رو اشتباه نوشتی، برنامه نصب نیست، مسیرش توی PATH قرار نداره یا اصلاً داخل محیط متفاوتی هستی. توی آموزش ترمینال لینوکس می‌خوام اول دلیل رو پیدا کنی و بعد راه‌حل انتخاب کنی؛ نه اینکه برای هر خطا یه دستور ناشناس از اینترنت کپی کنی.

برای اینکه فرق «فرمان پیدا نشد» و «فرمان خطا داد» رو بفهمی، اول از command -v کمک بگیر. برای یادگیری استفاده از فرمان‌های رایج هم گزینه --help یا ابزار man گاهی اطلاعات مفیدی می‌ده؛ البته همه فرمان‌ها دقیقاً همین گزینه‌ها رو ندارن و صفحات راهنما در همه محیط‌ها نصب نیستن. یکی از مهم‌ترین تفاوت‌های یک کاربر باتجربه با مبتدی این نیست که همه گزینه‌ها رو از حفظه؛ بلکه می‌دونه وقتی چیزی رو فراموش کرد، از چه مرجعی و با چه سؤال مشخصی کمک بگیره.

پنج خطای پرتکرار و روش فکر کردن به آن‌ها

پنج خطای رایج رو می‌تونی با چند سؤال ساده بررسی کنی. فایل پیدا نشد؟ اول pwd و اسم فایل رو چک کن. Permission denied دیدی؟ ببین کدوم کاربر و کدوم مجوز درگیره. command not found اومد؟ نام فرمان و PATH رو بررسی کن. فایل دارای فاصله درست باز نشد؟ نقل‌قول‌ها رو ببین. آخرش هم اگه فرمان بدون خطا اجرا شد، حتماً فایل مقصد رو بخون؛ شاید خروجی رو جای اشتباه نوشته باشی.

نشانهاحتمال رایجاولین بررسی بی‌خطر
No such file or directoryمسیر یا نام نادرستpwd و ls روی پوشه مقصد
Permission deniedمجوز ناکافیبررسی مالکیت و دلیل نیاز به دسترسی
command not foundنام، نصب یا PATHcommand -v و املای فرمان
خروجی خالیداده یا فیلتر نامتناسبcat فایل ورودی و بررسی عبارت
فایل خروجی اشتباهمسیر یا Redirect نادرستخواندن مقصد و بازبینی > یا >>

چرا نباید هر فرمان ناشناسی رو با sudo اجرا کنیم؟

در لینوکس، sudo در محیط‌های پیکربندی‌شده می‌تونه فرمانی رو با هویت کاربر دیگری، معمولاً مدیر، اجرا کنه. این قابلیت برای کارهای مدیریتی لازمه، اما داروی عمومیِ خطاها نیست. اگر هنوز فرق پوشه پروژه و مسیر سیستمی رو نمی‌دونی، فعال کردن دسترسی بیشتر نه‌تنها مشکل اصلی رو حل نمی‌کنه، بلکه ممکنه اجازه تغییر فایل‌های حساس رو هم بده. کل پروژه این درس عمداً بدون sudo طراحی شده تا یادگیری با حداقل خطر پیش بره.

بهتره یک قانون شخصی داشته باشی : قبل از اجرای هر فرمانی که فایل‌ها رو حذف، بازنویسی یا مجوزها رو تغییر می‌ده، سه چیز رو بدونی؛ فرمان روی کدوم مسیر کار می‌کنه، نتیجه‌اش چیه و راه برگشت چقدره. حتی وقتی از یک چت‌بات یا سایت آموزشی دستور می‌گیری، اون دستور ممکنه برای سیستم تو مناسب نباشه. برعکس، یک فرمان ساده که فهمیدی چه می‌کنه معمولاً از یک دستور عجیب و طولانی که فقط کپی شده ارزش آموزشی بیشتری داره.

چطور نتیجه آزمایش رو بررسی کنیم تا فقط به ظاهر خروجی اعتماد نکنیم؟

حالا برگرد به آرشیو زیرنویس‌ها. اگه تمرین رو به ترتیب انجام داده باشی، inbox/scenes.txt چهار ردیف داره و review/todo.txt دو ردیف نیازمند بازبینی. توی ترمینال لینوکس یه فایل یادداشت با نام team notes.txt ساختیم و پیام خطای عمدی هم توی review/errors.log ذخیره شده. یعنی برای هر کاری که کردیم یه نشونه قابل بررسی داریم؛ لازم نیست فقط به حسِ «فکر کنم درست شد» تکیه کنیم.

cd "$HOME/nabegheha-shell-lab"
printf 'All lines: '
wc -l < inbox/scenes.txt
printf 'Needs review: '
grep -c 'needs-check' inbox/scenes.txt
printf 'Saved report lines: '
wc -l < review/todo.txt
ls -la review

در این نقطه اعداد مورد انتظار برای سه شمارش به‌ترتیب 4، 2 و 2 هستن. این اعداد فقط وقتی درستن که قدم‌ها رو یک‌بار و به ترتیب اجرا کرده باشی و فایل نمونه رو دستی تغییر نداده باشی. اگر عددها فرق دارن، به‌جای اینکه تمرین رو دوباره از صفر کپی کنی، فایل‌ها رو با cat بخون و ببین اختلاف از کدوم مرحله شروع شده. همین کار ساده، اساس عیب‌یابی حرفه‌ایه.

آموزش ترمینال لینوکس

تمرین‌های پایانی : واقعاً Bash رو فهمیدی یا فقط دستورها رو کپی کردی؟

برای اینکه مطمئن شی مطلب جا افتاده، سه تمرین کوتاه انجام بده. این‌ها نیاز به اینترنت یا دسترسی مدیریتی ندارن. حتی بهتره قبل از نگاه کردن به راهنما، خروجی ترمینال لینوکس رو روی کاغذ حدس بزنی چه نتیجه‌ای باید ببینی؛ بعد با ترمینال آزمایشش کنی و علت اختلاف بین حدس و خروجی رو بفهمی. این شیوه باعث می‌شه از حفظ کردن شکل فرمان فراتر بری و به فهم رفتار سیستم برسی.

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

در پوشه review یک فایل به اسم final review.txt بساز، یک جمله داخلش بنویس و محتواش رو نمایش بده. سؤال اصلی اینه که چرا بدون نقل‌قول ممکنه برنامه اسم فایل رو به چند بخش تقسیم کنه؟ اگر کارت درست بود، می‌تونی این راه‌حل نمونه رو با فرمان خودت مقایسه کنی :

cd "$HOME/nabegheha-shell-lab"
printf '%s\n' 'ready for review' > 'review/final review.txt'
cat 'review/final review.txt'

تمرین دوم : گزارش رو به‌روز کن

به فایل ورودی یک ردیف clip-05 | needs-check اضافه کن، بدون اینکه چهار ردیف قبلی پاک بشن. بعد گزارش review/todo.txt رو دوباره تولید کن و تعداد موارد نیازمند بازبینی رو به دست بیار. در نتیجه باید تعداد ردیف‌های فایل ورودی پنج و تعداد موارد نیازمند بازبینی سه بشه. از این تمرین باید فرق >> برای اضافه کردن به ورودی و > برای بازسازی خروجی رو یاد بگیری.

cd "$HOME/nabegheha-shell-lab"
printf '%s\n' 'clip-05 | needs-check' >> inbox/scenes.txt
grep -n 'needs-check' inbox/scenes.txt > review/todo.txt
wc -l < inbox/scenes.txt
wc -l < review/todo.txt

تمرین سوم : خطای مسیر رو خودت تشخیص بده

از داخل پوشه review سعی کن فقط با نوشتن cat inbox/scenes.txt فایل ورودی رو بخونی. انتظار داریم فرمان در پروژه ما فایل رو پیدا نکنه؛ چون نسبت به پوشه جاری به یک مسیر متفاوت اشاره می‌کنه. حالا بدون تغییر دادن فایل‌ها، مسیر رو اصلاح کن تا نتیجه درست ببینی. اگر فهمیدی چرا ../inbox/scenes.txt کار می‌کنه، یکی از مهم‌ترین مفهوم‌های خط فرمان رو یاد گرفتی.

cd "$HOME/nabegheha-shell-lab/review"
pwd
cat ../inbox/scenes.txt

مسیر یادگیری بعد از ترمینال لینوکس چیست؟

قرار نبود با یه مقاله همه دستورهای لینوکس رو تموم کنیم. الان باید بتونی فرق ترمینال لینوکس و شل رو توضیح بدی، بفهمی مسیر فایل چطور پیدا می‌شه و خروجی عادی با خطا چه فرقی داره. مهم‌تر از همه، وقتی چیزی جواب نمی‌ده، از خودت بپرسی «الان کجام؟ فرمان روی چی کار می‌کنه؟ خروجیش کجا رفت؟». اگه این سؤال‌ها برات روشن شده، وقتشه وارد درس بعدی یعنی دستورهای کاربردی‌تر و بعد فایل‌سیستم و مجوزها بشی.

برای ادامه، اول برو سراغ درس دستورات لینوکس و بعد ساختار فایل‌سیستم و مجوزهای لینوکس رو بخون. همه‌شون از هاب آموزش Linux Essentials در دسترسن. اگه هم یه مسیر ویدیویی منظم با تمرین‌های گسترده‌تر می‌خوای، می‌تونی پکیج آموزش Linux Essentials نابغه‌ها رو بررسی کنی. عجله‌ای برای خرید نیست؛ اول همین دستورات رو واقعاً روی سیستم خودت تمرین کن.

منابع فنی و مستندات پیشنهادی

وقتی درباره دستورها به مشکل می‌خوری، بهترین مرجع فقط یه جواب کوتاه توی شبکه‌های اجتماعی نیست. برای شروع، راهنمای خط فرمان Ubuntu خوبه. اگه می‌خوای قواعد Bash رو دقیق‌تر ببینی، تعریف Shell در مستندات GNU و بخش‌های Quoting، Redirections و Exit Status به کارت میان. برای Pipe هم راهنمای رسمی Pipelines رو داری. این‌ها منابع فنی درس هستن، نه جایگزین آزمایش روی سیستم خودت.

سؤالات متداول درباره ترمینال لینوکس و Bash

ترمینال لینوکس چیست و چه فرقی با شل دارد؟

ترمینال لینوکس معمولاً همون پنجره‌ایه که توش دستور می‌نویسی و خروجی رو می‌بینی، ولی شل برنامه‌ایه که اون دستور رو تفسیر و اجرا می‌کنه. مثلاً Bash رو می‌تونی توی ترمینال گرافیکی یا یه نشست SSH اجرا کنی. پس این دو معمولاً کنار هم هستن، اما یک چیز نیستن.

برای شروع لینوکس باید همه دستورهای ترمینال را حفظ کنم؟

نه، اصلاً لازم نیست همه دستورها رو حفظ کنی. اول یاد بگیر کجا ایستادی، فرمان چه ورودی‌ای می‌گیره و چه فایلی رو تغییر می‌ده. با pwd، cd، ls، mkdir، printf و cat هم می‌تونی یه تمرین واقعی انجام بدی.

Bash چیست و چه تفاوتی با Terminal دارد؟

زبان Bash یکی از شل‌های لینوکسه و برای نوشتن اسکریپت هم استفاده می‌شه. ترمینال لینوکس فقط محیط کار متنی رو فراهم می‌کنه؛ ممکنه داخلش Bash، Zsh یا یه شل دیگه اجرا شده باشه. پس نوع شل رو فقط از رنگ و شکل پنجره حدس نزن.

چطور ترمینال را در اوبونتو باز کنم؟

توی خیلی از دسکتاپ‌های اوبونتو از فهرست برنامه‌ها Terminal رو باز می‌کنی و معمولاً Ctrl+Alt+T هم جواب می‌ده. اگه میان‌بر کار نکرد، از جست‌وجوی برنامه‌ها کمک بگیر؛ تنظیمات بعضی سیستم‌ها فرق می‌کنه.

آیا دستورهای ترمینال لینوکس در ویندوز هم اجرا می‌شوند؟

نه لزوماً. PowerShell و Command Prompt قواعد خودشون رو دارن و همون Bash نیستن. اگه WSL و یه توزیع لینوکسی نصب کرده باشی، می‌تونی ترمینال لینوکس اون توزیع رو اجرا کنی و تمرین‌های Bash رو اونجا انجام بدی.

فرق مسیر مطلق و نسبی در ترمینال لینوکس چیست؟

مسیر مطلق با / شروع می‌شه و به پوشه فعلی وابسته نیست. مسیر نسبی از جایی حساب می‌شه که همین لحظه داخلش هستی. علامت ~ هم توی Bash معمولاً به پوشه خانگی کاربر اشاره می‌کنه؛ با ریشه فایل‌سیستم یکی نیست.

تفاوت علامت‌های > و >> در Bash چیست؟

در حالت معمول > خروجی عادی رو توی فایل می‌نویسه و محتوای قبلیش رو جایگزین می‌کنه، اما >> متن رو به آخر فایل اضافه می‌کنه. قبل از Enter زدن یه بار دیگه اسم فایل مقصد رو بررسی کن، مخصوصاً اگه اطلاعات مهمی توشه.

چرا با وجود اجرای دستور، پیام خطا می‌بینم یا فایلم پیدا نمی‌شود؟

ممکنه توی پوشه اشتباهی باشی، اسم فایل رو با حروف متفاوت نوشته باشی، نقل‌قول مسیر رو فراموش کرده باشی یا اجازه دسترسی نداشته باشی. اول pwd رو بزن و مسیر رو چک کن. اگه لازم بود بلافاصله بعد از فرمان با echo $? وضعیت خروجش رو ببین؛ صفر معمولاً نشونه موفقیته.

می‌خواهی عمیق‌تر جلو بروی؟

این درس فقط یک بخش از مسیر کامل است

اگر می‌خواهی مباحث را به‌ترتیب، همراه تمرین و پروژه دنبال کنی، مسیر کامل دوره را ببین.

مشاهده دوره Linux Essentials