$ # является количеством аргументов оболочке. Так, первая строка говорит "выход, если нет 3 аргументов", потому что правильная часть (после ||) только выполняется, если левая часть не верна. || логическое или.
255, поскольку код возврата может быть произвольным.
сценарии возвратятся 0, если слово "строка" будет во входе.
Это помогает?
Действительно нет никакой потребности в репродуцировании find
произведите цикл оболочки INA. Если Вы хотите упаковать список имен файлов, универсальная формула:
find ... | gzip > logfile.gz
Если Вы хотите к gzip сами файлы, он изменяется на:
find ... | tar -czvf archive.tar.gz -T -
который говорит tar
прочитать список имен файлов, чтобы продолжить работать из файла и сингла -
обозначает стандартный вход. ( -T
Иначе --files-from=
опция присутствует в tar GNU, я не уверен в других ароматах.), Конечно, это повреждается, если Вам удается работать над файлами, которые содержат \n
на их имена.
Вы не можете выполнить последующую обработку вывод находки надежно. Использовать -exec
в find
:
find . -type f ! -name '*.gz' ! -name '*.Z' -mtime +7 -exec sh -c '
for i do
printf "%s\n" "Will be compressing file $i"
gzip "$i"
done' sh {} + >> log
С реализацией GNU find
, можно даже уйти, не работая sh:
find . -type f ! -name '*.gz' ! -name '*.Z' -mtime +7 \
-printf 'Will be compressing file %p\n' -exec gzip {} + >> log
поместите свое перенаправление (>>
) вне цикла (после того, как done
) как так:
for i in $(find . -type f \( ! -name '*.gz' \) -a \( ! -name '*.Z' \) -mtime +7);
do echo "Will be compressing file ${i}";
##gzip $i;
done >> $LOGCLEAN_FILE
Или, если Вы планируете возможный некомментарий Вашего gzip
команда Вы могли бы рассмотреть:
for i in $(find . -type f \( ! -name '*.gz' \) -a \( ! -name '*.Z' \) -mtime +7);
do gzip "$i" && echo "Successfully compressed ${i}";
done >> $LOGCLEAN_FILE
&&
средства только делают следующую команду, если предыдущая команда выходит с 0
(никакая ошибка).
Поскольку имена файлов могут иметь и пробелы и новые строки, которыми был бы вероятный подход:
#!/bin/bash
logclean_file="logclean_file.txt"
ts="$(date)"
printf "%s\n" "$ts" > "$logclean_file"
# Set IFS blank
# -r Backslash does not act as an escape character. The backslash
# is considered to be part of the line. In particular, a
# back-slash-newline pair may not be used as a line continuation.
# -d delim
# The first character of delim is used to terminate the input
# line, rather than newline.
#
# Here setting -d to nul or 0x00. This enables us to capture any file-
# names with the print0 from find.
#
# fn The variable to read into.
#
while IFS= read -r -d $'\x00' fn; do
printf "Will perhaps be compressing file %s\n" "$fn" >> "$logclean_file"
# If file + gz does not exist
if [[ ! -e "$fn.gz" ]]; then
if gzip command "$fn"; then
echo "Horray! success!" >> "$logclean_file"
else
echo "Harf! Gzip failed." >> "$logclean_file"
fi
else
echo "Nah. Already exists." >> "$logclean_file"
fi
done < <(find . -type f \( ! -name '*.gz' \) -a \( ! -name '*.Z' \) -print0)
# Notice -print0 at end which means find will print filenames, - separating
# them with 0x00 instead of new-line
Ни один echo
ни print
являются действительно портативными. В то время как print
уникально для ksh93, echo
только был стандартизирован очень поздно в процессе POSIX, и на более старые версии нельзя полагаться для приведения к предсказуемым результатам. Посмотрите эхо по сравнению с печатью и Почему printf лучше....
printf "Some %s\n" "$var" >> "$foo"
# Or
echo "Some $var" >> "$foo"
Некоторые касательно:
Для руководств TLDP, и если бы Вы используете стильный, я рекомендовал бы один из них для чтения экрана.
Также короткий и сладкий: cat list | xargs rm
Это предполагает, что у вас есть файл с именем 'list' из всех вредоносных PHP-файлов и что вы находитесь в каталоге, содержащем PHP-файлы (просто чтобы быть понятным, но я уверен, вы уже поняли это).
Если какое-либо из имен файлов содержит новые строки, это будет опасно для запуска , особенно потому, что вы уже знаете, что они были созданы вредоносным противником. Если у вас есть список имен файлов в текстовом файле, вы можете проверить список заранее и убедиться, что ни одна из строк не удалит файлы, которые вы хотите сохранить.
Кроме того, если злоумышленнику удалось получить вредоносные php-скрипты на этом хосте, это может быть не самой большой вашей проблемой . Я только отвечаю на ваш вопрос, и @ soubunmei дал лучший ответ, потому что она знала немного больше о команде найти, чем я, но ни один из ответов не гарантирует безопасность . Извините, если это не было ясно, и спасибо @ soubunmei и @ SoubingHomer за то, что указали на мой неосторожный язык. Вы должны поговорить с профессионалом по кибербезопасности, если вы считаете, что кто-то из злоумышленников мог получить повышенные привилегии на хосте.
Я лично подозреваю, что есть хороший способ, основанный на «продлении и дате», чтобы сделать это, как вы просили, что некоторые люди могут найти более элегантным, но так как у вас уже есть список, почему бы не использовать его?
Я протестировал это на файл под названием «список», который содержал строки:
file1
file2
и эти файлы были на моем рабочем столе. Это сработало, как и ожидалось. Я настоятельно рекомендую сначала протестировать его на малой ступени, чтобы увидеть, как он будет себя вести, а также создать резервную копию каталога перед любым массовым удалением файлов. Место на жестком диске намного дешевле времени программистов!
-121--209995-Для определенных пакетов (те, которые я, скорее всего, не хочу взламывать), я делаю свой собственный пакет, используя это:
https://github.com/bluepeppers/pip2arch
затем построить и установить произведенный PKGBUILD.
Я оставляю virtualenvs для пакетов, которые я могу изменить или взломать.
-121--12149-Если вы пытаетесь перейти к выходному файлу, выполняется итерация по пути к файлу...
... для обработки итераций.
Я хотел выполнить итерацию по явным файлам перечислять через вложенную оболочку, и вызвать expand
, который выводит stdout, и перезаписать каждый отдельный файл. Проблема, решаемая этим ответом .
find $(git ls-files | grep '.py$') \
-exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
Я представляю немного измененную версию этого ответа, так как другие ответы в этом потоке не предоставляют решения общего назначения. Это единственное, что я видел, что работает, что применимо только при итерации по пути к файлу.
Я могу представить себе решение, которое злоупотребляет созданием файлов, названных в честь предметов итерации, чтобы можно было выполнить итерацию над этим именем с помощью поиска.
Неудачная попытка:
Как и вызов find exec, я попытался использовать bash -c...
внутри шлейфа for. Но я столкнулся с той же проблемой пустых выходных файлов.
Отказ от ответственности: Я не уверен, в чем именно была моя проблема, во всех попытках до использования find exec, все выходные файлы, в которые я ожидал быть записанным, были перезаписаны, моя проблема была в том, что они были пустыми после.