فهرست مندرجات

دستور find ( جستجوی فایل ها و دایرکتوری ها )

دستور find یکی از شگفت انگیزترین دستورات لینوکس است. با این دستور میتوانید کارهای بسیار جالبی انجام دهید. این دستور برای پیدا کردن فایلی در یک شاخه خاص و تمام زیرشاخه های آن استفاده میشود. به عبارت دیگر کاربرد دستور find پیدا کردن لیستی از فایل ها و پوشه ها بر اساس شرایط خاصی که توسط کاربر مشخص میشود. مثلا کاربر میتواند جستجو را براساس سطح دسترسی - کاربران - گروه ها - نوع فایل - تاریخ - اندازه و دیگر معیارهای ممکن انجام دهد.

find یکی از مهمترین و پراستفاده ترین دستورها در تمامی سیستم عامل های مبتنی بر لینوکس و یونیکس است که هر کاربر لینوکسی باید با آن آشنا باشد البته تفاوت هایی در syntax استفاده در find بین سیستم عامل های مبتنی بر یونیکس مانند:linux - BSD و Solaris وجود دارد اما نقاط اشتراک بیشتر هستند یک شکل کلی پایه برای استفاده از دستور find بصورت زیر است:

find <DIR_PATH>options

سوییچ name- و iname- جستجو بر اساس حساس به کوچکی و بزرگی یا برعکس

به عنوان اولین مثال برای یافتن فایل ها - دایرکتوری ها با آنها از سوئیچ 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- جستجو بر اساس نوع فایل

با استفاده از سوئیچ type- می توان جستجو را براساس نوع فایل ( دایرکتوری- فایل معمولی مانند فایل متنی و … ) انجام داد. دو مقدار f و d که به ترتیب یعنی file و دایرکتوری هستند. مقدار b برای Black Device ها و مقدار c برای Charactor Device ها استفاده میشود. بطور مثال برای یافتن دایرکتوری test اولین دستور زیر و برای یافتن تمامی Block Device ها از دومین دستور زیر استفاده کنید. در دومین دستور کاراکتر * به معنی تمامی فایل ها ( نام ها ) و حتما باید میان « » قرار گیرد.

find / -name test -type d
find / -name "*" -type b

سوییچ size- و empty- جستجو بر اساس اندازه یا تهی بودن

با استفاده از سوئیچ 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- جستجو بر اساس نفی نتیجه

از سوئیچ not- میتوان برای نفی نتیجه استفاده کرد. بطور مثال در مثال زیر تمامی فایل هایی که نامشان mysite.php نیست را پیدا میکند.

find / -not -iname mysite.php

سوییچ maxdepth- و mindepth- جستجو در حداکثر یا حداقل سطوح بعد دایرکتوری تعیین شده

سوئیچ 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

سوییچ inum- جستجو بر اساس inode

برای جستجوی فایلها بر اساس inode آنها از سوئیچ inum- که مخفف Inode Number است استفاده کنید. بطور مثال دستور زیر فایلی با inode494 را پیدا میکند.

find / -inum 494

سوییچ exec- ببعد از یافتین جستجو عملیات خاصی را انجام میدهد

با استفاده از سوئیچ exec- میتوان پس از یافتن فایل ها دستوری مانند rm برای حذف آنها را اجرا کرد. بطور مثال در دستور زیر پس از یافتن تمامی فایل های خالی در سیستم با اجرای دستور rm توسط سوئیچ exec- آنها پاک خواهند شد. سوئیچ exec- یعنی فایلها (مسیر و نام فایل ها) جایگزین {} شده و سپس توسط دستور rm پاک میشوند. اولین خط دستورهای زیر شکل کلی استفاده از سوئیچ exec- را نشان میدهد و دومین دستور مثالی برای پاک کردن تمامی فایل های خالی است.

find / -empty -exec rm -irf {} \;

کاربردهای دستور find

در ادامه مطلب به مهمترین کاربردهای دستور find خواهیم پرداخت و با ذکر مثال های متنوع هر یک را توضیح خواهیم داد. بطور کلی کاربردهای دستور find به ۵ دسته زیر تقسیم بندی میشوند:

دسته اول: پیدا کردن فایل ها بر اساس نام فایلها توسط دستور پایه find

جستجو فایل ها با استفاده از نام آنها در دایرکتوری جاری

جهت جستجو در تمام فایلهای دایرکتوری جاری که نام آنها test.txt باشد از دستور زیر استفاده میکنیم:

find / -name text.txt

پیدا کردن فایل ها در دایرکتوری home

جهت جستجو در تمام فایلهای موجود در دایرکتوری home که نام آنها test.txt باشد از دستور زیر استفاده میکنیم:

find ~ -name test.txt

پیدا کردن فایل ها بدون در نظر گرفتن بزرگی و کوچکی حروف آنها

جهت یافتن تمام فایل هایی که نام آنها test.txt که شامل حروف های بزرگ و کوچک میباشند از دستور زیر استفاده میکنیم:

find ~ -iname test.txt

پیدا کردن پوشه ها با توجه به نام آنها

برای پیدا کردن تمام دایرکتوری هایی که نام آنها test باشد در مسیر / می بایست از دستور زیر استفاده کرد:

find / -type d -name test

پیدا کردن فایل های php در دایرکتوری جاری براساس نام فایل

جهت پیدا کردن تمام فایل های php که در پوشه جاری بوده و نام آنها test.php باشد از دستور زیر استفاده میکنیم:

find . -name -type f test.php

پیدا کردن تمام فایلهای php در دایرکتوری جاری

جهت پیدا کردن تمام فایل هایی که پسوند آنها php. باشد در دایرکتوری جاری از دستور زیر استفاده میکنیم:

find . -type f -name "*.php"

دسته دوم: پیدا کردن فایل بر اساس سطح دسترسی

پیدا کردن فایل هایی که سطح دسترسی آنها ۷۷۷ باشد

جهت یافتن تمام فایل هایی که سطح دسترسی آنها ۷۷۷ باشد از دستور زیر استفاده میکنیم:

find . -type f -perm 0777 -print

پیدا کردن فایل هایی که سطح دسترسی آنها ۷۷۷ نباشد

جهت یافتن تمام فایل هایی که سطح دسترسی آنها ۷۷۷ نباشد از دستور زیر استفاده میکنیم:

find . -type f ! -perm 777

پیدا کردن فایل های SGID با سطح دسترسی 644

جهت یافتن فایل های sgid که سطح دسترسی آنها ۶۴۴ تنظیم شده است از دستور زیر استفاده میکنیم:

find / -perm 2644

پیدا کردن فایل های Sticky Bit با سطح دسترسی ۵۵۱

جهت یافتن تمام فایل هایی که بصورت Sticky Bit تنظیم شده اند و سطح دسترسی آنها ۵۵۱ است از دستور زیر استفاده میشود

find / -perm 1551

پیدا کردن فایل های SUID

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

find / -perm /u=s

پیدا کردن فایلهایی SGID

جهت یافتن فایل هایی که بصورت 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 {} \;

پیدا کردن و حذف کردن یک فایل توسط find

برای پیدا کردن یک فایل مانند text.txt و حذف خودکار آن از دستور زیر استفاده میشود:

find -type f -name "text.txt" -exec rm -f {} \;

پیدا کردن و حذف کردن دسته جمعی فایل ها توسط find

برای پیدا کردن و حذف کردن دسته جمعی فایل ها مانند پسوندهای 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 ".*"

دسته سوم: جستجو فایل ها بر اساس Owner ها و Group ها ( صاحبان فایل ها و گروه ها)

پیدا کردن یک فایل بر اساس یک Owner (صاحب)

برای پیدا کردن همه یا تنها یک فایل با اسم خاص در مسیر / که صاحب آنها root است از دستور زیر استفاده میشود

find / -user root -name text.txt

پیدا کردن تمام فایل هایی که صاحب (Owner) آنها یک کاربر است

پیدا کردن تمام فایل هایی که صاحب آن phoenix و در مسیر home باشند از دستور زیر استفاده میشود:

find ~ -user phoenix

پیدا کردن فایل ها بر اساس Group (گروه) آنها

جهت پیدا کردن تمام فایل های تحت Group (گروه ) Dev و در مسیر home از دستور زیر استفاده میکنیم:

find ~ -group dev

پیدا کردن یک فایل خاص تحت یک Owner

جهت یافتن یک فایل خاص که Owner آن کاربر phoenix باشد از دستور زیر استفاده میشود:

find ~ -user phoenix -iname "*.txt"

دسته چهارم: جستجوی فایل ها و پوشه ها بر اساس تاریخ و زمان

پیدا کردن فایل هایی که در ۵۰ روز اخیر اصلاح شده ( تغییر کرده modify شدن)

جهت پیدا کردن تمام فایل هایی که Modified time آنها برای ۵۰ روز اخیر باشد از دستور زیر استفاده میشود:

find / -mtime 50

پیدا کردن فایل هایی که در ۵۰ روز اخیر بازدید شده اند.( به فایل دسترسی پیدا شده است - accessed files )

جهت پیدا کردن تمام فایل هایی که در ۵۰ روز اخیر مشاهده شده اند از دستور زیر استفاده میشود:

find / -atime 50

پیدا کردن فایل هایی که بین ۵۰ تا ۱۰۰ روز modify شده اند

جهت یافتن تمام فایل هایی که بیشتر از ۵۰ روز و کمتر از ۱۰۰ روز modify شده اند از دستور زیر استفاده میکنیم:

find / -mtime +50 -mtime -100 

پیدا کردن فایل تغییر کرده در یک ساعت اخیر (Changed file)

جهت یافتن تمام فایل هایی که در یک ساعت اخیر تغییر کرده اند از دستور زیر استفاده میشود:

find / -cmin -60

پیدا کردن فایل های modify شده در یک ساعت اخیر

جهت پیدا کردن تمام فایل هایی که در یک ساعت اخیر modify شده اند از دستور استفاده میشود:

find / -mmin -60

پیدا کردن فایل های مشاهده شده در یک ساعت اخیر (accessed files)

جهت یافتن تمام فایل هایی که در یک ساعت اخیر مشاهده شده اند از دستور زیر استفاده میشود:

find / -amin -60

دسته پنجم: جستجو فایل ها و دایرکتوری ها بر اساس حجم آنها

پیدا کردن فایل های 50 مگابایتی

جهت پیدا کردن تمام فایل هایی که حجم آنها ۵۰ مگابایت است از دستور زیر استفاده میکنیم:

find / -size 50M

پیدا کردن فایل های ۵۰ تا ۱۰۰ مگابایت

جهت پیدا کردن تمام فایل هایی که حجم آنها بین ۵۰ تا ۱۰۰ مگابایت می باشد از دستور زیر استفاده میشود:

find / -size +50M -size -100M

پیدا کردن و حذف کردن خودکار فایل های ۱۰۰ مگابایتی

جهت یافتن تمام فایل هایی که حجم آنها ۱۰۰ مگابایت است و حذف خودکار این فایل ها توسط دستور استفاده میکنیم:

find / -size +100M -exec rm -rf {} \;

یافتن فایل های خاص و حذف آنها ( فایل های Specifile)

جهت پیدا کردن تمام فایل های با پسوند 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' {} +