Как рекурсивно установить права доступа к каталогу при поиске, в котором отсутствует -exec?

Использование tar с компрессией lz4, как в

tar cvf - myFolder | lz4 > myFolder.tar.lz4

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

Дополнительная литература :сравнение алгоритмов сжатия Как смолить с помощью lz4

5
23.05.2021, 11:50
3 ответа

Вывод findвыдает имена файлов, разделенные символами новой строки 1 . Это не тот формат, который нужен xargs, и findне может создать формат, который нужен xargs:он анализирует ввод как элементы, разделенные пробелами -, а \'"используется для цитирования. Некоторые версии xargsмогут принимать ввод, разделенный новой строкой -, но если в вашем findотсутствуют стандартные параметры, скорее всего, в вашем xargsони тоже есть.

find. -type d | xargs chmod g+sработает до тех пор, пока имена ваших каталогов не содержат пробелов или \'". Обратите внимание, что$1:не имеет значения для оболочки, но никакая оболочка не участвует в синтаксическом анализе вывода findи передаче его в chmod, только xargs.

Если ваш findимеет -print0, а ваш xargsимеет -0, вы можете использовать эти параметры для передачи имен файлов с нулевыми -разделителями, что работает с произвольными именами файлов.

find. -type d -print0 | xargs -0 chmod g+s

Если ваш xargsподдерживает стандартную опцию -I, вы можете использовать ее, чтобы указать обрабатывать каждую строку как элемент вместо пустых -строк, разделенных кавычками. Это работает с пробелами, но не с \"'или новыми строками.

find. -type d | xargs -I {} chmod g+s {}

Вы можете использовать оболочку для перебора строк вместо xargs. Это работает для любого имени файла, которое не содержит символов новой строки.

find. -type d | while IFS= read -r line; do chmod g+s "$line"; done

Оба эти решения работают только с именами файлов, которые не содержат символов новой строки. Вывод findс именами файлов, содержащими новые строки, неоднозначен, за исключением одного случая, который сложно анализировать.:findне будет спонтанно испускать множественные косые черты, поэтому, если вы поместите //в путь к каталогу для перехода, вы можете распознать это в выводе. Вот некоторый минимально протестированный код, использующий этот факт для преобразования вывода из findво входной формат xargs.

chars=$(printf '\t "'\\\')
{ find.//. -type d; echo.// } | LC_ALL=C sed -n '
s/['"$chars"']/\\&/g
/^\.\/\// {
x
s/\n/\\&/g
p
b
}
H' | LC_ALL=C xargs chmod g+s

1Точнее, :оканчивается символом новой строки (есть новая строка после фамилии ).

12
28.07.2021, 11:30

Вы можете указать xargs использовать \0 в качестве разделителяfind. -type d -print0 | xargs -0 chmod g+s

или

find. -type d | xargs -I{} -d '\n' chmod g+s "{}". Он будет использовать \n в качестве разделителя.

1
28.07.2021, 11:30

Вы можете сделать рекурсию самостоятельно с помощью bash. Что-то вроде:

shopt -s nullglob dotglob
recurse_chmod () (
  cd "$1"
  for d in./*/
  do
    if [ -L "$d" ]; then continue; fi
    chmod g+s "$d"
    recurse_chmod "$d"
  done
)
recurse_chmod.
4
28.07.2021, 11:30

Теги

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