Для такого большого количества IP-адресов следует использовать модуль ipsets . ipset создает наборы данных, на которых iptables может React, он может легко обрабатывать 10 из 1000 записей .
Убедитесь, что у вас включено репозиторий EPEL , а затем установите ipset через:
yum install ipset
Пример:
ipset -N blockedip iphash
создает набор под названием «blockedip» в формате «iphash» (существуют разные форматы, это только для IP-адресов).
с помощью ipset -A вы можете добавить данные (в данном случае IP-адреса) в набор данных:
ipset -A blockedip 192.168.1.1
ipset -A blockedip 192.168.1.2
и так далее ...
Или создать пакет без запуска одного ipset
вызов для каждого IP-адреса, предполагая, что вы big-file.list
- это список адресов IPv4, по одному в каждой строке:
ipset -N blockedip iphash
sed 's/^/add blockedip /' < big-file.list | ipsec restore
С помощью следующей команды iptables вы можете указать ядру отбросить все пакеты, поступающие из любого источников в этом наборе:
iptables -A INPUT -m set --set blockedip src -j DROP
Ближайший ответ, который я могу найти без отдельного воссоздания структуры каталогов, — использовать install:
cd example
find. -type f -exec sh -c 'grep ERROR {} | install -D /dev/stdin /tmp/example_grepped/{}' \;
К сожалению, описанное выше может работать только в том случае, если ваша команда может передать результат в STDOUT.
#!/bin/bash
filter() {
local target_root="${@: -1}"
target_path=$(sed -E "s/[^/]*/$target_root/" <<< "$1")
target_dir=$(dirname "$target_path")
mkdir -p "$target_dir"
if [[ -f $1 ]]; then
# do your grep thing here
grep burger "$1" > "$target_path"
fi
}
export -f filter
source_root="example"
target_root="example_grepped"
find "$source_root/" -print0 | xargs -0 -I content bash -c "filter 'content' '$target_root'"
Этот сценарий также работает с именами каталогов и файлов, содержащими пробелы.
Запустите этот сценарий, где находится исходный каталог («пример» ).
Другой способ приблизиться к этому — использовать программу, которая в любом случае делает рекурсивное копирование. Я проверил rsync
, но не смог быстро найти вариант обратного вызова. Но у gnu tar
есть опция --to-command
, для которой вы можете предоставить команду для запуска, которая получает входные данные файла в stdin
. Но как тогда создать файл? Итак, вызываемая команда находит текущее имя файла в $TAR_FILENAME
.
Собирая все вместе, основной призыв
tar cf - example | tar xf - --to-command="./script example_grepped 'grep-pattern'"
где script может быть что-то вроде
#!/bin/bash
mkdir -p $(dirname "$1/$TAR_FILENAME")
grep '$2' >"$1/$TAR_FILENAME"
exit 0
Другой способ приблизиться к этому — обернуть tar-канал в сценарий, который запускает команду в командной строке. Тем не менее, побег для конструкции mkdir...dirname
будет немного сложным.
Используя GNU Parallel, вы можете сделать что-то подобное:
cd src
find. -type f | parallel 'mkdir -p../dst/{//}; dostuff --input {} --output../dst/{}'