Эквивалент строки grep, соответствующей sed и awk

Ошибка сегментации означает, что программа, в данном случае wget, пыталась получить доступ к недопустимому адресу памяти и поэтому была завершена ядром. Обычно это происходит из-за ошибки в программе, поэтому, хотя вполне вероятно, что это вызвано определенным веб-сайтом или веб-страницей (, учитывая, что вы, кажется, можете воспроизвести это довольно последовательно, на нескольких платформах, в одной и той же точке ), вполне вероятно, что вы выявили ошибку в самом wget.

Чтобы найти, где в wget происходит ошибка сегментации, вы можете использовать gdbпрограмму (отладчик GNU ), чтобы получить трассировку стека wget во время его сбоя, что возможно, поскольку вы есть файл core. (Дамп ядра — это копия образа работающей программы на момент ее остановки из-за недопустимой операции, например ошибки сегментации.)

Для этогоиспользуйте следующую команду:

$ gdb wget core

Который запустит отладчик на двоичном файле wget(по пути )и восстановит файл core(в текущем каталоге )в качестве образа работающей программы.

gdbраспечатает некоторую информацию о программе и выдаст подсказку:

$ gdb wget core
GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
...
Core was generated by `wget --directory-prefix=... --recursive --page-requisites --span-hosts --tries=... --timeout=... --reject=*.tar --convert-links --adjust-extension --continue --no-check-certificate http://website.com/'.
Program terminated with signal SIGSEGV, Segmentation Fault.
(gdb) _

В этот момент вы можете использовать команду bt(, сокращенную от «backtrace» ), чтобы показать вам, что выполнялось в момент сбоя программы. Как правило, это хорошее место для начала поиска ошибки.

Например, вы можете увидеть что-то вроде этого:

(gdb) bt
#0  0x00007f5371206363 in __select_nocancel () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x0000559e5acbf21c in select_fd ()
#2  0x0000559e5acf0bde in wgnutls_poll ()
#3  0x0000559e5acbf3a2 in poll_internal ()
#4  0x0000559e5acbf6ed in fd_peek ()
#5  0x0000559e5ace423d in fd_read_hunk ()
#6  0x0000559e5acd5ef9 in gethttp ()
#7  0x0000559e5acd9b26 in http_loop ()
#8  0x0000559e5ace53c8 in retrieve_url ()
#9  0x0000559e5ace273b in retrieve_tree ()
#10 0x0000559e5acbe67d in main ()

Затем вы можете выйти gdbс помощьюq(команды "quit" ):

(gdb) q

Обычно полезно, если у вас установлены "символы отладки". Это информация, сгенерированная компилятором для отладки двоичных файлов, которая обычно удаляется для двоичных файлов, установленных в системе, поэтому они меньше по размеру. Эта информация может быть сохранена в другом месте (, обычно в /usr/lib/debug), которое может быть найдено с помощью gdbпри попытке отладки двоичного файла.

При наличии этой информации к вашим обратным трассировкам, как правило, будет прикреплена дополнительная информация, например, имена всех внутренних функций.

В Debian вы можете установить отладочную информацию для wget с помощью следующей команды:

$ sudo apt-get install wget-dbgsym

Вы также можете установить символы отладки для glibc:

$ sudo apt-get install libc6-amd64-dbgsym

Тем не менее, прежде чем вы начнете искать причину сбоя wget, вы можете попробовать последнюю версию wget, которая, кажется, является версией 1.9.4, которую вы можете скачать здесь . Это исходный пакет, поэтому вам может потребоваться собрать его из исходников, чтобы заставить его работать в вашей системе.

Это связано с тем, что ошибка сегментации обычно вызывается ошибкой, и вполне возможно, что эта ошибка уже исправлена ​​в wget, и это исправление присутствует в последней версии.

Если вы столкнулись с той же проблемой в последней версии, рассмотрите возможность получения файла ядра и использования gdb для получения обратной трассировки, а затем сообщите об ошибке сопровождающим wget, чтобы у них была возможность ее устранить.

Если он исправлен в последней версии wget 1.9.4, но существует в используемой вами версии Debian, рассмотрите возможность сообщить об этом в Debian, чтобы у них была возможность перенести исправление на свою версию wget.

Также есть новый проект под названием wget2 , похоже, они пытаются заменить wget новой кодовой базой. Возможно, вы захотите проверить, работает ли он или нет... Похоже, недавно Debian выпустил его под именем "wget2".

Надеюсь, эти советы тоже будут вам полезны!

0
22.12.2020, 00:41
2 ответа

Используя awk, считать все шаблоны в ассоциативный массив как ключи. Затем просмотрите строки в файле данных одну за другой и для каждой строки сравните с ней каждый оставшийся шаблон. Если шаблон совпадает, удалите его из ассоциативного массива.

В конце выведите образцы, которые остались несопоставленными.

NR == FNR { pat[$0] = 1; next }

{
    for (p in pat)
        if (index($0,p) != 0)
            delete pat[p]
}

END {
    for (p in pat)
        print p
}

Вы должны сохранить это в файл, например. script.awk, а затем запустить с

awk -f script.awk patterns.txt large_strings.txt >unmatched_patterns.txt

Это будет выполнять сравнение строк, используя index(), а не совпадения регулярных выражений (, как и grep -F), но потенциально будет сопоставлять несколько строк шаблонов в перекрывающихся местах в данных, что я не думаю grepсделает (шаблоны abи baоба будут соответствовать даннымaba).

Тестирование на фиктивных данных:

$ cat patterns.txt
a
b
c
d
$ cat strings.txt
abba
bull
cooler
$ awk -f script.awk patterns.txt strings.txt
d

(Строка dне найдена в файле strings.txt.)

3
18.03.2021, 22:41

С GNU grepя бы сделал вместо этого:

(
  export LC_ALL=C
  sort -uo patterns.txt patterns.txt # if not already uniqued and sorted in the C locale
  grep -oFf patterns.txt large_strings.txt |
    sort -u |
    comm -13 - patterns.txt > unmatched_patterns
)

Теоретически он должен быть медленнее, чем ответ @Kusalananda, поскольку он ищет все вхождения шаблонов.

1
18.03.2021, 22:41

Теги

Похожие вопросы