1) установить build-essential
apt-get install build-essential
Перейдите в / usr / local / src
floder
cd /usr/local/src
Загрузите последний пакет Curl
из здесь с использованием:
wget http://curl.haxx.se/download/curl-7.48.0.tar.gz
Unzip
tar -xvzf curl-7.48.0.tar.gz
rm *.gz
cd curl-7.48.0
./configure
sudo make
sudo make install
2) Лучшая архитектура - amd64
`
Поскольку вы уже используете расширения GNU ( -quit
, -H
, -m1
), вы также можете использовать GNU grep
параметр -r
вместе с - line-buffered
, чтобы он выводил совпадения как можно скорее. как только они будут найдены, то SIGPIPE с большей вероятностью будет отключен, как только он напишет 6-ю строку:
grep -rHm1 --line-buffered pattern /path | head -n 5
С помощью find
вам, вероятно, потребуется сделать что-то вроде:
find /path -type f -exec sh -c '
grep -Hm1 --line-buffered pattern "$@"
[ "$(kill -l "$?")" = PIPE ] && kill -s PIPE "$PPID"
' sh {} + | head -n 5
That есть, оберните grep
в sh
(вы по-прежнему хотите запускать как можно меньше вызовов grep
, отсюда {} +
), и sh
убить своего родителя ( find
), когда grep
умирает из SIGPIPE.
Другой подход может заключаться в использовании xargs
в качестве альтернативы -exec {} +
. xargs
немедленно завершается, когда порождаемая им команда умирает от сигнала, например:
find . -type f -print0 |
xargs -r0 grep -Hm1 --line-buffered pattern |
head -n 5
( -r
и -0
являются расширениями GNU). Как только grep
выполнит запись в сломанный канал, оба grep
и xargs
завершат работу, а find
также выйдет из себя в следующий раз. он что-то печатает после этого. Выполнение find
под stdbuf -oL
может ускорить это.
Версия POSIX может быть:
trap - PIPE # restore default SIGPIPE handler in case it was disabled
RE=pattern find /path -type f -exec sh -c '
for file do
awk '\''
$0 ~ ENVIRON["RE"] {
print FILENAME ": " $0
exit
}'\'' < "$file"
if [ "$(kill -l "$?")" = PIPE ]; then
kill -s PIPE "$PPID"
exit
fi
done' sh {} + | head -n 5
Очень неэффективной, поскольку она запускает несколько команд для каждого файла.
Решение, позволяющее избежать ошибок, может быть следующим:
find / -type f -print0 \
| xargs -0 -L 1 grep -H -m 1 --line-buffered 2>/dev/null \
| head -10
В этом примере xargs остановится после сбоя команды, поэтому будет только одна ошибка канала, которая будет отфильтрована перенаправлением stderr.
Вы grep
по одному файлу за раз. С помощью -quit
вы останавливаете поиск при первом успешном выполнении команды grep.
[update] Моим первым решением было сразу выполнить команду grep для нескольких файлов:
find /path/ -type f -exec grep -H -m 1 'pattern' \{\} + -quit | head -n 5
(магия находится в +
в конце подкоманда -exec
. Добавлен -type f
. Вы можете удалить параметр -H
в grep
, если вы уверен, что / path / содержит несколько файлов)
Проблема здесь, как сообщает @ StéphaneChazelas, заключается в том, что команда -exec
выполняется асинхронно и всегда возвращает true
=> find
завершает работу с первым файлом.
Если мы хотим, чтобы find
останавливался после завершения head
, find
также должен получить SIGPIPE, который grep
получает (signal 13). Это означает, что find
должен послать что-то по конвейеру.
Вот быстрый и грязный прием, дополненный предложениями Стефана:
find /path/ -type f -exec grep -H -m 1 --line-buffered 'pattern' {} + -printf '\r' | head -n 5
С помощью -printf '\ r'
я заставляю find
выводить безобидный символ, который будет (надеюсь) не изменит вывод grep
. Как только head
остановится, find
получит SIGPIPE и тоже остановится.
[update2] Я предупреждал вас, что это грязный взлом.Вот лучшее решение:
find /path/ -type f -exec grep --quiet 'pattern' {} ";" -print | head -n 5
Здесь больше не grep
, который печатает имя файла, а find
=> больше никаких «grep завершается сигналом 13» и find
останавливается на head
. Проблема в том, что совпадающие строки больше не печатаются grep
.
[update3] Наконец, как было предложено @Andrey, эта бесстыдная команда, приведенная ниже, решит эту последнюю проблему:
find /path/ -type f \
-exec grep --quiet 'pattern' {} \; \
-printf '%p:' \
-exec grep -h -m 1 'pattern' {} \; \
| head -n 5`