رفتن به محتوا
LoopX

ساختن، کپی، جابه‌جایی و حذف

توی این درس یاد می‌گیری کارهای روزانه‌ی فایل‌ها را با ترمینال انجام بدهی: ساختن (touch، mkdir -p)، کپی (cp، cp -r)، جابه‌جایی و تغییر نام (mv) و حذف (rm، rm -r، rmdir). با wildcardها (*، ?، [ ]) و brace expansion ({a,b}) یک دستور را روی ده‌ها فایل اجرا می‌کنی، با حالت تعاملی -i و پیش‌نمایش با echo از اشتباه جلوگیری می‌کنی، و می‌فهمی چرا rm -rf خطرناک‌ترین دستور تازه‌کارهاست و چطور امن با آن کار کنی. تمرین: یک ساختار پروژه را با یک دستور mkdir می‌سازی.

مسئله: لینوکس سطل زباله ندارد

Section titled “مسئله: لینوکس سطل زباله ندارد”

در ویندوز و مک وقتی فایلی را پاک می‌کنی، به سطل زباله می‌رود. در ترمینال لینوکس rm فایل را برای همیشه پاک می‌کند؛ نه تأییدی می‌پرسد و نه برگشتی دارد. همین‌طور cp بدون هشدار فایل مقصد را رونویسی می‌کند و mv هم. پس یاد گرفتن این دستورها یعنی یاد گرفتن عادت‌های امن، نه فقط دستور.

پوشه‌ها قفسه‌ها و فایل‌ها برگه‌اند. mkdir قفسه‌ی تازه می‌سازد، touch برگه‌ی خالی می‌گذارد، cp فتوکپی می‌گیرد (اصل سر جایش است)، mv برگه را جابه‌جا یا اسمش را عوض می‌کند، و rm برگه را خرد می‌کند (دستگاه کاغذخردکن، نه سطل زباله). با کاغذخردکن آرام و با نگاه کردن کار می‌کنی.

cp یک نسخه‌ی جدید می‌سازد و اصل می‌ماند؛ mv همان فایل را جابه‌جا یا بازنام‌گذاری می‌کند (در یک دیسک بدون کپی داده)؛ rm پاک می‌کند، بدون سطل زباله.

touch اگر فایل نباشد یک فایل خالی می‌سازد، و اگر باشد فقط زمان آخرین تغییرش را به «الآن» می‌برد:

Terminal window
touch a.txt b.txt c.txt
ls -l --time-style=+%H:%M:%S
echo "--- ۲ ثانیه بعد دوباره touch a.txt:"
sleep 2
touch a.txt
ls -l --time-style=+%H:%M:%S a.txt b.txt
خروجی
total 0
-rw-r--r-- 1 ali ali 0 19:58:48 a.txt
-rw-r--r-- 1 ali ali 0 19:58:48 b.txt
-rw-r--r-- 1 ali ali 0 19:58:48 c.txt
--- ۲ ثانیه بعد دوباره touch a.txt:
-rw-r--r-- 1 ali ali 0 19:58:50 a.txt
-rw-r--r-- 1 ali ali 0 19:58:48 b.txt

سه فایل خالی (حجم صفر) ساخته شد و touch دوباره فقط زمان a.txt را عوض کرد. mkdir (make directory) پوشه می‌سازد:

Terminal window
mkdir photos
mkdir -v docs reports
mkdir a/b/c
خروجی
mkdir: created directory 'docs'
mkdir: created directory 'reports'
mkdir: cannot create directory ‘a/b/c’: No such file or directory

-v (verbose) کارش را چاپ می‌کند. خط آخر خطا داد: a/b وجود ندارد، پس mkdir نمی‌تواند c را بسازد. با -p (parents) مسیر کامل را یکجا می‌سازد و اگر از قبل باشد خطا نمی‌دهد:

Terminal window
mkdir -pv a/b/c
mkdir -p a/b/c && echo "دوباره اجرا: بدون خطا"
خروجی
mkdir: created directory 'a'
mkdir: created directory 'a/b'
mkdir: created directory 'a/b/c'
دوباره اجرا: بدون خطا

مثال ۲: wildcard، یک دستور برای چند فایل

Section titled “مثال ۲: wildcard، یک دستور برای چند فایل”

shell علامت‌های * و ? و [] را قبل از اجرای دستور با اسم‌های واقعی فایل‌ها جایگزین می‌کند (این را globbing می‌نامند). چند فایل برای آزمایش (در یک پوشه‌ی جدا، تا با فایل‌های قبلی قاطی نشود):

Terminal window
mkdir glob && cd glob
touch report1.txt report2.txt report10.txt notes.md img1.png img2.png .hidden.txt
echo "* همه: $(echo *)"
echo "*.txt: $(echo *.txt)"
echo "report?.txt: $(echo report?.txt)"
echo "report??.txt: $(echo report??.txt)"
echo "report[12].txt: $(echo report[12].txt)"
echo "img[0-9].png: $(echo img[0-9].png)"
echo "*[!t]: $(echo *[!t])"
echo "*.nothing: $(echo *.nothing)"
خروجی
* همه: img1.png img2.png notes.md report1.txt report10.txt report2.txt
*.txt: report1.txt report10.txt report2.txt
report?.txt: report1.txt report2.txt
report??.txt: report10.txt
report[12].txt: report1.txt report2.txt
img[0-9].png: img1.png img2.png
*[!t]: img1.png img2.png notes.md
*.nothing: *.nothing

الگوهای wildcard: پنج حالت اصلی

الگو معنی
* هر تعداد کاراکتر (حتی صفر)
? دقیقاً یک کاراکتر
[abc] یکی از a و b و c
[0-9] یک رقم (بازه)
[!abc] هر کاراکتری به‌جز این‌ها

نکته‌ی مهم: * فایل‌های مخفی (با .) را شامل نمی‌شود (.hidden.txt در فهرست نیست)، و اگر الگو با هیچ فایلی جور نشود (*.nothing)، bash همان متن را بدون تغییر نگه می‌دارد. چون shell جایگزینی را انجام می‌دهد (نه خود دستور)، یک دستور مثل ls *.txt در واقع ls report1.txt report10.txt report2.txt را می‌گیرد. اگر quote بگذاری ("*.txt") جایگزینی انجام نمی‌شود.

مثال ۳: brace expansion، ساختن چند اسم

Section titled “مثال ۳: brace expansion، ساختن چند اسم”

آکولاد { } فهرستی از اسم‌ها می‌سازد (برخلاف wildcard، نیازی به وجود فایل ندارد):

Terminal window
echo file{1,2,3}.txt
echo file{1..5}.txt
echo file{01..03}.txt
echo {a,b,c}{1,2}
echo backup-{jan,feb}-2026
خروجی
file1.txt file2.txt file3.txt
file1.txt file2.txt file3.txt file4.txt file5.txt
file01.txt file02.txt file03.txt
a1 a2 b1 b2 c1 c2
backup-jan-2026 backup-feb-2026

سه شکل: لیست ({a,b,c})، بازه ({1..5}) و بازه با صفر پیشرو ({01..03}). ترکیب با دستورها بسیار مفید است:

Terminal window
mkdir -pv project/{src,tests,docs}/{old,new}
touch project/src/main.py project/tests/test_main.py
cp project/src/main.py{,.bak}
ls project/src
خروجی
mkdir: created directory 'project'
mkdir: created directory 'project/src'
mkdir: created directory 'project/src/old'
mkdir: created directory 'project/src/new'
mkdir: created directory 'project/tests'
mkdir: created directory 'project/tests/old'
mkdir: created directory 'project/tests/new'
mkdir: created directory 'project/docs'
mkdir: created directory 'project/docs/old'
mkdir: created directory 'project/docs/new'
main.py
main.py.bak
new
old

mkdir -p project/{src,tests,docs}/{old,new} شش پوشه را با یک دستور می‌سازد (۳ × ۲ ترکیب). و ترفند محبوب cp فایل{,.bak} که به cp فایل فایل.bak باز می‌شود، یعنی یک نسخه‌ی پشتیبان سریع قبل از ویرایش.

⚡ بررسی سریع

echo file{1..3}.txt چه چاپ می‌کند؟

Terminal window
echo "نسخه‌ی اول" > data.txt
cp data.txt data-copy.txt
ls data*
echo "--- محتوا یکی است:"
cat data-copy.txt
خروجی
data-copy.txt
data.txt
--- محتوا یکی است:
نسخه‌ی اول

cp مبدأ مقصد. اگر مقصد از قبل باشد، بی‌صدا رونویسی می‌شود:

Terminal window
echo "قدیمی مهم" > keep.txt
echo "جدید" > new.txt
cp new.txt keep.txt
echo "محتوای keep.txt بعد از cp: $(cat keep.txt)"
خروجی
محتوای keep.txt بعد از cp: جدید

«قدیمی مهم» برای همیشه رفت. دو دفاع: -i (interactive: قبل از رونویسی بپرس) و -n (no-clobber: هرگز رونویسی نکن؛ در coreutils جدید املای تازه‌اش --update=none است و -n هشدار می‌دهد که رفتارش در آینده ممکن است عوض شود):

Terminal window
echo "قدیمی مهم" > keep.txt
echo "--- cp -i با جواب n:"
echo n | cp -i new.txt keep.txt
echo "محتوا: $(cat keep.txt)"
echo "--- cp --update=none (هم‌معنی -n):"
cp --update=none new.txt keep.txt; echo "کد خروج: $? محتوا: $(cat keep.txt)"
خروجی
--- cp -i با جواب n:
cp: overwrite 'keep.txt'? محتوا: قدیمی مهم
--- cp --update=none (هم‌معنی -n):
کد خروج: 0 محتوا: قدیمی مهم

برای پوشه‌ها باید -r (recursive) بدهی:

Terminal window
mkdir -p src/lib && touch src/lib/a.py src/main.py
cp src src-backup
echo "--- با -r:"
cp -rv src src-backup
خروجی
cp: -r not specified; omitting directory 'src'
--- با -r:
'src' -> 'src-backup'
'src/lib' -> 'src-backup/lib'
'src/lib/a.py' -> 'src-backup/lib/a.py'
'src/main.py' -> 'src-backup/main.py'

بدون -r خطای «-r not specified; omitting directory». دو flag مفید دیگر: -v (چاپ کارها) و -a (archive: همه‌چیز را حفظ کن: زمان‌ها، دسترسی‌ها، لینک‌ها؛ برای بکاپ).

مثال ۵: جابه‌جایی و تغییر نام، mv

Section titled “مثال ۵: جابه‌جایی و تغییر نام، mv”

mv هم برای جابه‌جایی و هم برای تغییر نام است (تغییر نام یعنی جابه‌جایی در همان پوشه):

Terminal window
touch old-name.txt
mv old-name.txt new-name.txt # تغییر نام
mkdir archive
mv new-name.txt archive/ # جابه‌جایی به پوشه
mv -v archive/new-name.txt archive/final.txt
ls archive
خروجی
renamed 'archive/new-name.txt' -> 'archive/final.txt'
final.txt

چند فایل را با wildcard به یک پوشه ببر (آخرین argument باید پوشه باشد):

Terminal window
touch log1.tmp log2.tmp log3.tmp
mkdir old-logs
mv -v *.tmp old-logs/
ls old-logs
خروجی
renamed 'log1.tmp' -> 'old-logs/log1.tmp'
renamed 'log2.tmp' -> 'old-logs/log2.tmp'
renamed 'log3.tmp' -> 'old-logs/log3.tmp'
log1.tmp
log2.tmp
log3.tmp

mv هم مثل cp مقصد موجود را بی‌هشدار رونویسی می‌کند؛ -i و -n برایش هم هستند. جابه‌جایی داخل یک دیسک سریع است (فقط ثبت مکان فایل عوض می‌شود)، حتی برای فایل ۱۰ گیگابایتی.

Terminal window
mkdir rmtest && cd rmtest
touch temp1.txt temp2.txt keep.txt
rm temp1.txt
ls
echo "--- پیش‌نمایش با echo:"
echo rm temp*
rm temp*
ls
خروجی
keep.txt
temp2.txt
--- پیش‌نمایش با echo:
rm temp2.txt
keep.txt

قبل از rm با wildcard، دستور را با echo بزن تا ببینی shell چه چیزی جایگزین می‌کند. برای پوشه‌ها:

Terminal window
mkdir -p empty full/sub
touch full/file.txt
rmdir empty && echo "rmdir پوشه‌ی خالی: موفق"
echo "--- rmdir روی پوشه‌ی پر:"
rmdir full
echo "--- rm -r (با -v برای دیدن):"
rm -rv full
خروجی
rmdir پوشه‌ی خالی: موفق
--- rmdir روی پوشه‌ی پر:
rmdir: failed to remove 'full': Directory not empty
--- rm -r (با -v برای دیدن):
removed 'full/file.txt'
removed directory 'full/sub'
removed directory 'full'

rmdir فقط پوشه‌ی خالی را پاک می‌کند (یک شبکه‌ی ایمنی)؛ rm -r (recursive) پوشه و همه‌چیز داخلش را. و -f (force) خطاها و پرسش‌ها را نادیده می‌گیرد: ترکیب rm -rf یعنی «بی‌سؤال و بی‌شکایت همه‌چیز را پاک کن».

مثال ۷: حالت تعاملی -i و ایمنی rm

Section titled “مثال ۷: حالت تعاملی -i و ایمنی rm”

rm -i برای هر فایل می‌پرسد (y = بله، هر چیز دیگر = نه):

Terminal window
touch x1 x2 x3
printf 'y\nn\ny\n' | rm -i x1 x2 x3
echo "--- باقی‌مانده:"
ls x*
خروجی
rm: remove regular empty file 'x1'? rm: remove regular empty file 'x2'? rm: remove regular empty file 'x3'? --- باقی‌مانده:
x2

سه پرسش و پاسخ y، n، y (در ترمینال واقعی پاسخی که تایپ می‌کنی کنار هر سؤال دیده می‌شود؛ اینجا از pipe آمده‌اند): x1 و x3 پاک شد و x2 ماند. -I (حرف بزرگ) فقط یک بار و فقط وقتی بیش از ۳ فایل یا پوشه‌ی بازگشتی باشد می‌پرسد؛ برای استفاده‌ی روزمره ملایم‌تر است. و یک شبکه‌ی ایمنی داخلی: rm از پاک کردن ریشه امتناع می‌کند:

Terminal window
rm -r /
خروجی
rm: it is dangerous to operate recursively on '/'
rm: use --no-preserve-root to override this failsafe

این --preserve-root پیش‌فرض است (به‌خاطر فاجعه‌های قدیمی). ولی هیچ محافظی برای پوشه‌ی خانه‌ی تو یا پوشه‌ی پروژه نیست.

مثال ۸: یک ترفند مهم: اسم‌هایی که با - شروع می‌شوند و --

Section titled “مثال ۸: یک ترفند مهم: اسم‌هایی که با - شروع می‌شوند و --”

اگر اسم فایل با - شروع شود، دستور آن را flag می‌پندارد:

Terminal window
mkdir dash && cd dash
touch -- -weird.txt
ls
rm -weird.txt 2>&1 | head -1
rm -- -weird.txt && echo "با -- پاک شد"
خروجی
-weird.txt
rm: invalid option -- 'w'
با -- پاک شد

-- یعنی «از اینجا به بعد هیچ flag ای نیست». این برای اسم‌های عجیب لازم است و در اسکریپت‌ها هم عادت خوب است (rm -- "$file").

آیا cp -r src dst پوشه‌ی src را داخل dst می‌گذارد یا به‌جای آن؟ بستگی دارد dst از قبل باشد:

Terminal window
mkdir -p s/inner && touch s/inner/f.txt
echo "--- dst وجود ندارد:"
cp -r s d1 && find d1
echo "--- dst از قبل هست:"
mkdir d2
cp -r s d2 && find d2
خروجی
--- dst وجود ندارد:
d1
d1/inner
d1/inner/f.txt
--- dst از قبل هست:
d2
d2/s
d2/s/inner
d2/s/inner/f.txt

اگر مقصد نبود، d1 خودش یک کپی از s شد؛ اگر بود، s داخل d2 رفت (d2/s/...). این یکی از رایج‌ترین گیج‌کننده‌هاست؛ در شک، با ls/find بعد از کپی نتیجه را ببین و بدان که mkdir قبل از cp رفتار را عوض می‌کند.

مثال ۱۰: ساختار یک پروژه با یک دستور

Section titled “مثال ۱۰: ساختار یک پروژه با یک دستور”

تمام آنچه گفتیم برای ساختن یک اسکلت پروژه:

Terminal window
mkdir -p webapp/{src/{components,pages},public/{css,js,img},tests,docs}
touch webapp/{README.md,.gitignore}
touch webapp/src/components/{Header,Footer}.js
find webapp | sort
خروجی
webapp
webapp/.gitignore
webapp/README.md
webapp/docs
webapp/public
webapp/public/css
webapp/public/img
webapp/public/js
webapp/src
webapp/src/components
webapp/src/components/Footer.js
webapp/src/components/Header.js
webapp/src/pages
webapp/tests

یک خط، ۱۱ پوشه و ۴ فایل. (find را در درس پیدا کردن فایل‌ها کامل می‌خوانی؛ فعلاً فقط برای نمایش درخت.)

پشت پرده: shell glob می‌کند، دستور فقط argument می‌بیند

Section titled “پشت پرده: shell glob می‌کند، دستور فقط argument می‌بیند”

وقتی rm *.tmp می‌نویسی، برنامه‌ی rm هرگز علامت * را نمی‌بیند. shell اول *.tmp را با اسم‌های واقعی جایگزین می‌کند (مثلاً a.tmp b.tmp) و بعد rm a.tmp b.tmp را اجرا می‌کند. این را با echo ببین: echo *.tmp دقیقاً همان چیزی را نشان می‌دهد که rm می‌بیند. نتیجه‌ها:

  • اگر فایل خیلی زیاد باشد (صدها هزار)، خط فرمان از حد طول می‌گذرد (Argument list too long)؛ راه‌حل find یا xargs (درس‌های بعد).
  • اسم فایل با فاصله یا - در glob درست جایگزین می‌شود (هر اسم یک argument) ولی در فایل‌هایی که با - شروع می‌شوند flag به نظر می‌رسند (--).
  • پیش‌نمایش echo دقیقاً سناریوی واقعی را شبیه‌سازی می‌کند.

و درباره‌ی حذف: rm اسم فایل را از پوشه حذف می‌کند (یک «لینک» را کم می‌کند) و اگر هیچ لینک دیگری به آن داده نمانده باشد، بلوک‌های دیسک آزاد (قابل‌استفاده‌ی دوباره) علامت می‌خورند. بازیابی بعد از rm ممکن است ولی بی‌تضمین است؛ پس بکاپ بگیر.

دستور کار flag های مهم
touch f ساخت فایل خالی / به‌روز کردن زمان —
mkdir d ساخت پوشه -p مسیر کامل، -v
cp a b کپی -r پوشه، -i بپرس، -n رونویسی نکن، -a حفظ همه‌چیز، -v
mv a b جابه‌جایی/تغییر نام -i، -n، -v
rm f حذف فایل -r پوشه، -f اجبار، -i بپرس، -v
rmdir d حذف پوشه‌ی خالی —
الگو مثال نتیجه
* *.txt همه‌ی فایل‌های txt
? f?.txt f1.txt، fa.txt …
[ab] f[12].txt f1.txt و f2.txt
{a,b} f{a,b}.txt fa.txt fb.txt
{1..3} f{1..3} f1 f2 f3

۱) rm -rf با فاصله‌ی اشتباه یا متغیر خالی

Section titled “۱) rm -rf با فاصله‌ی اشتباه یا متغیر خالی”
Terminal window
mkdir -p proj/data && touch proj/data/a.txt
dir=""
echo "دستوری که اجرا می‌شود: rm -rf $dir/*"
خروجی
دستوری که اجرا می‌شود: rm -rf /*

اگر متغیر $dir خالی باشد، rm -rf $dir/* به rm -rf /* تبدیل می‌شود! (در اینجا فقط چاپش کردیم.) راه‌حل: در اسکریپت‌ها set -u (خطا برای متغیر تعریف‌نشده) و "${dir:?}" را به کار ببر (درس‌های bash)، و همیشه قبل از rm -rf مسیر را با echo یا ls ببین.

۲) رونویسی فایل مهم با cp یا mv

Section titled “۲) رونویسی فایل مهم با cp یا mv”

مثال ۴: «قدیمی مهم» رفت. راه‌حل: -i یا -n؛ یا یک alias (درس‌های بعد): alias cp='cp -i'.

Terminal window
mkdir folder && touch folder/f
cp folder folder2
خروجی
cp: -r not specified; omitting directory 'folder'

راه‌حل: cp -r (یا -a برای بکاپ کامل).

Terminal window
mkdir full2 && touch full2/x
rmdir full2
خروجی
rmdir: failed to remove 'full2': Directory not empty

rmdir عمداً فقط پوشه‌ی خالی را پاک می‌کند. راه‌حل: اگر واقعاً می‌خواهی همه‌چیز برود، rm -r full2 (بعد از نگاه کردن به محتوا).

۵) wildcard که چیزی بیشتر از انتظار جور می‌کند

Section titled “۵) wildcard که چیزی بیشتر از انتظار جور می‌کند”
Terminal window
mkdir g && cd g
touch data.csv data.csv.bak data-old.csv
echo "data* → $(echo data*)"
echo "data.csv → $(echo data.csv)"
خروجی
data* → data-old.csv data.csv data.csv.bak
data.csv → data.csv

rm data* هر سه را می‌برد، حتی بکاپ‌ها. راه‌حل: الگوی دقیق‌تر یا echo قبل از rm.

✎ تمرینآسان

یک پوشه به اسم exercise بساز، داخلش سه فایل a.txt، b.txt و c.txt بساز، و بعد همه را با یک دستور و wildcard به پوشه‌ی backup کپی کن.

دیدن جواب
Terminal window
mkdir exercise backup
touch exercise/{a,b,c}.txt
cp exercise/*.txt backup/
ls backup
خروجی
a.txt
b.txt
c.txt
✎ تمرینمتوسط

تمرین اصلی: ساختار پوشه‌ی یک پروژه را با یک دستور mkdir بساز: site با زیرپوشه‌های css، js، img و در img هم icons و photos. سپس برای سه فایل index.html، about.html، contact.html یک خط touch بنویس و درخت را نشان بده.

دیدن جواب
Terminal window
mkdir -p site/{css,js,img/{icons,photos}}
touch site/{index,about,contact}.html
find site | sort
خروجی
site
site/about.html
site/contact.html
site/css
site/img
site/img/icons
site/img/photos
site/index.html
site/js
✎ تمرینسخت

یک سناریوی امن بنویس: ده فایل log-01.tmp تا log-10.tmp بساز، یک پوشه‌ی archive بساز، فایل‌ها را با پیش‌نمایش (echo) نشان بده، بعد فقط شماره‌های زوج را (۰۲، ۰۴، …) به archive منتقل کن و بقیه را با rm -i (جواب‌های خودکار n) نگه دار.

دیدن جواب
Terminal window
mkdir ex3 && cd ex3
touch log-{01..10}.tmp
mkdir archive
echo "پیش‌نمایش زوج‌ها: $(echo log-*[02468].tmp)"
mv -v log-*[02468].tmp archive/ | wc -l
echo "--- در archive: $(ls archive | tr '\n' ' ')"
echo "--- باقی‌مانده: $(ls log-* | tr '\n' ' ')"
yes n | rm -i log-*.tmp
echo "بعد از پاسخ n: $(ls log-* | wc -l) فایل ماند"
خروجی
پیش‌نمایش زوج‌ها: log-02.tmp log-04.tmp log-06.tmp log-08.tmp log-10.tmp
5
--- در archive: log-02.tmp log-04.tmp log-06.tmp log-08.tmp log-10.tmp
--- باقی‌مانده: log-01.tmp log-03.tmp log-05.tmp log-07.tmp log-09.tmp
rm: remove regular empty file 'log-01.tmp'? rm: remove regular empty file 'log-03.tmp'? rm: remove regular empty file 'log-05.tmp'? rm: remove regular empty file 'log-07.tmp'? rm: remove regular empty file 'log-09.tmp'? بعد از پاسخ n: 5 فایل ماند

الگوی *[02468] یعنی «اسمی که با یک رقم زوج تمام می‌شود» (البته log-10 هم با ۰ تمام می‌شود و به‌عنوان زوج می‌رود).

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

  2. echo *.txt در واقع چه کسی را جایگزین می‌کند؟

  3. cp -r برای چیست؟

  4. rm بعد از اجرا…

  5. rmdir چه فرقی با rm -r دارد؟

  6. چطور فایلی با اسم -weird.txt را حذف می‌کنی؟

  • touch فایل خالی می‌سازد (یا زمان را به‌روز می‌کند)؛ mkdir -p مسیر کامل می‌سازد.
  • cp (با -r برای پوشه، -i/-n برای ایمنی، -a برای بکاپ)؛ mv هم جابه‌جایی هم تغییر نام؛ هر دو بی‌هشدار رونویسی می‌کنند.
  • rm برای همیشه پاک می‌کند (بدون سطل زباله)؛ rmdir فقط پوشه‌ی خالی؛ rm -r پوشه‌ی پر؛ -f بی‌سؤال.
  • wildcard (*، ?، [ ]) و brace ({a,b}، {1..5}) را shell پیش از اجرا جایگزین می‌کند؛ echo پیش‌نمایش عالی است.
  • عادت‌های امن: echo rm ... قبل از حذف، -i، بکاپ، عدم استفاده از rm -rf با متغیر خالی، و -- برای اسم‌های عجیب.
  • cp -r src dst بسته به اینکه dst وجود داشته باشد نتیجه‌ی متفاوتی دارد.
برگه‌ی تقلب این درس
دستورکاری که می‌کند
touch a.txt b.txtساخت فایل‌های خالی
mkdir -p a/b/cساخت مسیر تو در تو
mkdir -p proj/{src,tests,docs}چند پوشه با brace
cp a.txt b.txtکپی فایل
cp -r dir dir2کپی پوشه
cp -i a b / cp -n a bبپرس / رونویسی نکن
cp file{,.bak}بکاپ سریع
mv old newتغییر نام / جابه‌جایی
mv *.tmp dir/جابه‌جایی چند فایل
rm file / rm -r dir / rmdir dirحذف فایل / پوشه‌ی پر / پوشه‌ی خالی
rm -i *.tmpحذف با تأیید
echo rm *.tmpپیش‌نمایش آنچه shell جایگزین می‌کند
rm -- -fileحذف اسمی که با - شروع می‌شود