Note:
- This answer probably goes deeper than the use case warrants, and
find 2>/dev/null
may be good enough in many situations. It may still be of interest for a cross-platform perspective and for its discussion of some advanced shell techniques in the interest of finding a solution that is as robust as possible, even though the cases guarded against may be largely hypothetical.
If your shell is bash
or zsh
, there’s a solution that is robust while being reasonably simple, using only POSIX-compliant find
features; while bash
itself is not part of POSIX, most modern Unix platforms come with it, making this solution widely portable:
find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
Note:
-
If your system is configured to show localized error messages, prefix the
find
calls below withLC_ALL=C
(LC_ALL=C find ...
) to ensure that English messages are reported, so thatgrep -v 'Permission denied'
works as intended. Invariably, however, any error messages that do get displayed will then be in English as well. -
>(...)
is a (rarely used) output process substitution that allows redirecting output (in this case, stderr output (2>
) to the stdin of the command inside>(...)
.
In addition tobash
andzsh
,ksh
supports them as well in principle, but trying to combine them with redirection from stderr, as is done here (2> >(...)
), appears to be silently ignored (inksh 93u+
).-
grep -v 'Permission denied'
filters out (-v
) all lines (from thefind
command’s stderr stream) that contain the phrasePermission denied
and outputs the remaining lines to stderr (>&2
). -
Note: There’s a small chance that some of
grep
‘s output may arrive afterfind
completes, because the overall command doesn’t wait for the command inside>(...)
to finish. Inbash
, you can prevent this by appending| cat
to the command.
-
This approach is:
-
robust:
grep
is only applied to error messages (and not to a combination of file paths and error messages, potentially leading to false positives), and error messages other than permission-denied ones are passed through, to stderr. -
side-effect free:
find
‘s exit code is preserved: the inability to access at least one of the filesystem items encountered results in exit code1
(although that won’t tell you whether errors other than permission-denied ones occurred (too)).
POSIX-compliant solutions:
Fully POSIX-compliant solutions either have limitations or require additional work.
If find
‘s output is to be captured in a file anyway (or suppressed altogether), then the pipeline-based solution from Jonathan Leffler’s answer is simple, robust, and POSIX-compliant:
find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
Note that the order of the redirections matters: 2>&1
must come first.
Capturing stdout output in a file up front allows 2>&1
to send only error messages through the pipeline, which grep
can then unambiguously operate on.
The only downside is that the overall exit code will be the grep
command’s, not find
‘s, which in this case means: if there are no errors at all or only permission-denied errors, the exit code will be 1
(signaling failure), otherwise (errors other than permission-denied ones) 0
— which is the opposite of the intent.
That said, find
‘s exit code is rarely used anyway, as it often conveys little information beyond fundamental failure such as passing a non-existent path.
However, the specific case of even only some of the input paths being inaccessible due to lack of permissions is reflected in find
‘s exit code (in both GNU and BSD find
): if a permissions-denied error occurs for any of the files processed, the exit code is set to 1
.
The following variation addresses that:
find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
Now, the exit code indicates whether any errors other than Permission denied
occurred: 1
if so, 0
otherwise.
In other words: the exit code now reflects the true intent of the command: success (0
) is reported, if no errors at all or only permission-denied errors occurred.
This is arguably even better than just passing find
‘s exit code through, as in the solution at the top.
gniourf_gniourf in the comments proposes a (still POSIX-compliant) generalization of this solution using sophisticated redirections, which works even with the default behavior of printing the file paths to stdout:
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
In short: Custom file descriptor 3
is used to temporarily swap stdout (1
) and stderr (2
), so that error messages alone can be piped to grep
via stdout.
Without these redirections, both data (file paths) and error messages would be piped to grep
via stdout, and grep
would then not be able to distinguish between error message Permission denied
and a (hypothetical) file whose name happens to contain the phrase Permission denied
.
As in the first solution, however, the the exit code reported will be grep
‘s, not find
‘s, but the same fix as above can be applied.
Notes on the existing answers:
-
There are several points to note about Michael Brux’s answer,
find . ! -readable -prune -o -print
:-
It requires GNU
find
; notably, it won’t work on macOS. Of course, if you only ever need the command to work with GNUfind
, this won’t be a problem for you. -
Some
Permission denied
errors may still surface:find ! -readable -prune
reports such errors for the child items of directories for which the current user does haver
permission, but lacksx
(executable) permission. The reason is that because the directory itself is readable,-prune
is not executed, and the attempt to descend into that directory then triggers the error messages. That said, the typical case is for ther
permission to be missing. -
Note: The following point is a matter of philosophy and/or specific use case, and you may decide it is not relevant to you and that the command fits your needs well, especially if simply printing the paths is all you do:
- If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any
find
command, then the opposite approach of proactively preventing permission-denied errors requires introducing «noise» into thefind
command, which also introduces complexity and logical pitfalls. - For instance, the most up-voted comment on Michael’s answer (as of this writing) attempts to show how to extend the command by including a
-name
filter, as follows:
find . ! -readable -prune -o -name '*.txt'
This, however, does not work as intended, because the trailing-print
action is required (an explanation can be found in this answer). Such subtleties can introduce bugs.
- If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any
-
-
The first solution in Jonathan Leffler’s answer,
find . 2>/dev/null > files_and_folders
, as he himself states, blindly silences all error messages (and the workaround is cumbersome and not fully robust, as he also explains). Pragmatically speaking, however, it is the simplest solution, as you may be content to assume that any and all errors would be permission-related. -
mist’s answer,
sudo find . > files_and_folders
, is concise and pragmatic, but ill-advised for anything other than merely printing filenames, for security reasons: because you’re running as the root user, «you risk having your whole system being messed up by a bug in find or a malicious version, or an incorrect invocation which writes something unexpectedly, which could not happen if you ran this with normal privileges» (from a comment on mist’s answer by tripleee). -
The 2nd solution in viraptor’s answer,
find . 2>&1 | grep -v 'Permission denied' > some_file
runs the risk of false positives (due to sending a mix of stdout and stderr through the pipeline), and, potentially, instead of reporting non-permission-denied errors via stderr, captures them alongside the output paths in the output file.
Note:
- This answer probably goes deeper than the use case warrants, and
find 2>/dev/null
may be good enough in many situations. It may still be of interest for a cross-platform perspective and for its discussion of some advanced shell techniques in the interest of finding a solution that is as robust as possible, even though the cases guarded against may be largely hypothetical.
If your shell is bash
or zsh
, there’s a solution that is robust while being reasonably simple, using only POSIX-compliant find
features; while bash
itself is not part of POSIX, most modern Unix platforms come with it, making this solution widely portable:
find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
Note:
-
If your system is configured to show localized error messages, prefix the
find
calls below withLC_ALL=C
(LC_ALL=C find ...
) to ensure that English messages are reported, so thatgrep -v 'Permission denied'
works as intended. Invariably, however, any error messages that do get displayed will then be in English as well. -
>(...)
is a (rarely used) output process substitution that allows redirecting output (in this case, stderr output (2>
) to the stdin of the command inside>(...)
.
In addition tobash
andzsh
,ksh
supports them as well in principle, but trying to combine them with redirection from stderr, as is done here (2> >(...)
), appears to be silently ignored (inksh 93u+
).-
grep -v 'Permission denied'
filters out (-v
) all lines (from thefind
command’s stderr stream) that contain the phrasePermission denied
and outputs the remaining lines to stderr (>&2
). -
Note: There’s a small chance that some of
grep
‘s output may arrive afterfind
completes, because the overall command doesn’t wait for the command inside>(...)
to finish. Inbash
, you can prevent this by appending| cat
to the command.
-
This approach is:
-
robust:
grep
is only applied to error messages (and not to a combination of file paths and error messages, potentially leading to false positives), and error messages other than permission-denied ones are passed through, to stderr. -
side-effect free:
find
‘s exit code is preserved: the inability to access at least one of the filesystem items encountered results in exit code1
(although that won’t tell you whether errors other than permission-denied ones occurred (too)).
POSIX-compliant solutions:
Fully POSIX-compliant solutions either have limitations or require additional work.
If find
‘s output is to be captured in a file anyway (or suppressed altogether), then the pipeline-based solution from Jonathan Leffler’s answer is simple, robust, and POSIX-compliant:
find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
Note that the order of the redirections matters: 2>&1
must come first.
Capturing stdout output in a file up front allows 2>&1
to send only error messages through the pipeline, which grep
can then unambiguously operate on.
The only downside is that the overall exit code will be the grep
command’s, not find
‘s, which in this case means: if there are no errors at all or only permission-denied errors, the exit code will be 1
(signaling failure), otherwise (errors other than permission-denied ones) 0
— which is the opposite of the intent.
That said, find
‘s exit code is rarely used anyway, as it often conveys little information beyond fundamental failure such as passing a non-existent path.
However, the specific case of even only some of the input paths being inaccessible due to lack of permissions is reflected in find
‘s exit code (in both GNU and BSD find
): if a permissions-denied error occurs for any of the files processed, the exit code is set to 1
.
The following variation addresses that:
find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
Now, the exit code indicates whether any errors other than Permission denied
occurred: 1
if so, 0
otherwise.
In other words: the exit code now reflects the true intent of the command: success (0
) is reported, if no errors at all or only permission-denied errors occurred.
This is arguably even better than just passing find
‘s exit code through, as in the solution at the top.
gniourf_gniourf in the comments proposes a (still POSIX-compliant) generalization of this solution using sophisticated redirections, which works even with the default behavior of printing the file paths to stdout:
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
In short: Custom file descriptor 3
is used to temporarily swap stdout (1
) and stderr (2
), so that error messages alone can be piped to grep
via stdout.
Without these redirections, both data (file paths) and error messages would be piped to grep
via stdout, and grep
would then not be able to distinguish between error message Permission denied
and a (hypothetical) file whose name happens to contain the phrase Permission denied
.
As in the first solution, however, the the exit code reported will be grep
‘s, not find
‘s, but the same fix as above can be applied.
Notes on the existing answers:
-
There are several points to note about Michael Brux’s answer,
find . ! -readable -prune -o -print
:-
It requires GNU
find
; notably, it won’t work on macOS. Of course, if you only ever need the command to work with GNUfind
, this won’t be a problem for you. -
Some
Permission denied
errors may still surface:find ! -readable -prune
reports such errors for the child items of directories for which the current user does haver
permission, but lacksx
(executable) permission. The reason is that because the directory itself is readable,-prune
is not executed, and the attempt to descend into that directory then triggers the error messages. That said, the typical case is for ther
permission to be missing. -
Note: The following point is a matter of philosophy and/or specific use case, and you may decide it is not relevant to you and that the command fits your needs well, especially if simply printing the paths is all you do:
- If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any
find
command, then the opposite approach of proactively preventing permission-denied errors requires introducing «noise» into thefind
command, which also introduces complexity and logical pitfalls. - For instance, the most up-voted comment on Michael’s answer (as of this writing) attempts to show how to extend the command by including a
-name
filter, as follows:
find . ! -readable -prune -o -name '*.txt'
This, however, does not work as intended, because the trailing-print
action is required (an explanation can be found in this answer). Such subtleties can introduce bugs.
- If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any
-
-
The first solution in Jonathan Leffler’s answer,
find . 2>/dev/null > files_and_folders
, as he himself states, blindly silences all error messages (and the workaround is cumbersome and not fully robust, as he also explains). Pragmatically speaking, however, it is the simplest solution, as you may be content to assume that any and all errors would be permission-related. -
mist’s answer,
sudo find . > files_and_folders
, is concise and pragmatic, but ill-advised for anything other than merely printing filenames, for security reasons: because you’re running as the root user, «you risk having your whole system being messed up by a bug in find or a malicious version, or an incorrect invocation which writes something unexpectedly, which could not happen if you ran this with normal privileges» (from a comment on mist’s answer by tripleee). -
The 2nd solution in viraptor’s answer,
find . 2>&1 | grep -v 'Permission denied' > some_file
runs the risk of false positives (due to sending a mix of stdout and stderr through the pipeline), and, potentially, instead of reporting non-permission-denied errors via stderr, captures them alongside the output paths in the output file.
Note:
- This answer probably goes deeper than the use case warrants, and
find 2>/dev/null
may be good enough in many situations. It may still be of interest for a cross-platform perspective and for its discussion of some advanced shell techniques in the interest of finding a solution that is as robust as possible, even though the cases guarded against may be largely hypothetical.
If your shell is bash
or zsh
, there’s a solution that is robust while being reasonably simple, using only POSIX-compliant find
features; while bash
itself is not part of POSIX, most modern Unix platforms come with it, making this solution widely portable:
find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
Note:
-
If your system is configured to show localized error messages, prefix the
find
calls below withLC_ALL=C
(LC_ALL=C find ...
) to ensure that English messages are reported, so thatgrep -v 'Permission denied'
works as intended. Invariably, however, any error messages that do get displayed will then be in English as well. -
>(...)
is a (rarely used) output process substitution that allows redirecting output (in this case, stderr output (2>
) to the stdin of the command inside>(...)
.
In addition tobash
andzsh
,ksh
supports them as well in principle, but trying to combine them with redirection from stderr, as is done here (2> >(...)
), appears to be silently ignored (inksh 93u+
).-
grep -v 'Permission denied'
filters out (-v
) all lines (from thefind
command’s stderr stream) that contain the phrasePermission denied
and outputs the remaining lines to stderr (>&2
). -
Note: There’s a small chance that some of
grep
‘s output may arrive afterfind
completes, because the overall command doesn’t wait for the command inside>(...)
to finish. Inbash
, you can prevent this by appending| cat
to the command.
-
This approach is:
-
robust:
grep
is only applied to error messages (and not to a combination of file paths and error messages, potentially leading to false positives), and error messages other than permission-denied ones are passed through, to stderr. -
side-effect free:
find
‘s exit code is preserved: the inability to access at least one of the filesystem items encountered results in exit code1
(although that won’t tell you whether errors other than permission-denied ones occurred (too)).
POSIX-compliant solutions:
Fully POSIX-compliant solutions either have limitations or require additional work.
If find
‘s output is to be captured in a file anyway (or suppressed altogether), then the pipeline-based solution from Jonathan Leffler’s answer is simple, robust, and POSIX-compliant:
find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
Note that the order of the redirections matters: 2>&1
must come first.
Capturing stdout output in a file up front allows 2>&1
to send only error messages through the pipeline, which grep
can then unambiguously operate on.
The only downside is that the overall exit code will be the grep
command’s, not find
‘s, which in this case means: if there are no errors at all or only permission-denied errors, the exit code will be 1
(signaling failure), otherwise (errors other than permission-denied ones) 0
— which is the opposite of the intent.
That said, find
‘s exit code is rarely used anyway, as it often conveys little information beyond fundamental failure such as passing a non-existent path.
However, the specific case of even only some of the input paths being inaccessible due to lack of permissions is reflected in find
‘s exit code (in both GNU and BSD find
): if a permissions-denied error occurs for any of the files processed, the exit code is set to 1
.
The following variation addresses that:
find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
Now, the exit code indicates whether any errors other than Permission denied
occurred: 1
if so, 0
otherwise.
In other words: the exit code now reflects the true intent of the command: success (0
) is reported, if no errors at all or only permission-denied errors occurred.
This is arguably even better than just passing find
‘s exit code through, as in the solution at the top.
gniourf_gniourf in the comments proposes a (still POSIX-compliant) generalization of this solution using sophisticated redirections, which works even with the default behavior of printing the file paths to stdout:
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
In short: Custom file descriptor 3
is used to temporarily swap stdout (1
) and stderr (2
), so that error messages alone can be piped to grep
via stdout.
Without these redirections, both data (file paths) and error messages would be piped to grep
via stdout, and grep
would then not be able to distinguish between error message Permission denied
and a (hypothetical) file whose name happens to contain the phrase Permission denied
.
As in the first solution, however, the the exit code reported will be grep
‘s, not find
‘s, but the same fix as above can be applied.
Notes on the existing answers:
-
There are several points to note about Michael Brux’s answer,
find . ! -readable -prune -o -print
:-
It requires GNU
find
; notably, it won’t work on macOS. Of course, if you only ever need the command to work with GNUfind
, this won’t be a problem for you. -
Some
Permission denied
errors may still surface:find ! -readable -prune
reports such errors for the child items of directories for which the current user does haver
permission, but lacksx
(executable) permission. The reason is that because the directory itself is readable,-prune
is not executed, and the attempt to descend into that directory then triggers the error messages. That said, the typical case is for ther
permission to be missing. -
Note: The following point is a matter of philosophy and/or specific use case, and you may decide it is not relevant to you and that the command fits your needs well, especially if simply printing the paths is all you do:
- If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any
find
command, then the opposite approach of proactively preventing permission-denied errors requires introducing «noise» into thefind
command, which also introduces complexity and logical pitfalls. - For instance, the most up-voted comment on Michael’s answer (as of this writing) attempts to show how to extend the command by including a
-name
filter, as follows:
find . ! -readable -prune -o -name '*.txt'
This, however, does not work as intended, because the trailing-print
action is required (an explanation can be found in this answer). Such subtleties can introduce bugs.
- If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any
-
-
The first solution in Jonathan Leffler’s answer,
find . 2>/dev/null > files_and_folders
, as he himself states, blindly silences all error messages (and the workaround is cumbersome and not fully robust, as he also explains). Pragmatically speaking, however, it is the simplest solution, as you may be content to assume that any and all errors would be permission-related. -
mist’s answer,
sudo find . > files_and_folders
, is concise and pragmatic, but ill-advised for anything other than merely printing filenames, for security reasons: because you’re running as the root user, «you risk having your whole system being messed up by a bug in find or a malicious version, or an incorrect invocation which writes something unexpectedly, which could not happen if you ran this with normal privileges» (from a comment on mist’s answer by tripleee). -
The 2nd solution in viraptor’s answer,
find . 2>&1 | grep -v 'Permission denied' > some_file
runs the risk of false positives (due to sending a mix of stdout and stderr through the pipeline), and, potentially, instead of reporting non-permission-denied errors via stderr, captures them alongside the output paths in the output file.
Иногда критически важно быстро найти нужный файл или информацию в системе. Порой можно ограничиться стандартами функциями поиска, которыми сейчас обладает любой файловый менеджер, но с возможностями терминала им не сравниться.
Команда find – это невероятно мощный инструмент, позволяющий искать файлы не только по названию, но и по:
- Дате добавления.
- Содержимому.
- Регулярным выражениям.
Данная команда будет очень полезна системным администраторам для:
- Управления дисковым пространством.
- Бэкапа.
- Различных операций с файлами.
Команда find в Linux производит поиск файлов и папок на основе заданных вами критериев и позволяет выполнять действия с результатами поиска.
Синтаксис команды find:
$ find directory-to-search criteria action
Где:
- directory-to-search (каталог поиска) – это отправной каталог, с которой find начинает поиск файлов по всем подкаталогам, которые находятся внутри. Если не указать путь, тогда поиск начнется в текущем каталоге;
- criteria (критерий) – критерий, по которым нужно искать файлы;
- action (действие) – что делать с каждым найденным файлом, соответствующим критериям.
Поиск по имени
Следующая команда ищет файл s.txt в текущем каталоге:
$ find . -name "s.txt"
./s.txt
Где:
- . (точка) – файл относится к нынешнему каталогу
- -name – критерии по которым осуществляется поиск. В данном случае поиск по названию файла.
В данном случае критерий -name учитывает только символы нижнего регистра и файл S.txt не появиться в результатах поиска. Чтобы убрать чувствительность к регистру необходимо использовать –iname.
$ find . -iname "s.txt"
./s.txt
./S.txt
Для поиска всех изображений c расширением .png нужно использовать шаблон подстановки *.png:
$ find . -name "*.png"
./babutafb.png
./babutafacebook.png
./Moodle2.png
./moodle.png
./moodle/moodle1.png
./genxfacebook.png
Можно использовать название каталога для поиска. Например, чтобы с помощью команды find найти все png изображения в каталоге home:
$ find /home -name "*.png"
find: `/home/babuta/.ssh': Permission denied
/home/vagrant/Moodle2.png
/home/vagrant/moodle.png
/home/tisha/hello.png
find: `/home/tisha/testfiles': Permission denied
find: `/home/tisha/data': Permission denied
/home/tisha/water.png
find: `/home/tisha/.cache': Permission denied
Если выдает слишком много ошибок в отказе разрешения, тогда можно добавить в конец команды – 2> /dev/null. Таким образом сообщения об ошибках будут перенаправляться по пути dev/null, что обеспечит более чистую выдачу.
find /home -name "*.jpg" 2>/dev/null
/home/vagrant/Moodle2.jpg
/home/vagrant/moodle.jpg
/home/tisha/hello.jpg
/home/tisha/water.jpg
Поиск по типу файла
Критерий -type позволяет искать файлы по типу, которые бывают следующих видов:
- f – простые файлы;
- d – каталоги;
- l – символические ссылки;
- b – блочные устройства (dev);
- c – символьные устройства (dev);
- p – именованные каналы;
- s – сокеты;
Например, указав критерий -type d будут перечислены только каталоги:
$ find . -type d
.
./.ssh
./.cache
./moodle
Поиск по размеру файла
Допустим, что вам необходимо найти все большие файлы. Для таких ситуаций подойдет критерий -size.
- «+» — Поиск файлов больше заданного размера
- «-» — Поиск файлов меньше заданного размера
- Отсутствие знака означает, что размер файлов в поиске должен полностью совпадать.
В данном случае поиск выведет все файлы более 1 Гб (+1G).
$ find . -size +1G
./Microsoft_Office_16.29.19090802_Installer.pkg
./android-studio-ide-183.5692245-mac.dmg
Единицы измерения файлов:
- c — Байт
- k — Кбайт
- M — Мбайт
- G — Гбайт
Поиск пустых файлов и каталогов
Критерий -empty позволяет найти пустые файлы и каталоги.
$ find . -empty
./.cloud-locale-test.skip
./datafiles
./b.txt
...
./.cache/motd.legal-displayed
Поиск времени изменения
Критерий -cmin позволяет искать файлы и каталоги по времени изменения. Для поиска всех файлов, измененных за последний час (менее 60 мин), нужно использовать -60:
$ find . -cmin -60
.
./a.txt
./datafiles
Таким образом можно найти все файлы в текущем каталоге, которые были созданы или изменены в течение часа (менее 60 минут).
Для поиска файлов, которые наоборот были изменены в любое время кроме последнего часа необходимо использовать +60.
$ find . -cmin +60
Поиск по времени доступа
Критерий -atime позволяет искать файлы по времени последнего доступа.
$ find . -atime +180
Таким образом можно найти файлы, к которым не обращались последние полгода (180 дней).
Поиск по имени пользователя
Опция –user username дает возможность поиска всех файлов и каталогов, принадлежащих конкретному пользователю:
$ find /home -user tisha 2>/dev/null
Таким образом можно найти все файлы пользователя tisha в каталоге home, а 2>/dev/null сделает выдачу чистой без ошибок в отказе доступа.
Поиск по набору разрешений
Критерий -perm – ищет файлы по определенному набору разрешений.
$ find /home -perm 777
Поиск файлов с разрешениями 777.
Операторы
Для объединения нескольких критериев в одну команду поиска можно применять операторы:
- -and
- -or
- -not
Например, чтобы найти файлы размером более 1 Гбайта пользователя tisha необходимо ввести следующую команду:
$ find /home -user tisha -and -size +1G 2>/dev/null
Если файлы могут принадлежать не только пользователю tisha, но и пользователю pokeristo, а также быть размером более 1 Гбайта.
$ find /home ( -user pokeristo -or -user tisha ) -and -size +1G 2>/dev/null
Перед скобками нужно поставить обратный слеш «».
Действия
К команде find можно добавить действия, которые будут произведены с результатами поиска.
- -delete — Удаляет соответствующие результатам поиска файлы
- -ls — Вывод более подробных результатов поиска с:
- Размерами файлов.
- Количеством inode.
- -print Стоит по умолчанию, если не указать другое действие. Показывает полный путь к найденным файлам.
- -exec Выполняет указанную команду в каждой строке результатов поиска.
-delete
Полезен, когда необходимо найти и удалить все пустые файлы, например:
$ find . -empty -delete
Перед удалением лучше лишний раз себя подстраховать. Для этого можно запустить команду с действием по умолчанию -print.
-exec:
Данное действие является особенным и позволяет выполнить команду по вашему усмотрению в результатах поиска.
-exec command {} ;
Где:
- command – это команда, которую вы желаете выполнить для результатов поиска. Например:
- rm
- mv
- cp
- {} – является результатами поиска.
- ; — Команда заканчивается точкой с запятой после обратного слеша.
С помощью –exec можно написать альтернативу команде –delete и применить ее к результатам поиска:
$ find . -empty -exec rm {} ;
Другой пример использования действия -exec:
$ find . -name "*.jpg" -exec cp {} /backups/fotos ;
Таким образом можно скопировать все .jpg изображения в каталог backups/fotos
Заключение
Команду find можно использовать для поиска:
- Файлов по имени.
- Дате последнего доступа.
- Дате последнего изменения.
- Имени пользователя (владельца файла).
- Имени группы.
- Размеру.
- Разрешению.
- Другим критериям.
С полученными результатами можно сразу выполнять различные действия, такие как:
- Удаление.
- Копирование.
- Перемещение в другой каталог.
Команда find может сильно облегчить жизнь системному администратору, а лучший способ овладеть ей – больше практиковаться.
Модераторы: /dev/random, Модераторы разделов
-
pavelvat
- Сообщения: 64
- ОС: Arch Linux i686
find — каким ключом отключить сообщения «Отказано в доступе»?
Код: Выделить всё
[user@myhost ~]$ find / -name "*http_cache_*"
find: `/proc/tty/driver': Отказано в доступе
find: `/proc/1/task/1/fd': Отказано в доступе
find: `/proc/1/task/1/fdinfo': Отказано в доступе
find: `/proc/1/fd': Отказано в доступе
find: `/proc/1/fdinfo': Отказано в доступе
find: `/proc/2/task/2/fd': Отказано в доступе
.
.
.
/usr/share/kde4/services/http_cache_cleaner.desktop
.
.
.
find: `/usr/lib/mozilla/extensions': Отказано в доступе
.
.
.
/usr/lib/kde4/libexec/kio_http_cache_cleaner
/usr/lib/libkdeinit4_kio_http_cache_cleaner.so
find: `/lost+found': Отказано в доступе
find: `/boot/lost+found': Отказано в доступе
-
flank’er
- Сообщения: 496
- Статус: слаковщик
- ОС: Slackware64
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит…
- ОС: Slackware-current
- Контактная информация:
Re: find — каким ключом отключить сообщения «Отказано в доступе»?
Сообщение
drBatty » 02.02.2010 09:52
wilgib писал(а): ↑
02.02.2010 01:04
2 > /dev/null ?
Спасибо.
Но у этого способа есть недостаток — убираются все сообщения об ошибках, а нужно только не замусоривать вывод сообщениями о директориях к которым нет доступа. Я подумал, что разработчики find предусмотрели такую возможность, но беглый просмотр
как-бы это сообщение об ошибке, как его можно убрать? Я-бы тоже не стал так делать.
Впрочем лекарство есть:
запустите find с ключём -type d и проверяйте второй find только в директориях в которых у вас есть доступ. Впрочем, проще отфильтровать эти сообщения, как сказано в прошлом посте.
-
pavelvat
- Сообщения: 64
- ОС: Arch Linux i686
Re: find — каким ключом отключить сообщения «Отказано в доступе»?
Сообщение
pavelvat » 03.02.2010 12:23
drBatty писал(а): ↑
02.02.2010 09:52
wilgib писал(а): ↑
02.02.2010 01:04
2 > /dev/null ?
Спасибо.
Но у этого способа есть недостаток — убираются все сообщения об ошибках, а нужно только не замусоривать вывод сообщениями о директориях к которым нет доступа. Я подумал, что разработчики find предусмотрели такую возможность, но беглый просмотркак-бы это сообщение об ошибке, как его можно убрать? Я-бы тоже не стал так делать.
Впрочем лекарство есть:
запустите find с ключём -type d и проверяйте второй find только в директориях в которых у вас есть доступ. Впрочем, проще отфильтровать эти сообщения, как сказано в прошлом посте.
Пожалуй, способ указанный flank’er наиболее простой, но и у него есть недостаток — если локаль произвольная.
Всё же интересно, можно ли добиться желаемого только средствами команды find, без организации конвеера?
-
drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит…
- ОС: Slackware-current
- Контактная информация:
Re: find — каким ключом отключить сообщения «Отказано в доступе»?
Сообщение
drBatty » 03.02.2010 12:46
wilgib писал(а): ↑
03.02.2010 12:23
если локаль произвольная.
Код: Выделить всё
drb@localhost:~$ ( LANG=C; find /etc -name "XXX" )
find: /etc/cups/ssl: Permission denied
find: /etc/samba/private: Permission denied
find: /etc/openvpn/certs: Permission denied
find: /etc/openvpn/keys: Permission denied
find: /etc/bluetooth/passkeys: Permission denied
drb@localhost:~$ find /etc -name "XXX"
find: /etc/cups/ssl: Отказано в доступе
find: /etc/samba/private: Отказано в доступе
find: /etc/openvpn/certs: Отказано в доступе
find: /etc/openvpn/keys: Отказано в доступе
find: /etc/bluetooth/passkeys: Отказано в доступе
wilgib писал(а): ↑
03.02.2010 12:23
Всё же интересно, можно ли добиться желаемого только средствами команды find, без организации конвеера?
ИМХО нет, разве что использовать -perm, -uid, что-бы не лазать в закрытые папки.
-
pavelvat
- Сообщения: 64
- ОС: Arch Linux i686
Re: find — каким ключом отключить сообщения «Отказано в доступе»?
Сообщение
pavelvat » 03.02.2010 15:11
drBatty писал(а): ↑
03.02.2010 12:46
wilgib писал(а): ↑
03.02.2010 12:23
если локаль произвольная.
Код: Выделить всё
drb@localhost:~$ ( LANG=C; find /etc -name "XXX" ) find: /etc/cups/ssl: Permission denied find: /etc/samba/private: Permission denied find: /etc/openvpn/certs: Permission denied find: /etc/openvpn/keys: Permission denied find: /etc/bluetooth/passkeys: Permission denied drb@localhost:~$ find /etc -name "XXX" find: /etc/cups/ssl: Отказано в доступе find: /etc/samba/private: Отказано в доступе find: /etc/openvpn/certs: Отказано в доступе find: /etc/openvpn/keys: Отказано в доступе find: /etc/bluetooth/passkeys: Отказано в доступе
Действительно, LANG=C решает проблему с произвольной локалью.
Команда find позволяет задействовать одноименную утилиту, предназначенную для поиска файлов в иерархии директорий файловой системы. Она позволяет задавать гибкие критерии поиска, генерировать форматированный вывод и выполнять пользовательские команды по отношению к найденным файлам.
Базовый синтаксис команды выглядит следующим образом:
$ find [параметры] [директория…] [выражение]
В случае утилиты find параметры используются достаточно редко: они позволяют регламентировать обработку символьных ссылок, задать уровень оптимизации выражения и передать параметры отладки. Так, параметр -P позволяет запретить переход по символьным ссылкам, параметр -L — разрешить переход по символьным ссылкам, а параметр -H — запретить переход по символьным ссылкам за исключением случаев обработки выражений, например, когда в качестве имени файла для сравнения используется символьная ссылка. Параметр -O позволяет задать уровень оптимизации выражения из диапазона от 0 до 3 и в подавляющем большинстве случаев не используется, как и параметр -D, предназначенный для передачи параметров отладки утилите.
Утилита может принимать неограниченное количество путей к директориям для поиска файлов, но чаще всего ей передается путь к единственной директории. Если не указано ни одного пути к директории, утилита будет искать файлы в текущей директории.
Основным параметром утилиты является выражение, которое подробно описывает интересующие пользователя файлы и действия, которые должны выполняться при их обнаружении. В том случае, если выражения не передано, считается, что пользователя интересуют все файлы и директории. В составе выражения могут присутствовать параметры выражения, проверки, действия и операторы.
Параметры выражения позволяют воздействовать на всю операцию, а не на обработку отдельного файла и всегда возвращают логическое значение true. По описанным причинам они должны располагаться в начале выражения. Наиболее важные параметры выражения приведены в таблице.
Параметр выражения | Назначение |
-daystart | Измерять время (для проверок -amin, -atime, -cmin, -ctime, -mmin, -mtime) с начала текущего дня, а не с 24 часов назад. |
-depth | Обрабатывать содержимое директорий до самих директорий. |
-follow | Переходить по символьным ссылкам. |
-help | Вывести справочную информацию и выйти. |
-ignore-readdir-race | Не выводить сообщение об ошибке, если файл был удален после чтения содержимого директории, но до использования вызова stat для получения его параметров. |
-maxdepth x | Осуществлять поиск в не более, чем x поддиректориях заданных директорий. |
-mindepth x | Осуществлять поиск в не менее, чем x поддиректориях заданных директорий. |
-regextype type | Использовать тип type регулярных выражений (emacs (по умолчанию), posix-awk, posix-basic, posix-egrep, posix-extended) |
-version | Вывести информацию о версии и выйти. |
-warn/-nowarn | Выводить/не выводить предупреждения. |
-xdev | Не исследовать директории на других файловых системах. |
Утилита поддерживает достаточно много выражений-проверок, возвращающих логические значения true и false. Чаще всего используется проверка -name для поиска файлов с заданным именем, но существует и множество других проверок, самые важные из которых приведены в таблице ниже.
Проверка | Назначение |
-amin x | Файл открыт x минут назад |
-anewer file | Файл открыт после открытия файла file |
-atime x | Файл открыт ранее, чем x дней назад |
-cmin x | Файл модифицирован x минут назад |
-cnewer file | Файл модифицирован после файла file |
-ctime x | Файл модифицирован ранее, чем x дней назад |
-empty | Файл пуст |
-executable | Файл является исполняемым |
-false | Возврат логического значения false |
-fstype fs | Файл расположен на файловой системе fs |
-gid id | Файлом владеет группа пользователей с идентификатором id |
-group group | Файлом владеет группа пользователей с именем group |
-ilname name | Символьная ссылка имеет имя name без учета регистра |
-iname name | Файл имеет имя name без учета регистра |
-inum x | Файл связан со структурой inode с номером x |
-ipath path | В пути к файлу присутствует фрагмент path без учета регистра |
-iregex regex | Путь к файлу соотвествует регулярному выражению regex без учета регистра |
-links x | Файл имеет x символьных ссылок |
-lname name | Символьная ссылка имеет имя name |
-mmin x | Файл модифицирован x минут назад |
-mtime x | Файл модифицирован x дней назад |
-name name | Файл имеет имя name |
-newer file | Файл модифицирован после файла file |
-nogroup | Файлом не владеет ни одна из существующих групп пользователей |
-nouser | Файлом не владеет ни один из существующих пользователей |
-path path | В пути к файлу присутствует фрагмент path |
-perm perm | Файл имеет права доступа perm |
-readable | Файл доступен для чтения |
-regex regex | Путь к файлу соотвествует регулярному выражению regex |
-samefile file | Файл связан с той же структурой inode, что и файл file |
-size x | Файл имеет размер x байт (для указания размера в других единицах используются модификаторы: b — 512-байтовые блоки, c — байты, w — двухбайтовые слова, k — килобайты, M — мегабайты, G — гигабайты) |
-true | Возврат логического значения true |
-type type | Файл относится к указанному типу type (b — блочное устройство, c — символьное устройство, d — директория, p — именованный канал FIFO, f — обычный файл, l — символьная ссылка, s — сокет) |
-uid id | Файлом владеет пользователь с идентификатором id |
-user user | Файлом владеет пользователь с именем user |
-writable | Файл доступен для записи |
В случае числовых значений x могут использоваться дополнительные модификаторы:
- +x — значение, большее x
- -x — значение, меньшее x
- x — ровно x
Помимо проверок утилита позволяет выполнять определенные действия по отношению к найденным файлам. Наиболее важные действия приведены в таблице.
Действие | Назначение |
-delete | Удалять найденные файлы. В случае корректного удаления возвращает true, в противном — false. |
-exec command ; | Выполнять команду command по отношению к каждому из найденных файлов. Возвращает true в случае получения нулевого статуса завершения команды, false — в противном случае. Последовательность {} заменяется на имя текущего файла, параметры команды задаются до символа ;. |
-exec command {} + | Вариант действия exec, в котором осуществляется объединение имен найденных файлов в рамках одной команды. Таким образом снижается количество создаваемых процессов. |
-execdir command ; | Аналог действия exec, исполняющий команду в поддиректории с найденным файлом. |
-execdir command {} + | Вариант действия execdir, в котором осуществляется объединение имен найденных файлов в рамках одной команды. Таким образом снижается количество создаваемых процессов. |
-fprint file | Записывает полное имя файла, завершающееся символом перехода на новую строку, в файл с именем file, всегда возвращая логическое значение true. |
-fprintf file format | Аналог действия printf, записывающий вывод в файл с именем file. Файл создается всегда, даже если в него не записывается имен файлов. |
-ok command ; | Вариант действия exec, в котором пользователю предлагается согласиться или отказаться от выполнения действия. В случае отказа возвращается логическое значение false. |
-okdir command ; | Вариант действия execdir, в котором пользователю предлагается согласиться или отказаться от выполнения действия. В случае отказа возвращается логическое значение false. |
Выводит полное имя файла, завершающееся символом перехода на новую строку, всегда возвращая логическое значение true. | |
-printf format | Выводит строку в заданном формате, всегда возвращая логическое значение true. Строка форматирования формируется по аналогии со строками форматирования языка C, но имеется множество нюансов, которые позволяют выводить информацию о найденных файлах. |
-quit | Немедленно завершает работу утилиты. |
Операторы в выражениях утилиты find используются по аналогии с операторами языков программирования. Наиболее важные операторы приведены в таблице.
Оператор | Назначение |
( expr ) | Исполнять выражение expr в первую очередь. Так как скобки являются специальными символами командной оболочки, следует использовать символы для экранирования. |
! expr | Возвращает логическое значение true, если результатом исполнения выражения expr является логическое значение false (логическое «не»). Символ восклицательного знака также должен экранироваться. |
-not expr | Аналог оператора !, совместимый с POSIX. |
expr1 expr2 | Два выражения объединяются с помощью неявного оператора -and (логическое «и»), то есть, expr2 не выполняется в том случае, если в результате исполнения expr1 получено логическое значение false. |
expr1 -a expr2 | Аналог expr1 expr2. |
expr1 -and expr2 | Аналог expr1 expr2, совместимый с POSIX. |
expr1 -o expr2 | Возвращает логическое значение true, если результатом исполнения выражения expr1 или expr2 является значение true и false в противном случае (логическое «или»). |
expr1 -or expr2 | Аналог expr1 -o expr2, совместимый с POSIX. |
expr1, expr2 | При использовании запятой оба выражения будут исполняться всегда. В качестве результата будет использоваться результат исполнения выражения expr2. |
Примеры использования
Вывод списка всех файлов в файловой системе
Для вывода списка всех доступных файлов может использоваться утилита find без каких-либо параметров.
$ find
.
./debian.patch
./Изображения
…
Поиск файлов без учета регистра имен
Для игнорирования регистра имен файлов следует использовать проверку -iname вместо -name. Например, для поиска файлов myClass.h, MyClass.h и так далее следует использовать команду:
$ find -iname myClass.h
Удаление найденных файлов
Если вам нужно удалить все найденные временные файлы с расширением .old, вы можете воспользоваться следующей командой:
$ find -type f -name "*.old" -delete
Учтите, что все файлы будут удалены, а не помещены в корзину, поэтому следует использовать данную команду с особой осторожностью.
Поиск файлов с заданным содержимым
Для поиска файлов с заданной строкой достаточно объединить функции утилит find и grep. В этом нет ничего сложного — достаточно использовать аналогичную команду:
$ find . -exec grep -H "Hello World" {} ;
grep: .: Это каталог
./main.d: MainWindow win = new MainWindow("Hello World");
./main.d: win.add(new Label("Hello World"));
grep: ./other: Это каталог
Символ точки с запятой является управляющим символом командной оболочки и должен экранироваться.
Поиск непустых файлов
Для поиска непустых файлов достаточно использовать оператор «не» и проверку пустого файла:
$ find -not -empty
.
./splash1280.jpg
./main.d
./other
./other/Better_Red_Than_Dead.rar
./nolf228.jpg
./splash1024.jpg