-x для всех файлов (не трогая катологи)

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Аватара пользователя
AlexYeCu
Сообщения: 1137
ОС: fedora

-x для всех файлов

Сообщение AlexYeCu »

Задача: пройтись по всем каталогам и сделать неисполняемыми файлы по маске (к примеру, *.txt), не трогая права каталогов. Если в качестве маски можно использовать mime-тип — вообще отлично.
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: -x для всех файлов

Сообщение allez »

Можно так, например:

Код: Выделить всё

find -type f -iname "*.txt" -exec chmod a-x {} \;


P. S. Для общего развития рекомендую прочесть статью "Утилита find как универсальный файловый инструмент" ну и, конечно, man find. :)
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: -x для всех файлов

Сообщение ZyX »

AlexYeCu писал(а):
27.03.2010 13:02
Задача: пройтись по всем каталогам и сделать неисполняемыми файлы по маске (к примеру, *.txt), не трогая права каталогов. Если в качестве маски можно использовать mime-тип — вообще отлично.

Для zsh можно обойтись и без find:

zyx@zyx-desktop

% setopt extendedglob % chmod a-x ./**/*(^/)

Для того, чтобы использовать mime-type в качестве шаблона:

zyx@zyx-desktop

% chmod a-x ./**/*(e.'file --brief --mime-type ${REPLY} | grep -q -x text/plain'.^/)

Вообще, если вы используете zsh, то про find может забыть.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5405
ОС: Gentoo

Re: -x для всех файлов

Сообщение /dev/random »

ZyX писал(а):
27.03.2010 23:59
Для zsh можно обойтись и без find:

zyx@zyx-desktop

% setopt extendedglob % chmod a-x ./**/*(^/)

В bash тоже так можно. Только будет не "extendedglob", а "globstar", и не (), а []

Вот только так легко напороться на лимит длины ком. строки. ведь весь этот список будет раскрываться оболочкой и передваться одной команде.
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: -x для всех файлов

Сообщение ZyX »

/dev/random писал(а):
28.03.2010 01:00
ZyX писал(а):
27.03.2010 23:59
Для zsh можно обойтись и без find:

zyx@zyx-desktop

% setopt extendedglob % chmod a-x ./**/*(^/)

В bash тоже так можно. Только будет не "extendedglob", а "globstar", и не (), а []

Вот только так легко напороться на лимит длины ком. строки. ведь весь этот список будет раскрываться оболочкой и передваться одной команде.

Как я понял, к собственным командам zsh это не относится. Поэтому для слишком
длинного списка можно применить цикл.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5405
ОС: Gentoo

Re: -x для всех файлов

Сообщение /dev/random »

ZyX писал(а):
28.03.2010 05:39
Поэтому для слишком длинного списка можно применить цикл.

Можно. Но это будет уже длиннее, чем find. И для большого количества файлов - медленнее.
Спасибо сказали:
Аватара пользователя
Luinnar
Сообщения: 246
ОС: Solaris, Debian, Ubuntu

Re: -x для всех файлов

Сообщение Luinnar »

ИМХО find в этом случае как-то по проще выглядит. :)

И кстати, здесь лучше + в конце использовать, а не \; :

Код: Выделить всё

find -type f -iname "*.txt" -exec chmod a-x {} +


В этом случае find будет запускать chmod для группы файлов, а не по одному для каждого файла. Так быстрее должно работать.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: -x для всех файлов

Сообщение sash-kan »

Luinnar
длина командной строки в этом случае может «зашкалить».

upd. а если добавить традицонную спарку find-а с xargs-ом, можно формировать команду заведомо «влезающей» длины. получаем взвешенный компромисс между «одна команда для каждого файла» и «одна команда для всех файлов».
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: -x для всех файлов

Сообщение drBatty »

вот ещё вариант с sed:

Код: Выделить всё

$ find . -type f -exec file {} \; | sed -rn '/English text/s/(.*): .*/echo \1/ep'

только тормозит команда file...
Вместо echo можно поставить любую команду. Например chmod. В имени могут быть любые символы кроме комбинации `: '
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: -x для всех файлов

Сообщение sash-kan »

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

upd.

Shell

$ time find /usr/bin/ -type f -exec file {} \; >/dev/null real 0m4.904s user 0m1.476s sys 0m3.108s $ time find /usr/bin/ -type f -print0 | xargs -0 -n 100 file >/dev/null real 0m0.733s user 0m0.408s sys 0m0.252s
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
Luinnar
Сообщения: 246
ОС: Solaris, Debian, Ubuntu

Re: -x для всех файлов

Сообщение Luinnar »

sash-kan писал(а):
28.03.2010 20:37
Luinnar
длина командной строки в этом случае может «зашкалить».

upd. а если добавить традицонную спарку find-а с xargs-ом, можно формировать команду заведомо «влезающей» длины. получаем взвешенный компромисс между «одна команда для каждого файла» и «одна команда для всех файлов».

Зачем скрещивать find и xargs? find сам следит за длиной строки, так же как xargs. Он выполнит указанную команду не один раз, а сколько потребуется. Просто кол-во этих вызовов будет меньше, чем при использовании \;

Вот описание из man find:

Код: Выделить всё

       -exec command {} +
              This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected
              file  name at the end; the total number of invocations of the command will be much less than the number of matched files.  The command line
              is built in much the same way that xargs builds its command lines.  Only one instance of `{}' is allowed within the command.   The  command
              is executed in the starting directory.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: -x для всех файлов

Сообщение sash-kan »

Luinnar
>Зачем скрещивать find и xargs?

не всегда возможностей find-а достаточно.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
Luinnar
Сообщения: 246
ОС: Solaris, Debian, Ubuntu

Re: -x для всех файлов

Сообщение Luinnar »

sash-kan писал(а):
29.03.2010 16:48
Luinnar
>Зачем скрещивать find и xargs?

не всегда возможностей find-а достаточно.

Да, но длина строки не зашкалит. ;)
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5405
ОС: Gentoo

Re: -x для всех файлов

Сообщение /dev/random »

Luinnar писал(а):
29.03.2010 17:10
Да, но длина строки не зашкалит. ;)

xargs умеет регулировать длину строки.
Спасибо сказали:
Аватара пользователя
Luinnar
Сообщения: 246
ОС: Solaris, Debian, Ubuntu

Re: -x для всех файлов

Сообщение Luinnar »

/dev/random писал(а):
29.03.2010 17:13
Luinnar писал(а):
29.03.2010 17:10
Да, но длина строки не зашкалит. ;)

xargs умеет регулировать длину строки.

Да, но find тоже не даст переполниться строке запуска команды с аргументами.

Вот замеры по скорости из которых видно, что "find -exec cmd {} +" быстрее всех:

Код: Выделить всё

# /usr/bin/time find /usr/local/ > /dev/null
real        0.1
user        0.0
sys         0.1

# /usr/bin/time find /usr/local/ -exec echo {} \; > /dev/null
real     1:25.6
user        0.7
sys         7.8

# /usr/bin/time find /usr/local/ | xargs echo > /dev/null
real        3.2
user        0.0
sys         0.1

# /usr/bin/time find /usr/local/ -exec echo {} + > /dev/null
real        0.2
user        0.0
sys         0.1


А вот здесь видно, сколько раз выполнялась команда echo (кол-во строк в результате выполнения wc). А из равенства последнего столбца в выводе wc видно, что ничего не потерялось в результате запуска echo из find:

Код: Выделить всё

# find /usr/local/ | wc
  55974   56289 3536866
# find /usr/local/ -exec echo {} \; | wc
  55974   56289 3536866
# find /usr/local/ | xargs echo | wc
   1763   56289 3536866
# find /usr/local/ -exec echo {} + | wc
      4   56289 3536866
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: -x для всех файлов

Сообщение drBatty »

Luinnar писал(а):
29.03.2010 17:41
Вот замеры по скорости из которых видно, что "find -exec cmd {} +" быстрее всех:
Код

я не вижу в ваших замерах ключа -n100, как у sash-kan
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Luinnar
Сообщения: 246
ОС: Solaris, Debian, Ubuntu

Re: -x для всех файлов

Сообщение Luinnar »

drBatty писал(а):
29.03.2010 18:58
Luinnar писал(а):
29.03.2010 17:41
Вот замеры по скорости из которых видно, что "find -exec cmd {} +" быстрее всех:
Код

я не вижу в ваших замерах ключа -n100, как у sash-kan


Here you are:

Код: Выделить всё

# /usr/bin/time find /usr/local/ | xargs -n 100 echo > /dev/null

real        8.1
user        0.0
sys         0.4

Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: -x для всех файлов

Сообщение sash-kan »

/dev/random
>xargs умеет регулировать длину строки.

насколько помню, по умолчанию (без -n, -L, -l или -S) строка может переполниться.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: -x для всех файлов

Сообщение drBatty »

Luinnar писал(а):
29.03.2010 19:32
Here you are:

понимаете в чём дело, ваши замеры - это всё мелочь. рубли идут на команду file, которая постоянно юзает базу mime

Код: Выделить всё

$ ll /etc/file/
итого 500
-rw-r--r-- 1 root root 474443 2007-06-03 03:52 magic
-rw-r--r-- 1 root root  32203 2007-06-03 03:52 magic.mime

как видите, на КАЖДЫЙ файл нужно загрузить и пропарсить полметра инфы. sash-kan предложил загружать эту полуметровую базу один раз на сто файлов, и получил таким образом ускорение. Вы предлагаете несколько другой подход, и как-бы тут echo не очень к месту.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: -x для всех файлов

Сообщение watashiwa_daredeska »

sash-kan писал(а):
29.03.2010 20:05
насколько помню, по умолчанию (без -n, -L, -l или -S) строка может переполниться.
Не может. В этом и прелесь xargs. -n и пр. наличествуют совсем для других целей.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: -x для всех файлов

Сообщение t.t »

drBatty писал(а):
29.03.2010 20:20
Luinnar писал(а):
29.03.2010 19:32
Here you are:
понимаете в чём дело, ваши замеры - это всё мелочь. рубли идут на команду file, которая постоянно юзает базу mime

Код: Выделить всё

$ ll /etc/file/
итого 500
-rw-r--r-- 1 root root 474443 2007-06-03 03:52 magic
-rw-r--r-- 1 root root  32203 2007-06-03 03:52 magic.mime
как видите, на КАЖДЫЙ файл нужно загрузить и пропарсить полметра инфы. sash-kan предложил загружать эту полуметровую базу один раз на сто файлов, и получил таким образом ускорение. Вы предлагаете несколько другой подход, и как-бы тут echo не очень к месту.
Так в том-то ведь и дело, что find с плюсом на конце сама расчитывает нужное количество вызовов исходя из максимальной длины строки. Т.е. база file-а будет парситься минимальное количество раз именно в этом случае, а подобрать этот минимум вручную наперёд сложновато. Да и не нужно, даже при использовании xargs, как заметил предыдущий оратор.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
Luinnar
Сообщения: 246
ОС: Solaris, Debian, Ubuntu

Re: -x для всех файлов

Сообщение Luinnar »

drBatty писал(а):
29.03.2010 20:20
Luinnar писал(а):
29.03.2010 19:32
Here you are:

понимаете в чём дело, ваши замеры - это всё мелочь. рубли идут на команду file, которая постоянно юзает базу mime

Код: Выделить всё

$ ll /etc/file/
итого 500
-rw-r--r-- 1 root root 474443 2007-06-03 03:52 magic
-rw-r--r-- 1 root root  32203 2007-06-03 03:52 magic.mime

как видите, на КАЖДЫЙ файл нужно загрузить и пропарсить полметра инфы. sash-kan предложил загружать эту полуметровую базу один раз на сто файлов, и получил таким образом ускорение. Вы предлагаете несколько другой подход, и как-бы тут echo не очень к месту.

В том то и дело, что find с плюсом в конце выполнит команду file гораздо меньшее кол-во раз. Вот замеры:

Код: Выделить всё

# /usr/bin/time find /usr/local/ -exec file {} + > /dev/null
real       23.0
user        1.3
sys         1.8

# /usr/bin/time find /usr/local/ -exec file {} + > /dev/null
real        2.7
user        1.3
sys         1.3

# /usr/bin/time find /usr/local/ | xargs file > /dev/null
real        7.8
user        0.0
sys         0.1

# /usr/bin/time find /usr/local/ | xargs -n 100 file > /dev/null
real        7.9
user        0.0
sys         0.1


Выполнил в начале find два раза, чтобы кэширование FS не влияло на результат. Сравниваем время выполнения второго find и xargs.
find здесь работает быстрее xargs потому что find генерит бо'льшие строки. Но цель у меня была не эта, я хотел показать эквивалентность find + и xargs в противовес find \;
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: -x для всех файлов

Сообщение drBatty »

t.t писал(а):
30.03.2010 09:15
Так в том-то ведь и дело, что find с плюсом на конце сама расчитывает нужное количество вызовов исходя из максимальной длины строки. Т.е. база file-а будет парситься минимальное количество раз именно в этом случае, а подобрать этот минимум вручную наперёд сложновато. Да и не нужно, даже при использовании xargs, как заметил предыдущий оратор.

Это я понимаю. Я про то, что find + не может быть настолько быстрее xargs.
(как в прошлом замере)

Luinnar писал(а):
30.03.2010 13:49
Но цель у меня была не эта, я хотел показать эквивалентность find + и xargs в противовес find \;

а с этим я согласен. xargs более универсальна (плюсик вообще не управляем), и потому в простых случаях работает медленнее, но допускает разнообразные настройки.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Luinnar
Сообщения: 246
ОС: Solaris, Debian, Ubuntu

Re: -x для всех файлов

Сообщение Luinnar »

drBatty писал(а):
30.03.2010 15:58
t.t писал(а):
30.03.2010 09:15
Так в том-то ведь и дело, что find с плюсом на конце сама расчитывает нужное количество вызовов исходя из максимальной длины строки. Т.е. база file-а будет парситься минимальное количество раз именно в этом случае, а подобрать этот минимум вручную наперёд сложновато. Да и не нужно, даже при использовании xargs, как заметил предыдущий оратор.

Это я понимаю. Я про то, что find + не может быть настолько быстрее xargs.
(как в прошлом замере)

Что значит не может? Замер то сделан, цифры я не придумывал. Вы, наверное, хотели сказать, что на реальных задачах разница будет не такой большой. Ну да, в случае с командой file разница не такая большая, но всё же find в ~3 раза быстрее, что немало.

Luinnar писал(а):
30.03.2010 13:49
Но цель у меня была не эта, я хотел показать эквивалентность find + и xargs в противовес find \;

а с этим я согласен. xargs более универсальна (плюсик вообще не управляем), и потому в простых случаях работает медленнее, но допускает разнообразные настройки.

Универсальнее, это да.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: -x для всех файлов

Сообщение t.t »

drBatty писал(а):
30.03.2010 15:58
t.t писал(а):
30.03.2010 09:15
Так в том-то ведь и дело, что find с плюсом на конце сама расчитывает нужное количество вызовов исходя из максимальной длины строки. Т.е. база file-а будет парситься минимальное количество раз именно в этом случае, а подобрать этот минимум вручную наперёд сложновато. Да и не нужно, даже при использовании xargs, как заметил предыдущий оратор.
Это я понимаю. Я про то, что find + не может быть настолько быстрее xargs.
(как в прошлом замере)
"Настолько" или "не настолько" -- это, на мой взгляд, вопрос двадцать пятый. Суть в том, что быстрее (в общем случае).

drBatty писал(а):
30.03.2010 15:58
Luinnar писал(а):
30.03.2010 13:49
Но цель у меня была не эта, я хотел показать эквивалентность find + и xargs в противовес find \;
а с этим я согласен. xargs более универсальна (плюсик вообще не управляем), и потому в простых случаях работает медленнее, но допускает разнообразные настройки.
А с этим тут как будто никто и не спорил.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали: