دستور find یکی از شگفت انگیزترین دستورات لینوکس است. با این دستور میتوانید کارهای بسیار جالبی انجام دهید. این دستور برای پیدا کردن فایلی در یک شاخه خاص و تمام زیرشاخه های آن استفاده میشود. به عبارت دیگر کاربرد دستور find پیدا کردن لیستی از فایل ها و پوشه ها بر اساس شرایط خاصی که توسط کاربر مشخص میشود. مثلا کاربر میتواند جستجو را براساس سطح دسترسی - کاربران - گروه ها - نوع فایل - تاریخ - اندازه و دیگر معیارهای ممکن انجام دهد.
find یکی از مهمترین و پراستفاده ترین دستورها در تمامی سیستم عامل های مبتنی بر لینوکس و یونیکس است که هر کاربر لینوکسی باید با آن آشنا باشد البته تفاوت هایی در syntax استفاده در find بین سیستم عامل های مبتنی بر یونیکس مانند:linux - BSD و Solaris وجود دارد اما نقاط اشتراک بیشتر هستند یک شکل کلی پایه برای استفاده از دستور find بصورت زیر است:
find <DIR_PATH>options
به عنوان اولین مثال برای یافتن فایل ها - دایرکتوری ها با آنها از سوئیچ name-
استفاده میکنیم. دستور زیر در دایرکتوری root تمام فایلها با نام passwd را پیدا میکند. اگر جای دایرکتوری چیزی نوشته نشود یا یک نقطه نوشته شود یعنی جستجو در دایرکتوری جاری انجام شود.
[phoenix@phoenix-mashhad ~]$ find / -name passwd /etc/pam.d/passwd /etc/passwd /sys/fs/selinux/class/passwd /sys/fs/selinux/class/passwd/perms/passwd /usr/share/licenses/passwd /usr/share/doc/passwd /usr/share/bash-completion/completions/passwd /usr/bin/passwd /var/lib/rkhunter/passwd /var/lib/sss/mc/passwd
سوئیچ name-
به کوچکی و بزرگی حساس است با استفاده از iname-
جستجو دیگر به بزرگی و کوچکی حروف حساس نیست.
find / -iname passwd
با استفاده از سوئیچ type-
می توان جستجو را براساس نوع فایل ( دایرکتوری- فایل معمولی مانند فایل متنی و … ) انجام داد. دو مقدار f و d که به ترتیب یعنی file و دایرکتوری هستند. مقدار b برای Black Device
ها و مقدار c برای Charactor Device
ها استفاده میشود. بطور مثال برای یافتن دایرکتوری test اولین دستور زیر و برای یافتن تمامی Block Device
ها از دومین دستور زیر استفاده کنید. در دومین دستور کاراکتر * به معنی تمامی فایل ها ( نام ها ) و حتما باید میان « »
قرار گیرد.
find / -name test -type d find / -name "*" -type b
با استفاده از سوئیچ size-
فایل ها را براسا اندازه شان پیدا کنید. همچنین با استفاده از سوئیچ empty-
میتوان فایل های تهی ( با اندازه صفر ) را پیدا کرد. استفاده مهم این دو سوئیچ زمانی است که اندازه پارتیشن یک سرور به خاطر فایل های حجیم و بی استفاده بسیار بزرگ شده یا به دلیل وجود فایل های خالی بسیار شلوغ شده اند که با دو سوئیچ می توان آنها را پیدا کرد.
find / -name "*.iso" -size 3.6G find . -name -empty find / -empty -type f
اولین دستور بالا تمامی فایل ها با فرمت iso. را که حجم شان 3.6 گیگابایت است و دومین دستور تمامی فایل های خالی در دایرکتوری جاری را پیدا میکند. سومین دستور تمامی فایل های معمولی ( مانند فایل های متنی ) خالی در دایرکتوری جاری را پیدا میکند. به جای G میتوان از K به معنی کیلوبایت و M به معنی مگابایت استفاده کرد و توجه کنید که K کوچک است. در استفاده از سوئیچ size-
میتوان از علامتهای + و - در کنار عدد استفاده کرد. بطور مثال اولین دستور زیر یعنی تمامی فایل های iso. با اندازه بیشتر از 3.6G و دومین دستور یعنی تمامی فایل های iso. با اندازه کمتر از 150M را پیدا کن.
find / -name "*.iso"-size +3.6G find / -name "*.iso" -size -150M
از سوئیچ not-
میتوان برای نفی نتیجه استفاده کرد. بطور مثال در مثال زیر تمامی فایل هایی که نامشان mysite.php نیست را پیدا میکند.
find / -not -iname mysite.php
سوئیچ maxdepth-
که یک عدد را به عنوان مقدار میگیرد حداکثر تعداد سطوح بعد دایرکتوری تعیین شده را برای آن جستجو میکند. بطور مثال در دستور زیر برای جستجوی فایل هایی با نام passwd از دایرکتوری root تا دو سطح بعد از دایرکتوری root جستجو میشود. عدد ۳ تعیین شده ولی تا دو سطح بعد جستجو می شود که باید هر عددی را از یک کم کنیم. یعنی ۱-۳ که ۲ میشود.
[phoenix@phoenix-mashhad ~]$ find / -maxdepth 3 -name passwd /etc/pam.d/passwd /etc/passwd /usr/bin/passwd
همانطور که در خروجی مشاهده میکنید تا دو دایرکتوری بعد از دایرکتوری / جستجو شده است. البته در اصل باید جستجو در ۱ یا ۲ دایرکتوری انجام شود ولی بالاتر از دو دایرکتوری بعد دایرکتوری / انجام نمیشود maxdepth-
تعیین کننده حداکثر سطح دایرکتوری ها برای جستجو است و mindepth-
حداقل سطح دایرکتوری ها برای جستجو را تعیین میکند. بطور مثال در دستور زیر برای جستجو بین سطح ۲ تا ۴ برای یافتن فایل های passwd استفاده میشود.
find / -mindepth 3 -maxdepth 5 -name passwd -type f
توجه: سوئیج های mindepth-
و maxdepth-
میبایست حتما پیش از هر سوئیچ دیگری نوشته شوند.
اگر maxdepth-
را مقدار ۱ بدهیم یعنی جستجو در دایرکتوری جاری که معادل نوشتن یک نقطه به جای دایرکتوری یا ننوشتن چیزی به جای دایرکتوری است. هر سه دستور زیر معادل هم هستند.
find -maxdepth 1 -name passwd find . -name passwd find -name passwd
برای جستجوی فایلها بر اساس inode آنها از سوئیچ inum-
که مخفف Inode Number است استفاده کنید. بطور مثال دستور زیر فایلی با inode494 را پیدا میکند.
find / -inum 494
با استفاده از سوئیچ exec-
میتوان پس از یافتن فایل ها دستوری مانند rm برای حذف آنها را اجرا کرد. بطور مثال در دستور زیر پس از یافتن تمامی فایل های خالی در سیستم با اجرای دستور rm توسط سوئیچ exec-
آنها پاک خواهند شد. سوئیچ exec-
یعنی فایلها (مسیر و نام فایل ها) جایگزین {} شده و سپس توسط دستور rm پاک میشوند. اولین خط دستورهای زیر شکل کلی استفاده از سوئیچ exec-
را نشان میدهد و دومین دستور مثالی برای پاک کردن تمامی فایل های خالی است.
find / -empty -exec rm -irf {} \;
در ادامه مطلب به مهمترین کاربردهای دستور find خواهیم پرداخت و با ذکر مثال های متنوع هر یک را توضیح خواهیم داد. بطور کلی کاربردهای دستور find به ۵ دسته زیر تقسیم بندی میشوند:
جهت جستجو در تمام فایلهای دایرکتوری جاری که نام آنها test.txt باشد از دستور زیر استفاده میکنیم:
find / -name text.txt
جهت جستجو در تمام فایلهای موجود در دایرکتوری home که نام آنها test.txt باشد از دستور زیر استفاده میکنیم:
find ~ -name test.txt
جهت یافتن تمام فایل هایی که نام آنها test.txt که شامل حروف های بزرگ و کوچک میباشند از دستور زیر استفاده میکنیم:
find ~ -iname test.txt
برای پیدا کردن تمام دایرکتوری هایی که نام آنها test باشد در مسیر / می بایست از دستور زیر استفاده کرد:
find / -type d -name test
جهت پیدا کردن تمام فایل های php که در پوشه جاری بوده و نام آنها test.php باشد از دستور زیر استفاده میکنیم:
find . -name -type f test.php
جهت پیدا کردن تمام فایل هایی که پسوند آنها php. باشد در دایرکتوری جاری از دستور زیر استفاده میکنیم:
find . -type f -name "*.php"
جهت یافتن تمام فایل هایی که سطح دسترسی آنها ۷۷۷ باشد از دستور زیر استفاده میکنیم:
find . -type f -perm 0777 -print
جهت یافتن تمام فایل هایی که سطح دسترسی آنها ۷۷۷ نباشد از دستور زیر استفاده میکنیم:
find . -type f ! -perm 777
جهت یافتن فایل های sgid که سطح دسترسی آنها ۶۴۴ تنظیم شده است از دستور زیر استفاده میکنیم:
find / -perm 2644
جهت یافتن تمام فایل هایی که بصورت Sticky Bit تنظیم شده اند و سطح دسترسی آنها ۵۵۱ است از دستور زیر استفاده میشود
find / -perm 1551
جهت یافتن فایل هایی که بصورت SUID تنظیم شده اند از دستور زیر استفاده میشود:
find / -perm /u=s
جهت یافتن فایل هایی که بصورت SGID تنظیم شده اند از دستور زیر استفاده میشود:
find / -perm /g+s
جهت پیدا کردن تمام فایل های فقط خواندنی از دستور زیر استفاده میشود:
find / -perm /u=r
جهت یافتن تمام فایل های اجرا شدنی در لینوکس از دستور زیر استفاده میشود:
find / -perm /a=x
جهت پیدا کردن تمام فایل هایی که سطح دسترسی آنها ۷۷۷ است و تغییر سطح دسترسی آنها به ۶۴۴ از دستور زیر استفاده میشود:
find / -type f -perm 0777 -print -exec chmod 644 {} \;
جهت پیدا کردن تمام فایل هایی که سطح دسترسی آنها ۶۶۶ است و تغییر سطح دسترسی آنها به ۶۴۴ از دستور زیر استفاده میشود:
find / -type f -perm 0666 -print -exec chmod 644 {} \;
جهت پیدا کردن دایرکتوری هایی که سطح دسترسی آنها ۷۷۷ است و تغییر سطح دسترسی آنها به ۷۵۵ از دستور زیر استفاده میشود:
find / -type d -perm 777 - print -exec chmod 775 {} \;
برای پیدا کردن یک فایل مانند text.txt و حذف خودکار آن از دستور زیر استفاده میشود:
find -type f -name "text.txt" -exec rm -f {} \;
برای پیدا کردن و حذف کردن دسته جمعی فایل ها مانند پسوندهای txt. یا mp3. از یکی از دستورات زیر استفاده میشود:
find / -type f -name "*.txt" -exec rm -f {} \; find / -type f -name "*.mp3" -exec rm -f {} \;
جهت پیدا کردن تمام دایرکتوری های خالی در یک مسیر خاص از دستور زیر استفاده میشود:
find / -type f -empty
جهت پیدا کردن تمام دایرکتوری های خالی در یک مسیر خاص از دستور زیر استفاده میشود:
find -type d -empty
برای پیدا کردن تمام فایل های مخفی در لینوکس از دستور زیر استفاده میشود:
find / type f -name ".*"
برای پیدا کردن همه یا تنها یک فایل با اسم خاص در مسیر / که صاحب آنها root است از دستور زیر استفاده میشود
find / -user root -name text.txt
پیدا کردن تمام فایل هایی که صاحب آن phoenix و در مسیر home باشند از دستور زیر استفاده میشود:
find ~ -user phoenix
جهت پیدا کردن تمام فایل های تحت Group (گروه ) Dev و در مسیر home از دستور زیر استفاده میکنیم:
find ~ -group dev
جهت یافتن یک فایل خاص که Owner آن کاربر phoenix باشد از دستور زیر استفاده میشود:
find ~ -user phoenix -iname "*.txt"
جهت پیدا کردن تمام فایل هایی که Modified time آنها برای ۵۰ روز اخیر باشد از دستور زیر استفاده میشود:
find / -mtime 50
جهت پیدا کردن تمام فایل هایی که در ۵۰ روز اخیر مشاهده شده اند از دستور زیر استفاده میشود:
find / -atime 50
جهت یافتن تمام فایل هایی که بیشتر از ۵۰ روز و کمتر از ۱۰۰ روز modify شده اند از دستور زیر استفاده میکنیم:
find / -mtime +50 -mtime -100
جهت یافتن تمام فایل هایی که در یک ساعت اخیر تغییر کرده اند از دستور زیر استفاده میشود:
find / -cmin -60
جهت پیدا کردن تمام فایل هایی که در یک ساعت اخیر modify شده اند از دستور استفاده میشود:
find / -mmin -60
جهت یافتن تمام فایل هایی که در یک ساعت اخیر مشاهده شده اند از دستور زیر استفاده میشود:
find / -amin -60
جهت پیدا کردن تمام فایل هایی که حجم آنها ۵۰ مگابایت است از دستور زیر استفاده میکنیم:
find / -size 50M
جهت پیدا کردن تمام فایل هایی که حجم آنها بین ۵۰ تا ۱۰۰ مگابایت می باشد از دستور زیر استفاده میشود:
find / -size +50M -size -100M
جهت یافتن تمام فایل هایی که حجم آنها ۱۰۰ مگابایت است و حذف خودکار این فایل ها توسط دستور استفاده میکنیم:
find / -size +100M -exec rm -rf {} \;
جهت پیدا کردن تمام فایل های با پسوند mp3. که حجم آنها بیشتر از 10 مگابایت باشد و حذف خودکار آنها از دستور زیر استفاده میکنیم:
find / -type f -name *.mp3 -size +10M -exec rm {} \;
در دسته چهارم با مثال این موضوع را بررسی کردیم در این قسمت تصمیم داریم به صورت دقیق تر این بخش را بررسی کنیم در این بخش چگونگی پیدا کردن فایل ها بر اساس زمان گفته خواهد شد هر فایل شامل سه مهر زمانی Change Time - Access Time - Modift Time است. در ادامه سوئیچ های مرتبط با هر کدام از Timestamp های گفته شده در دستور find آورده شده است.
با استفاده از دستور stat میتوانستیم اطلاعات زمانی بالا را پیدا کنیم. اگر با دستور دستور cat فایلی را بخوانید به آن دسترسی داشته اید و زمان Access Time تغییر میکند. اگر با دستوری مانند دستور vi یا Vim محتوای یک فایل متنی را تغییر دهید زمان های Modift Time و Change Time تغییر میکند. اگر با دستور chmod مجوزهای فایل را تغییر دهید زمان Change Time تغییر میکند و برای دایرکتوری ها نیز اگر با دستور cd تغییر دایرکتوری به دایرکتوری جدید دهید زمان Access Time آن دایرکتوری جدید تغییر خواهد کرد. اگر با دستورهایی مانند دستور mkdir یا دستور touch فایل یا دایرکتوری جدیدی را ایجاد کنید یا اگر نام یا دایرکتوری را تغییر دهید زمان های Modift Time و Change Time تغییر میکنند و در نهایت مانند فایل اگر مجوز را با دستور chmod تغییر دهید زمان Change Time تغییر خواهد نمود. شکل کلی استفاده از آنها بصورت زیر است.
find <SEARCH_PATH> -atime X find <SEARCH_PATH> -mtime X find <SEARCH_PATH> -ctime X
X نشان دهنده روز است و اگر :
بطور مثال برای فهرست کردن تمامی فایل های زیر دایرکتوری etc/ که دقیقا ۷ روز پیش تغییر کرده اند از دستور زیر استفاده میکنیم:
find /etc -mtime 7
یا برای لیست کردن تمامی دایرکتوری هایی که در ۷ روز گذشته مورد دسترسی قرار گرفته اند از دستور زیر استفاده کنید:
find / -type d -atime 7 |less
برای پیدا کردن تمامی فایل ها با پسوند sh. که پیش از ۷ روز پیش تغییر کرده اند از دستور زیر استفاده میکنیم:
find ~ -mtime +7 -name "*.sh"|less
برای پیدا کردن فهرستی از فایل هایی که حجمی برابر ۱ مگابایت دارند و در ۷ روز گذشته تغییر کرده اند از دستور زیر استفاده کنید:
find / -type f -size 1M -mtime -7|less
دستور زیر فهرستی از فایل های pdf که در ۳۰ روز گذشته مورد دسترسی قرار گرفته اند را نشان میدهد.
find ~ -type f -iname "*.pdf" -atime -30
در مثال های بالا از سوئیچ هایی استفاده کردیم که خروجی را براساس X روز گذشته نشان می دادند. اگر بخواهیم که خروجی براساس X دقیقه پیش باشد باید به از سوئیچ های زیر استفاده کنیم.
و فرمت کلی آنها بصورت زیر است:
find <SEARCH_PATH> -amin X find <SEARCH_PATH> -mmin X find <SEARCH_PATH> -cmin X
X نشان دهنده روز است و اگر :
بطور مثال برای فهرست کردن تمامی دایرکتوری های زیر دایرکتوری etc/ که پیش از ۱ ساعت گذشته دسترسی داشته اند از دستور زیر استفاده میکنیم:
find /etc -type d -amin +60touch <file_name>
یا برای لیست کردن تمامی فایل هایی که دقیقا ۳۰ دقیقه قبل با پسوند sh. زیر دایرکتوری خانگی تان تغییر کرده اند از دستور زیر استفاده میکنیم:
find ~ -type f -name "*.sh" -mmin 30
در دسته سوم با مثال این موضوع را بررسی کردیم در این قسمت تصمیم داریم به صورت دقیق تر این بخش را بررسی کنیم در لینوکس هر فایل دارای مجوزهای: Write - Read و Exeute برای مالک (Owner) و گروه (Group) اصلی که کاربر عضو آن و دیگر افراد است. اگر میخواهید فایل هایی متعلق به یک گروه است را پیدا کنید از دستور find و به فرمت زیر استفاده کنید.
find directory-location -group {group-name} -name {file-name}
بطور مثال برای تعیین تمامی فایل های متعلق به کاربران گروه shell از دستور زیر استفاده کنید.
find ~ -group shell
یا برای یافتن تمامی فایل هایی که با sh. خاتمه میابند.
find /home -group shell -name "*.sh"
همچنین برای یافتن فایل های متعلق به یک کاربر خاص از دستور زیر استفاده کنید.
find directory-location -user {user-name} -name {file-name}
بطور مثال برای یافتن تمامی فایل های متعلق به کاربر phoenix که با sh. خاتمه می یابند.
find /home -user phoenix -name "*.sh"
اما مشکل خطوط بالا در این است که چون ما میخواهیم برای کاربر phoenix در زیر دایرکتوری home بگردیم پس قطعا ممکن است دیگر کاربران در دایرکتوری خانگی اشان فایل های داشته باشند که phoenix روی آنها مجوزی ندارد ساده ترین کار این است که به جای جستجو در دایرکتوری کلی تر home/ با دستور cd به دایرکتوری خود برویم و آنجا دستور را اجرا کنیم. اما شاید مجبور باشیم که در کل یک دایرکتوری جستجو کنیم پس بهتر است با مفاهیم Redirection خطاها را نشان ندهیم از دستور زیر برای نمایش ندادن خطای Permission Denied استفاده کنید.
find /home -user phoenix -name "*.sh" 2> /dev/null
یا میتوانید بصورت زیر عمل کنید که اگر فایل متعلق به شما بود در فایل access_list و اگر فایل متعلق به شما نبود در فایل denied_list ذخیره شوند.
find /home -user phoenix -name "*.sh" >~/access_list 2>~/denied_list
حالا با دستور cat فایل ها را بخوانید. اما اگر بخواهید بدانید چند فایل را دسترسی دارید و چند تا را دسترسی ندارید:
find /home -user phoenix -name "*.sh" 2>/dev/null|wc -l
یا
cat ~/access_list|wc -l
با دستور زیر میتوانید بدانید به چند فایل دسترسی ندارید.
cat ~/denied_list|wc -l
در این بخش تصمیم داریم با تلفیق دو دستور درون فایل ها جستجو کنیم و اگر کلمه ای مشابه مثلا کلمه manager پیدا شد آنرا با کلمه Phoenix جایگزین کند ما برای این منظور دستور sed را با find تلفیق کرده ایم
find . -type f -exec sed -i 's/manager/Phoenix/g' {} +