Ограничить POSIX find определенной глубиной?

Можно просто сохранить пароль luks в файле.

Я использую это на своем домашнем компьютере; Корневая файловая система находится на обычном томе luks, который я разблокирую с помощью кодовой фразы при загрузке. Дополнительный диск содержит том luks со сгенерированным паролем.

Этот дополнительный том разблокирован файлом паролей, который находится в зашифрованной корневой файловой системе. Он автоматически разблокируется во время загрузки, если разблокирована корневая файловая система.

Мой / etc / crypttab выглядит так:

crypt-root UUID=c5a2cf25-0aae-457e-874f-fca7ea3d5742 none luks
crypt-data UUID=96d79323-246d-49e0-9149-ec3a4cfc1c1e /etc/crypt-data.key luks

Третье поле - это ключевой файл, нет для корневой файловой системы, но / etc / crypt-data .key для файловой системы данных. /etc/crypt-data.key содержит пароль luks:

Tm90IHJlYWxseSBteSBwYXNzd29yZC4K

Обратите внимание, что новая строка или любой другой пробел будет использоваться как часть пароля! Позаботьтесь о том, чтобы сгенерировать этот файл без символа новой строки. Также убедитесь, что у него есть строгие разрешения:

-rw------- 1 root root 59 Sep 14 23:57 /etc/crypt-data.key

Вы должны иметь возможность дублировать этот подход для нескольких томов (либо с разными паролями, либо с одним общим паролем, на ваш выбор).

15
11.04.2016, 09:14
2 ответа
Подход

@meuh неэффективен, поскольку его подход -maxdepth 1 по-прежнему позволяет найти читать содержимое каталогов на уровне 1, чтобы позже игнорировать их в противном случае. Он также не будет работать должным образом с некоторыми реализациями find (включая GNU find ), если некоторые имена каталогов содержат последовательности байтов, которые не образуют допустимые символы в локали пользователя (например, для файла имена в другой кодировке символов).

find . \( -name . -o -prune \) -extra-conditions-and-actions

- это более канонический способ реализации GNU -maxdepth 1 (или FreeBSD -depth -2 ).

Как правило, вам нужна -глубина 1 ( -mindepth 1 -maxdepth 1 ), которую вы не хотите рассматривать . (глубина 0), а затем еще проще:

find . ! -name . -prune -extra-conditions-and-actions

Для -maxdepth 2 это становится:

find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions

И здесь вы запускаете проблемы с недопустимыми символами.

Например, если у вас есть каталог с именем Stéphane , но этот é закодирован в кодировке iso8859-1 (также известной как latin1) (байт 0xe9), как это было наиболее распространено на Западе В Европе и Америке до середины 2000-х годов этот байт 0xe9 не является допустимым символом в UTF-8. Таким образом, в языковых стандартах UTF-8 подстановочный знак * (с некоторыми реализациями find ) не будет соответствовать Stéphane , поскольку * равен 0 или больше символов и 0xe9 не является символом.

$ locale charmap
UTF-8
$ find . -maxdepth 2
.
./St?phane
./St?phane/Chazelas
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
$ find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St?phane/Chazelas/age
./St?phane/Chazelas/gender
./St?phane/Chazelas/address
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith

Моя find (когда вывод поступает на терминал) отображает этот недопустимый байт 0xe9 как ? выше.Вы можете видеть, что St <0xe9> phane / Chazelas не был черносливом d.

Вы можете обойти это, выполнив следующие действия:

LC_ALL=C find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions

Но обратите внимание, что это влияет на все локальные настройки find и любое приложение, которое оно запускает (например, через предикаты -exec ). .

$ LC_ALL=C find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St??phane
./St??phane/Chazelas
./John
./John/Smith

Теперь я действительно получаю -maxdepth 2 , но обратите внимание, как é во втором Стефане, правильно закодированном в UTF-8, отображается как ?? как байты 0xc3 0xa9 ( рассматриваются как два отдельных неопределенных символа в локали C) в кодировке UTF-8 символа é не являются печатными символами в локали C.

И если бы я добавил -имя '????????' , я бы получил неправильный Стефан (тот, который закодирован в iso8859-1).

Применяется к произвольным путям вместо . , вы должны сделать:

find some/dir/. ! -name . -prune ...

для -mindepth 1 -maxdepth 1 или:

find some/dir/. \( ! -path '*/./*/*' -o -prune \) ...

для -maxdepth 2 .

Я бы все равно сделал:

(cd -P -- "$dir" && find . ...)

Во-первых, потому что это делает пути короче, что снижает вероятность попадания в путь слишком длинный или список аргументов слишком длинный проблемы, но также чтобы обойти тот факт, что find не может поддерживать произвольные аргументы пути (за исключением -f с FreeBSD find ), поскольку он подавится значениями ] $ dir нравится ! или -print ...


-o в сочетании с отрицанием - это обычный прием для запуска двух независимых наборов -условия / -действие в найти .

Если вы хотите запустить -action1 для файлов, соответствующих -condition1 и независимо -action2 , для файлов, соответствующих -condition2 , вы невозможно:

find . -condition1 -action1 -condition2 -action2

Поскольку -action2 будет выполняться только для файлов, которые удовлетворяют обоим условиям.

Также:

find . -contition1 -action1 -o -condition2 -action2

Поскольку -action2 не будет запускаться для файлов, которые удовлетворяют обоим условиям.

find . \( ! -condition1 -o -action1 \) -condition2 -action2

работает так, как \ (! -Condition1 -o -action1 \) преобразуется в true для каждого файла. Предполагается, что -action1 - это действие (например, -prune , -exec ... {} + ), которое всегда возвращает true . Для таких действий, как -exec ... \; , которые могут возвращать false , вы можете добавить еще один -o -something где -something безвреден, но возвращает true , например -true в GNU find или -links +0 или -name '* ' (хотя обратите внимание на проблему с недопустимыми символами выше).

21
27.01.2020, 19:50

Я столкнулся с проблемой, когда мне нужно было ограничить глубину при поиске по нескольким путям (вместо просто.).

Например:

$ find dir1 dir2 -name myfile -maxdepth 1

Это привело меня к альтернативному подходу, использующему -регулярное выражение. Суть:

-regex '(<list of paths | delimited>)/<filename>'

Таким образом, приведенное выше будет:

$ find dir1 dir2 -name myfile -regextype awk -regex '(dir1|dir2)/myfile' # GNU
$ find -E dir1 dir2 -name myfile -regex '(dir1|dir2)/myfile' # MacOS BSD

Без имени файла:

$ find dir1 dir2 -name myfile -maxdepth 1 # GNU

-regex '(<list of paths | delimited>)/<anything that's not a slash>$'

$ find dir1 dir2 -name myfile -regextype awk -regex '(dir1|dir2)/[^/]*$' # GNU
$ find -E dir1 dir2 -name myfile -regex '(dir1|dir2)/[^/]*$' # MacOS BSD

Наконец, для -maxdepth 2регулярное выражение меняется на:'(dir1|dir2)/([^/]*/){0,1}[^/]*$'

0
27.01.2020, 19:50

Теги

Похожие вопросы