Прежде чем я рекурсивно создаю tar для каталога, я хочу иметь возможность удалить все исполняемые файлы. В Windows я бы просто удалил все файлы с расширениями .exe. И я не могу просто удалить все файлы в исполняемом режиме, так как это также приведет к удалению сценариев оболочки. Итак, есть ли способ автоматически удалить в каталоге только файлы сценариев без оболочки?
Я так понимаю, вы имеете в виду двоичные файлы? Если количество исполняемых файлов очень велико, эта команда может завершиться ошибкой из-за слишком длинной командной строки для «file» и «echo». Быстрый пример:
find /bin -type f | xargs file | grep "ELF.*executable" | awk -F: '{print $1}' | xargs echo
Если вы замените «echo» на «rm» в приведенном выше примере, эти файлы будут удалены. Команда "grep" должна предотвратить удаление библиотек (вы можете проверить / lib).
(Обратите внимание, что сейчас у меня есть доступ только к FreeBSD, поэтому вывод команды linux "file" может отличаться, что меняет то, что вам нужно делать.)
Это должно дать вам простой шаблон, как это сделать. Вам просто нужно быть уверенным, что вы знаете, что искать в выводе, полученном с помощью "file" и grep соответственно.
Быть осторожен. Вы можете полностью разорвать свою систему, если запустите ее как root в неправильном каталоге.
find . -perm /111 -type f -exec echo rm -v {} \;
Магия здесь в том, что флаг -perm (для разрешений) может принимать / перед аргументом разрешения, что заставляет его искать логическое ИЛИ для каждого из битов. На странице руководства:
-perm /mode
Any of the permission bits mode are set for the file. Symbolic
modes are accepted in this form. You must specify 'u', 'g' or
'o' if you use a symbolic mode. See the EXAMPLES section for
some illustrative examples. If no permission bits in mode are
set, this test currently matches no files. However, it will
soon be changed to match any file (the idea is to be more con-
sistent with the behaviour of perm -000).
В случае, если это не ясно, / указывает 111, указывает x в пользователе ИЛИ x в группе ИЛИ x в остальных. И это не XOR, поэтому мы ищем хотя бы один, но не больше трех.
Поскольку разрешения файла unix
rwxrwxrwx
421421421
И мы заботимся о x битах, мы получаем маску
--1--1--1
или 111
Следует отметить, что в приведенной выше команде есть эхо, которое не дает вам выстрелить себе в ногу. Не стесняйтесь позаботиться о безопасности, как только вы правильно закрепите файлы.
РЕДАКТИРОВАТЬ
Хорошо, это тоже удаляет все сценарии оболочки. Нет никакого приятного, изящного способа сделать это с помощью find, которую я нашел, из-за относительно примитивного сопоставления регулярных выражений. Я могу найти все нужные вам файлы .sh с помощью регулярных выражений:
-regex ".*\(.*sh\$\)"
Но я вообще не могу это изменить. Так что я сдаюсь. Я все еще оставляю это здесь, на случай, если это кому-то пригодится.
Напишите сценарий оболочки или воспользуйтесь чьим-либо предложением, или, если вы действительно хотите, просто временно удалите разрешения исполняемых файлов для сценариев оболочки, удалите все исполняемые файлы, а затем снова добавьте + x. Удачи.
file * | grep executable | grep -v 'shell script' | cut -d: -f 1 | xargs rm
Или возможно:
make clean
;-)
Прежде чем я рекурсивно создаю tar для каталога, я хочу иметь возможность удалить все исполняемые файлы.
ИМХО короткий ответ заключается в том, что не существует 100% надежного способа сделать это. Только в зависимости от разрешений могут отсутствовать или включать вещи, которые вам не нужны. В зависимости от имен файлов работать не будет. Даже в зависимости от выхода файл команда, вероятно, не является хорошей идеей, я несколько раз видел, как она неправильно идентифицирует вещи.
Тебе нужно find
для перебора файлов в дереве, file
утилита командной строки для определения их типа файла, за которым следует perl
для фильтрации исполняемых файлов:
find . -type f -print0 | xargs -0 file -N0 -- \
| perl -nlwe '/(.*\0).*ELF.*executable/ and printf $1' | xargs -0 ls -l --
Вы действительно хотите удалить файлы, заменив окончательные ls -l --
с участием rm --
.
Примечание: все -print0
и -0
переключатели необходимы, чтобы убедиться, что пробелы в именах файлов обрабатываются правильно. Это также причина, по которой perl
используется вместо awk
, который не может действительно проглотить нулевые символы на входе. В --
переключатели предназначены для защиты от имен файлов, начинающихся с тире.
Для этого вам, вероятно, придется написать сценарий оболочки. Сверху моей головы сначала запустите файл, получите исполняемые файлы и исключите все сценарии. Затем вы можете работать с остатком, который должен быть тем, что вы ищете.
Используя биты из ответа Мэтта, я придумал следующее:
find . -perm /111 -type f -print0 | xargs -0 file | grep -v 'shell script' | cut -d: -f1 | xargs echo rm
Для этого я создал сценарий bash. Если вы изучите все строки в нем, я уверен, что вы сможете понять, как делать все из командной строки и изменить ее, чтобы удалить любой тип файла, то есть использовать «find -iname» или что-то еще.
#!/bin/bash
#this script will grab all executable files in the
#bash shell scripts ending in .sh will be saved
#current directory and delete them
#it will also destroy itself so keep a copy somewhere
echo "WARNING! This script will self-destruct and take all"
echo "executable files in the current directory when executed"
echo ""
#first create a new file to set up executable files
touch xdelgo.txt
#save all the bash shell scripts ending in .sh
#this will only work and in the pwd and not child directories
touch protected.sh
echo "#!/bin/bash" >> protected.sh
find . -type f | grep .sh | grep -v xdel.sh >> protect.txt
SAVE=$'\n';x=sudo;for l in $(<protect.txt);do echo -e "$x chmod u-x $l";
((x+1));done >> protected.sh
sudo chmod u+x protected.sh
./protected.sh
#throw all executable files from the current directory inside
find -type f -executable >> xdelgo.txt
echo "The following files have been marked for deletion"
echo " "
cat xdelgo.txt
echo " "
#create a new script that will execute deletion
touch xdelgo.sh
echo "#!/bin/bash" >> xdelgo.sh
echo "rm xdelgo.sh" >> xdelgo.sh
echo "rm xdelgo.txt" >> xdelgo.sh
echo "rm protect.txt" >> xdelgo.sh
#append rm to each line and throw into new executable file
DEL=$'\n';x=rm;for l in $(<xdelgo.txt);do echo -e "$x\t$l";((x+1));done
>> xdelgo.sh
#go give permission to the file
sudo chmod u+x xdelgo.sh
echo "bash scripts ending in .sh have been protected"
echo "run ./restore.sh to re-enable .sh files"
echo ""
touch restore.sh
echo "#!/bin/bash" >> restore.sh
find . | grep .sh | grep -v xdel.sh >> restore.txt
SAVE=$'\n';x=sudo;for l in $(<restore.txt);do echo -e "$x chmod u+x $l";
((x+1));done >> restore.sh
sudo chmod u+x restore.sh
echo "rm restore.txt" >> restore.sh
echo "rm restore.sh" >> restore.sh
echo "rm protected.sh" >> restore.sh
#THE POINT OF NO RETURN
echo "Are you sure you really wanna delete these files?"
echo "Press ENTER to continue, ctrl+c to abort"
read input
./xdelgo.sh