Як я можу виключити всі повідомлення "відмовлено у дозволі" із "знайти"?


794

Мені потрібно приховати всі відхилені в дозволі повідомлення від:

find . > files_and_folders

Я експериментую, коли виникає таке повідомлення. Мені потрібно зібрати всі папки та файли, до яких вони не виникають.

Чи можна спрямувати рівні дозволу на files_and_foldersфайл?

Як я можу приховати помилки одночасно?

Відповіді:


259

Примітка:
* Ця відповідь, ймовірно, йде глибше, ніж вимагає випадок використання, і find 2>/dev/nullможе бути досить хорошим у багатьох ситуаціях. Це все ще може представляти інтерес для кросплатформенної перспективи та для обговорення деяких передових методів оболонки, щоб знайти рішення, яке є максимально надійним, хоча випадки, щодо яких захищаються, можуть бути значною мірою гіпотетичними.
* Якщо ваша система налаштована на показ локалізованих повідомлень про помилки , приставте findвиклики нижче за допомогою LC_ALL=C( LC_ALL=C find ...), щоб переконатися в повідомленні англійських повідомлень, щоб це grep -v 'Permission denied'працювало за призначенням. Однак незмінно будь-які повідомлення про помилки, які відображаються, також будуть англійською мовою.

Якщо ваша оболонка є bashабоzsh є рішення, яке є надійним і при цьому досить просто , використовуючи лише сумісні з POSIX findфункції ; хоча bashсам по собі не є частиною POSIX, більшість сучасних платформ Unix поставляються з ним, що робить це рішення широко портативним:

find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)

Примітка: Є невеликий шанс, що деякий з grepрезультатів може надійти після find завершення, оскільки загальна команда не чекає завершення команди всередині >(...). У цьому bashви можете запобігти цьому, додавши | catдо команди.

  • >(...)є (рідко використовується) вихідний процес підстановки , який дозволяє перенаправляти висновок (в даному випадку, STDERR вихід ( 2>) на стандартне введення командного всередині >(...).
    Крім того , bashі zsh, kshпідтримує їх, а в принципі , але при спробі об'єднати їх з переадресацією з stderr , як це робиться тут ( 2> >(...)), здається, мовчки ігнорується (в ksh 93u+).

    • grep -v 'Permission denied'фільтри з ( -v) все лінії (від findпотоку Stderr командування) , які містять фразу Permission deniedі виводить залишилися рядки в стандартний потік помилок ( >&2).

Цей підхід:

  • надійний : grepзастосовується лише до повідомлень про помилки (а не до комбінації шляхів до файлів та повідомлень про помилки, що потенційно призводить до помилкових позитивів), а повідомлення про помилки, окрім відхилених дозволів, передаються в stderr.

  • Побічний ефект безкоштовно : find«сек код виходу зберігається: неможливість доступу принаймні один з елементів файлової системи , з якими стикаються результати в вихідному коді 1(хоча це не про те , який помилки інших відбулося , ніж дозволу, заборонені (теж)).


POSIX-сумісні рішення:

Повністю POSIX-сумісні рішення або мають обмеження, або потребують додаткової роботи.

Якщо findвисновок повинен бути зафіксований у файлі будь-яким чином (або придушений взагалі), то рішення на основі конвеєра відповіді Джонатана Леффлера є простим, надійним та POSIX-сумісним:

find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2

Зауважте, що порядок переадресацій має значення: 2>&1повинен бути першим .

Захоплення виводу stdout у передній частині файлу дозволяє 2>&1надсилати через конвеєр лише повідомлення про помилки, які grepпотім можуть однозначно працювати.

Єдиним недоліком є те, що загальний код виходу буде grepкомандування , а НЕ find«s, що в даному випадку означає: якщо немає жодної помилки на всіх або тільки помилки дозволу, відмовлено, код виходу буде 1(сигналізації збою ), в іншому випадку ( помилки, відмінні від дозволів, відмовлених у дозволі) 0- що протилежне наміру.
Однак, findвихідний код в будь-якому випадку використовується рідко , оскільки він часто передає мало інформації за рамки принципових збоїв, таких як проходження неіснуючого шляху.
Однак конкретний випадок навіть лише деякихз вхідних шляхів бути недоступні з - за відсутність дозволів буде відображений в find«s коді виходу (як в GNU і BSD find): якщо помилка дозволу-відмовляв відбувається для будь-якого з оброблюваних файлів, код виходу встановлюються в 1.

Наступні варіанти адреси, які:

find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }

Тепер код виходу вказує, чи були помилки, крім помилок Permission denied: 1якщо так, то в 0іншому випадку.
Іншими словами: код виходу тепер відображає справжній намір команди: повідомляється успіх ( 0), якщо помилок взагалі не було або лише помилок, відхилених дозволом.
Це, мабуть, навіть краще, ніж просто проходження findкоду виходу через, як у рішенні вгорі.


gniourf_gniourf в коментарях пропонує (все ще сумісні з POSIX) узагальнення цього рішення з використанням складних перенаправлень , що працює навіть при поведінці за замовчуванням друку шляхів файлів до stdout :

{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1

Коротше кажучи: спеціальний дескриптор файлу 3використовується для тимчасової заміни stdout ( 1) та stderr ( 2), щоб лише повідомлення про помилки можна було передати grepчерез stdout.

Без цих перенаправлень як дані (шляхи до файлів), так і повідомлення про помилки переносилися б grepчерез stdout, і grepтоді вони не змогли б розрізнити повідомлення про помилку Permission denied та (гіпотетичний) файл, ім'я якого містить фразу Permission denied.

Як і в першому рішенні, однак, вихідний код, про який повідомляється, буде grep's, не find', але може бути застосовано те саме виправлення, що вище.


Примітки до існуючих відповідей:

  • Є кілька моментів , щоб відзначити про відповіді Майкла Brux в , find . ! -readable -prune -o -print:

    • Це вимагає GNU find ; помітно, він не працюватиме на macOS. Звичайно, якщо вам потрібна лише команда для роботи з GNU find, це не буде для вас проблемою.

    • Деякі Permission deniedпомилки все ще можуть виникати : find ! -readable -pruneповідомляє про такі помилки для дочірніх елементів каталогів, на які поточний користувач має rдозвіл, але не має x(виконуваного) дозволу. Причина полягає в тому, що , оскільки сам каталог є читаним, -pruneне виконується, а спроба спуску в цей каталог , то викликає повідомлення про помилки. Однак, типовим випадком є rвідсутність дозволу.

    • Примітка. Наступний момент - це питання філософії та / або конкретного випадку використання, і ви можете вирішити, що він не стосується вас і що команда добре відповідає вашим потребам, особливо якщо ви просто робите просто друк шляхів:

      • Якщо ви концептуалізуєте фільтрування повідомлень про помилки, відхилені в дозволі, окремим завданням, яке ви хочете застосувати до будь-якої find команди, то протилежний підхід проактивного запобігання помилок, відхилених дозволом, вимагає введення команди "шум" у findкоманду, яка також вводить складність та логічні підводні камені .
      • Наприклад, найголовніший коментар до відповіді Майкла (станом на це написання) намагається показати, як розширити команду, включивши -nameфільтр, наступним чином:
        find . ! -readable -prune -o -name '*.txt'
        Це, однак, не працює за призначенням, тому що потрібна остання -printдія (пояснення можна знайти у цій відповіді ). Такі тонкощі можуть вводити помилки.
  • Перше рішення в відповідь Джонатан Леффлера , find . 2>/dev/null > files_and_foldersяк він сам стверджує, сліпо заглушає всі повідомлення про помилки (і обхідний шлях є громіздким і не в повній мірі надійною, як він пояснює). Практично кажучи , проте це найпростіше рішення , оскільки ви можете бути задоволеними припускати, що будь-які помилки пов'язані з дозволом.

  • Відповідь Туману , sudo find . > files_and_folders, є коротким і прагматичним, але необачний для будь-яких інших цілей, ніж просто друк імен файлів , з міркувань безпеки: тому що ви працюєте в якості кореневого користувача « , ви ризикуєте маючи всю систему будучи переплуталися помилкою в знахідку або зловмисна версія, або неправильна виклик, яка пише щось несподівано, що не могло статися, якщо ви запустили це зі звичайними привілеями "(з коментаря до відповіді туману від триплечі ).

  • Друге рішення в відповідь viraptor в , find . 2>&1 | grep -v 'Permission denied' > some_fileпрацює ризик помилкових спрацьовувань ( в зв'язку з відправкою поєднання стандартний висновок і стандартний потік помилок по трубопроводу), і, можливо, замість того, щоб повідомляти не є -permission-помилки відмови через STDERR, захоплює їх разом з вихідними шляхами у вихідному файлі.


4
Просто швидке запитання: чому ви використовуєте процес заміни, а не просто трубу find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2:?
gniourf_gniourf

2
@ LéoLéopoldHertz 준영: Якщо ви не хочете виводити на зовнішній файл, просто виконайте більше сантехніки:{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
gniourf_gniourf

2
@ LéoLéopoldHertz Just: Просто це сумісність з POSIX. Процесні заміни >(...)характерні для Баша.
gniourf_gniourf

2
Я не впевнений, що збереження коду виходу findмає бути підкреслено та рекламоване: findвихідний код, як відомо, марний. Тут, швидше за все, це буде не нульовим (і це марно).
gniourf_gniourf

3
POSIX явно вимагає execute/searchдозволу в режимі файлу для «пошуку» каталогу (вилучення вкладених файлів). findробить це для того, щоб спуститися у підкаталог (крім того, щоб вимагати readдозволу на перелік файлів у каталозі). Це не "помилка" чи "помилка переносу".
wjordan

542

Використання:

find . 2>/dev/null > files_and_folders

Це Permission denied, звичайно, приховує не лише помилки, але й усі повідомлення про помилки.

Якщо ви дійсно хочете зберегти інші можливі помилки, такі як занадто багато стрибків на посиланнях, але не відмовлено в дозволі, то, ймовірно, вам доведеться гадати, що у вас немає багатьох файлів під назвою "дозвіл відмовлено". і спробуйте:

find . 2>&1 | grep -v 'Permission denied' > files_and_folders

Якщо ви чітко хочете відфільтрувати лише стандартну помилку, ви можете скористатися більш складною конструкцією:

find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2

I / O Перенаправлення на findкоманди: 2>&1 > files_and_folders |. Труба перенаправляє стандартний вихід до grepкоманди і застосовується спочатку. 2>&1Відправляє стандартну помилку в тому ж місці , що і стандартний висновок (труби). > files_and_foldersПосилає стандартний висновок (але не стандартна помилка) в файл. Результатом цього є те, що повідомлення, записані на стандартну помилку, надсилаються вниз по трубі, а регулярний висновок findзаписується у файл. grepФільтрує стандартний висновок (ви можете вирішити , як селективні ви хочете бути, і , можливо , доведеться змінити написання в залежності від регіону і O / S) і кінцевого>&2означає, що повідомлення, що пережили помилку (записані на стандартний вихід), ще раз переходять до стандартної помилки. Остаточне перенаправлення може розглядатися як необов’язкове на терміналі, але було б дуже хорошою ідеєю використовувати його в сценарії, щоб повідомлення про помилки з’являлися на стандартній помилці.

На цю тему існує нескінченна кількість варіантів, залежно від того, що ви хочете зробити. Це буде працювати на будь-якому варіанті Unix з будь-яким похідним оболонки Bourne (Bash, Korn,…) та будь-якою сумісною з POSIX версією find.

Якщо ви хочете адаптуватися до конкретної findвашої версії вашої системи, можуть бути альтернативні варіанти. findЗокрема, GNU має безліч варіантів, недоступних в інших версіях - дивіться прийняту в даний час відповідь на один такий набір варіантів.


9
Якщо ви такі, як я, зауважте, що нестача місця важлива! 2>/dev/null, без місця!
Нік

20
Це 2>єдине ціле без пробілів; ви можете мати пробіл між ним та назвою файлу. Точно так само з іншими переадресації, наприклад, 2>&1(який перенаправляє стандартні помилки в тому ж самому місце , як стандартний висновок відбувається), або 2>&-який закриває стандартну помилку, і т.д. Див переадресаций для інших закривавлених деталей. (Код, наведений вище, - це оболонка, схожа на POSIX, не специфічна bash.)
Джонатан Леффлер,

3
Мені довелося скористатися з великої літери P, тому що це мій термінал виводить: find. 2> & 1 | grep -v 'Дозвіл відмовлено'
Девід Дорія

4
Як це прийнятне рішення? 1) Ви переспрямовуєте ВСІ помилки на dev / null 2) Ви фільтруєте явний рядок помилок !! Залежно від них чудово крихко, а що, якщо ваш файл знаходився в каталозі з назвою "дозволу відмовлено"? На жаль!
Gunchars

10
Я проти заперечення рядків помилок, щоб змінити вихід програми. Він буде працювати більшу частину часу, але просте не є правильним рішенням (знайдіть з перманентними відомостями нижче). Щоб навести приклад, чому це не буде працювати в OSX, оскільки помилка "Дозволено відмовлено". Те саме для будь-якої іншої системи, де є навіть незначні відмінності в рядку помилок (хтось інтернаціоналізує?)
Gunchars

285

Використання:

find . ! -readable -prune -o -print

або загалом

find <paths> ! -readable -prune -o <other conditions like -name> -print
  • щоб уникнути "дозволу відмовлено"
  • І НЕ придушуйте (інші) повідомлення про помилки
  • І отримати статус виходу 0 ("всі файли успішно обробляються")

Працює з: find (GNU findutils) 4.4.2. Фон:

  • -readableТест відповідає читаним файлів. !Оператор повертає істину, якщо тест є хибним. І ! -readableзбіги не читаються каталогів (& файлів).
  • -pruneДія не спускається в каталог.
  • ! -readable -prune можна перекласти: якщо каталог не читабельний, не спускайтесь до нього.
  • -readableТест враховує списки контролю доступу і інші дозволи артефактів які на -permтест ігнорованих.

Дивіться також find(1) manpage для більш детальної інформації.


6
відмінності вже згадуються. якщо ви не розумієте, то відповіді, можливо, для вас не мають ніякого значення? STDOUT те саме - STDERR відрізняється (ви отримуєте інші повідомлення про помилки з цією відповіддю) - $? відрізняється (чи 0 "успішно" з цією відповіддю, коли жодна інша помилка не виникає - завжди> 0 "не успішна" при переадресації на dev / null) - можливо, комусь потрібні "правильні" $? за сценарієм
Майкл Брукс

6
@Masi Найбільш очевидним недоліком є ​​відповідь Джонатана (grep -v) буде виключено ім'я файлу, який містить "Дозвіл відхилено" :)
Фрукт

65
Я вважаю за доцільне додати тут, що якщо вам потрібно додати деякі інші критерії пошуку, це слід зробити з -o:find . ! -readable -prune -o -name '*.txt'
tempestadept

22
Зауважте, що POSIX findне включає -readableопцію; також не findдля BSD, а отже і для Mac OS X (я не впевнений у інших системах). Отже, там, де ви findгарантовані GNU , це працює чудово, але не очевидно, як це адаптувати, якщо ви не можете гарантувати, що в системі встановлений GNU find. (Це буде добре працювати в Linux; він може, а може і не працюватиме в іншому місці.)
Джонатан Леффлер,

6
find . ! -readable -prune -o -name '*.txt'не працює на Ubuntu 14.04, використовуючи find 4.2.2. Це, здається, перемагає -name. З якихось дивних причин я маю успіхfind . \( ! -readable -prune \) -o -name '*.txt' -print
con-f-use

110

Якщо ви хочете почати пошук з кореня "/", ви, мабуть, побачите вихідний щось таке:

find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied

Це через дозвіл. Щоб вирішити це:

  1. Ви можете використовувати команду sudo:

    sudo find /. -name 'toBeSearched.file'

Він запитує пароль суперкористувача, при введенні пароля ви побачите результат, який ви дійсно хочете. Якщо у вас немає дозволу на використання команди sudo, що означає, що у вас немає пароля суперкористувача, спершу попросіть системного адміністратора додати вас до файлу sudoers.

  1. Ви можете використовувати перенаправлення стандартного виводу помилок з (як правило, дисплей / екран) на якийсь файл і уникати побачень повідомлень про помилки на екрані! переадресація до спеціального файлу / dev / null:

    find /. -name 'toBeSearched.file' 2>/dev/null
  2. Ви можете використовувати переадресацію стандартного виводу помилок з (загалом дисплей / екран) на стандартний вихід (загалом дисплей / екран), а потім передайте команду grep з параметром -v "інвертувати", щоб не бачити рядки виводу, у яких "Дозвіл відхилено" пари слів:

    find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'

7
@scottmrogowski за винятком того, що він не відповідає на питання ... 1. попросіть системного адміністратора додати вас до файлу sudoers. 2.sudo find...
Стівен

1
саме те, що я шукав!
DankMasterDan

92

Мені довелося користуватися:

find / -name expect 2>/dev/null

вказуючи назву того, що я хотів знайти, а потім сказав йому переспрямувати всі помилки на / dev / null

очікуйте, що це місце розташування програми очікування, яку я шукав.


3
@Masi, команда у відповіді не використовує expect. Натомість expectце просто ім'я файлу, який ця команда спробує знайти.
Друв Капур

2
Сліпо переспрямовування всіх виводів більш жорсткого типу, щоб ігнорувати один клас повідомлень про помилки, як правило, погана ідея - ви втратите всі інші довільні помилки в процесі.
Йосип Родін

59

Труба stderrз /dev/nullдопомогою 2> / Dev / нуль

find . -name '...' 2>/dev/null


2
Це добре працює для мене навіть на Mac OSX. Або навітьfind . -name '...' -print 2>/dev/null
тінь

30

Ви також можете використовувати -permі -pruneпредикати, щоб уникнути пониження в нечитабельних каталогах (див. Також Як видалити заяви про друк "відмовлено в дозволі" з програми пошуку? - Unix & Linux Stack Exchange ):

find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders

4
-perm -g+r,u+r,o+rпросто відповідає файлам, на яких rвстановлено дозвіл на (читання) для всіх 3 принципів безпеки файлу , що не має прямого зв'язку з тим, чи може поточний користувач читати цей файл чи ні. Він має можливість як пропустити файли, які може читати поточний користувач, так і відповідати файлам, які вони не можуть.
mklement0

Я думаю, find . -type d ! \( -perm -u+r -o -perm -g+r -o -perm -o+r \) -prune -o -printбуло б хорошим рішенням.
Mattia72

2
@ Mattia72: Ні, це принципово неможливо повністю емулювати -readableз -perm- см мій попередній коментар і розглянемо наступний приклад: echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=rвідбитки file, так як його користувач прочитав біт встановлений, але він відноситься до nobodyкористувача, а не поточні користувача. Поточний користувач не може прочитати цей файл; спробуйте cat file. Дивіться також: моя відповідь моя.
mklement0

23

Перенаправлення стандартної помилки. Наприклад, якщо ви використовуєте bash на машині Unix, ви можете перенаправити стандартну помилку на / dev / null, як це:

find . 2>/dev/null >files_and_folders

20

Хоча вищезазначені підходи не стосуються випадку для Mac OS X, оскільки Mac Os X не підтримує -readableкомутатор, саме так ви можете уникнути помилок "Дозволено відмовлено" у вашому виході. Це може комусь допомогти.

find / -type f -name "your_pattern" 2>/dev/null.

Якщо ви використовуєте якусь іншу команду find, наприклад, щоб знайти розмір файлів певного шаблону в каталозі 2>/dev/null, все одно буде працювати, як показано нижче.

find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$.

Це поверне загальний розмір файлів заданого шаблону. Зауважте команду 2>/dev/nullв кінці пошуку.


Приємна прив’язка до OS X! Відповідь Джонатана пояснює частину 2>/dev/null. Чи можете ви поясніть, будь ласка, частину -exec du -ch {} + 2>/dev/null | grep total$.
Лео Леопольд Герц

1
@Masi Ви можете використовувати будь-яку команду з -execопцією, щоб вжити подальших дій щодо файлів або каталогів, знайдених findкомандою. du -ch file_patternобчислює розмір кожного відповідного файлу, file_patternа останній рядок цього виводу - це загальна сума всіх файлів, які відповідають file_pattern. Див. Сторінку чоловіка для du. grep totalпросто фільтрує рядок, який витягує велику суму (яка є останнім рядком).
Bunti

13

Ці помилки роздруковуються на стандартний вихід помилок (fd 2). Щоб їх відфільтрувати, просто переспрямуйте всі помилки на / dev / null:

find . 2>/dev/null > some_file

або спочатку приєднайтесь до stderr та stdout, а потім виправте ці конкретні помилки:

find . 2>&1 | grep -v 'Permission denied' > some_file

11

Проста відповідь:

find . > files_and_folders 2>&-

2>&-закриває ( -) стандартний дескриптор файлу помилок ( 2), тому всі повідомлення про помилки замовчуються.

  • Вихідний код все одно буде, 1якщо в Permission deniedіншому випадку надрукуються помилки

Надійна відповідь для GNU find:

find . -type d \! \( -readable -executable \) -prune -print -o -print > files_and_folders

Передайте до findцього додаткові параметри -prune(не допускайте спускання в них), але все-таки -printбудь-який каталог ( ), який не має ( ) і дозволів, або ( ) жодного іншого файлу.-typed\!-readable-executable-o-print

  • -readableі -executableпараметри - це розширення GNU, що не є частиною стандарту POSIX
  • Можливо, все ще повернеться ' Permission denied' для аномальних / пошкоджених файлів (наприклад, див. Звіт про помилку, що впливає на файлові системи, встановлені на контейнерах, за допомогою lxcfs<v2.0.5)

Надійна відповідь, яка працює з будь-якими сумісними POSIX find(GNU, OSX / BSD тощо)

{ LC_ALL=C find . 3>&2 2>&1 1>&3 > files_and_folders | grep -v 'Permission denied'; [ $? = 1 ]; } 3>&2 2>&1

Використовуйте конвеєр для передачі стандартного потоку помилок grep, видаляючи всі рядки, що містять 'Permission denied'рядок.

LC_ALL=Cвстановлює локаль POSIX з допомогою змінної середовища , 3>&2 2>&1 1>&3і 3>&2 2>&1 дублюючі файлові дескриптори до труби потік стандартного помилка grep, і [ $? = 1 ]використовує , []щоб інвертувати код помилки , що повертається grepапроксимувати оригінальне поведінку find.

  • Також буде фільтруватися будь-які 'Permission denied'помилки через перенаправлення виводу (наприклад, якщо сам files_and_foldersфайл не піддається запису)

Як ви думаєте про пропозицію відповіді ЙордіФеррана? - - Чи можете ви порівняти свою відповідь на це?
Лео Леопольд Герц 준영

2
Сценарій оболонки цього відповіді, як зазначено, не має загального призначення (перераховує лише каталоги, що відповідають $ {m_find_name}), і містить кілька варіантів, що не стосуються питання (приємно, / home *, -maxdepth 5, -наступніше). Ця відповідь вирішує конкретні проблеми "фільтрації читабельних, але не виконуваних каталогів" більш стисло, залишаючись загальним призначенням.
wjordan

1
@wjordan: Дякую Я вилучив свої коментарі, але все-таки діє один момент: -permрішення, засноване на основі, не варто представляти, оскільки воно в принципі, ніж пропонується цитата, робить щось інше, ніж було призначено: це суто орієнтований на файли тест, що стосується власника файлу і група, жодна з яких має гарантовану зв'язок з користувачем викликом команди (див цієї відповіді моїх схоже , ваше переглянутими рішенням GNU тепер робити не дозволу зловити помилки відмову , що випливають з. файлів .
mklement0

Я не розпізнаю синтаксис, який ви використовуєте (ні як GNU, ні як BSD), але дозвольте мені проілюструвати свою точку на прикладі автономного прикладу: echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=rдрукує file, бо його біт для читання користувача встановлений, але він стосується nobodyкористувача , а не поточний користувач. Поточний користувач не може прочитати цей файл; спробуйте cat file.
mklement0

1
@ mklement0 дякую за обговорення, мені вдалося створити поведінку, яку ви описали в іншому тесті (не знаю, що я зробив неправильно в перший раз), здається, -permце не працює для визначення поточних дозволів користувача. Видалено цю альтернативу з цієї відповіді.
wjordan

4

Щоб уникнути лише попереджень, у яких відмовлено у попередженнях, скажіть, щоб знайти ігнорувати нечитабельні файли, обрізаючи їх із пошуку. Додайте вираз як АБО до своєї знахідки, наприклад,

find / \! -readable -prune -o -name '*.jbd' -ls

Це здебільшого говорить про (зіставити нечитабельний файл та обрізати його зі списку) АБО (зіставити ім’я типу * .jbd та відобразити його [з ls]) . (Пам’ятайте, що за замовчуванням вирази є AND'd разом, якщо ви не використовуєте -or.) У другому виразі вам потрібні -ls, або в іншому випадку ви можете додати дію за замовчуванням, щоб показати будь-яку відповідність, яка також покаже всі файли, які не можна прочитати .

Але якщо ви шукаєте реальних файлів у вашій системі, зазвичай немає підстав шукати в / dev, у якому багато файлів, тому вам слід додати вираз, який виключає цей каталог, наприклад:

find / -mount \! -readable -prune  -o  -path /dev -prune  -o  -name '*.jbd' -ls

Отже (збігайте нечитабельний файл та підрізайте зі списку) АБО (шлях відповідності / dev та чорнослив зі списку) АБО (файл відповідності типу * .jbd та покажіть його) .


4

використання

sudo find / -name file.txt

Дурне (тому що ти піднімаєш пошук) і незахищено, але писати набагато коротше.


Ви шукаєте тут всю файлову систему, так що ви маєте на увазі під цим "підвищити пошук". Чому ви називаєте це незахищеним? Тому що це пошук всієї файлової системи?
Лео Леопольд Герц 준영

2
Тому що sudo запускає команду find з дозволами root, що в основному є поганою ідеєю. Порушуються принципи сегрегації та найменших пільг.
туман

3
"Піднесення" тут полягає в привілеях, коріння, с sudo. Ви ризикуєте заплутати всю вашу систему помилкою findабо зловмисною версією або неправильним викликом, який записує щось несподівано, що не могло статися, якщо ви запустили це із звичайними привілеями.
трійка

2

Жодна з наведених відповідей не працювала для мене. Що б я не знайшов в Інтернеті, фокусується на: прихованні помилок. Жоден належним чином не обробляє код повернення / вихідний код процесу. Я використовую команду find у bash-скриптах, щоб знайти деякі каталоги, а потім перевірити їх вміст. Я оцінюю команду пошуку успіху за допомогою виходу-коду: значення нуля працює, інакше не працює.

Відповідь Наведений вище по Майкл Brux іноді працює. Але в мене є один сценарій, в якому він провалюється! Я виявив проблему і вирішив її самостійно. Мені потрібно обрізати файли, коли:

it is a directory AND has no read access AND/OR has no execute access

Дивіться ключове питання тут: І / АБО. Один з хороших запропонованих нами послідовностей умов:

-type d ! -readable ! -executable -prune

Це працює не завжди. Це означає, що чорнослив спрацьовує, коли відповідає:

it is directory AND no read access AND no execute access

Ця послідовність виразів виходить з ладу, коли доступ для читання надається, але немає доступу до виконання.

Після деякого тестування я зрозумів це і змінив своє рішення сценарію оболонки на:

приємна знахідка / home * / -maxdepth 5-слідуюча \
    \ (-тип d -a ! \ (-читабельна -a -виконана \) \) -prune \
    -o \
    \ (-тип d -a -читабельна -a - виконується -a -name "$ {m_find_name}" \) -принт

Ключовим тут є розміщення "неправдивого" для комбінованого виразу:

has read access AND has execute access

Інакше він не має повного доступу, а це означає: обрізати його. Це виявилося для мене одним із сценаріїв, попередні запропоновані рішення не вдалися.

Надаю нижче технічні деталі для запитань у розділі коментарів. Прошу вибачення, якщо деталі надмірні.

  • ¿Навіщо використовувати команду nice? У мене тут ідея . Спочатку я думав, що було б непогано зменшити пріоритет процесу під час перегляду всієї файлової системи. Я зрозумів, що для мене це не має сенсу, оскільки мій сценарій обмежений кількома каталогами. Я знизив-maxx на 3.
  • ¿Навіщо шукати в / home * /? Це не стосується цієї теми. Я встановлюю всі програми вручну за допомогою компіляції вихідного коду з непривілейованими користувачами (не root). Вони встановлюються в межах "/ home". Я можу мати кілька бінарних файлів та версій, які живуть разом. Мені потрібно знаходити всі каталоги, перевіряти та створювати резервні копії в режимі «master-slave». У мене може бути декілька "/ home" (кілька дисків, що працюють на виділеному сервері).
  • ¿Навіщо використовувати-нижче? Користувачі можуть створювати символьні посилання на каталоги. Це корисність залежить, мені потрібно вести облік знайдених абсолютних шляхів.

Дякую за вашу відповідь та приємні спостереження! Я відкрив щедроту, щоб краще переглянути вашу відповідь. Я думаю, що це приємна знахідка, яка не заважає читати та виконувати доступ. - - Чи можете ви пояснити, чому ви використовуєте niceта find $HOME -maxdepth 5 -follow ...?
Лео Леопольд Герц 준영

2
Сценарій оболонки , як зазначено не загальне призначення (тільки списки каталоги відповідність ${m_find_name}), і містить кілька варіантів , які не мають відношення до даного питання ( nice, /home*, -maxdepth 5, -follow). Я додав відповідь, яка вирішує конкретну проблему "фільтрації читабельних, але не виконуваних каталогів" більш стисло, залишаючись загальним призначенням.
wjordan

2

Ви можете використовувати grep -v invert-match

-v, --invert-match        select non-matching lines

подобається це:

find . > files_and_folders
cat files_and_folders | grep -v "permission denied" > files_and_folders

Слід до магії


2

- = Для MacOS = -

Створіть нову команду за допомогою псевдоніму: просто додайте у рядок ~ / .bash_profile:

alias search='find / -name $file 2>/dev/null'

і в новому вікні терміналу ви можете його зателефонувати:

$ file=<filename or mask>; search

наприклад:

$ файл = тощо; пошук


1

Якщо ви використовуєте CSH або TCSH, ось таке рішення:

( find . > files_and_folders ) >& /dev/null

Якщо ви хочете вихід на термінал:

( find . > /dev/tty ) >& /dev/null

Однак, як описує FAQ "csh-whynot", ви не повинні використовувати CSH.


Я хочу зібрати всі файли txt та виключити приховані файли / каталоги, опустити надруковане повідомлення "Дозвіл відхилено". Я використовую оболонку csh. Я використовував команди нижче, і вони не працюють. -тип f -iname " .txt" -not-шлях '* / \. '| egrep -v "Дозвіл відхилено". -тип f -iname " .txt" -not-шлях '* / \. '2> / dev / null Потрапляючи нижче Помилка. find: шляху повинні передувати виразу: 2 Використання: find [-H] [-L] [-P] [-Olevel] [-D help | tree | search | stat | rate | opt | exec] [path ...] [вираз]
ядов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.