Sed: выполнить альтернативную команду, когда вывод из предыдущего пуст - PullRequest
0 голосов
/ 19 декабря 2018

Я хотел изменить команду dig для автоматического применения обратного просмотра к любой записи A, которую я получаю на выходе.

Поэтому я создал следующую функцию:

dt ()
{
    remove=$(echo $@ |  sed 's^https*^^' | sed 's^[,/*:]^^g' );
    dig any +trace +nocl +nodnssec $remove | sed "s/\($remove.*A\s*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)\)/dig -x \2 +short | xargs echo \"\1 ->\"/e"
}

С этим кодом у меня есть следующий вывод (только часть записи показана, чтобы избежать увеличения вопроса):

domain.com.      1200    A        198.54.115.174 -> server224-3.web-hosting.com.

Однако теперь мне также необходимо выполнить поиск по whois с использованием полученного IP-адреса.из вывода dig, но только в том случае, если dig -x \2 +short не дает никакого результата (stackoverflow.com может быть хорошим примером домена с записями A, у которых нет PTR).

Я пробовал что-то подобноепроверить код завершения обычной команды host (поскольку dig подразумевает, что вывод успешен, даже если он пуст) и выполнить правильную команду в зависимости от результата:

dig any +trace +nocl +nodnssec "$remove" | sed -e "s/\($remove.*A\s*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)\)/echo -n \"\1 -> \"; host \2 | grep -q ''; if [ ${PIPESTATUS[0]} -eq 0 ]; then dig -x \2 +short; else whois \2 | grep 'network:Network-Name:';fi; /e"

Но кажется, что sed как-то влияетзначение массива ${PIPESTATUS[0]}.

Я хотел сделать эти изменения в sed, потому что мне нужно было что-то, что будет печатать строки на ходу.Если я использую переменные и изменяю вывод из них, функция будет работать медленнее, по крайней мере визуально.

Может быть, awk может быть полезным здесь, но я не уверен, как мне написать код, используя этокоманда.

Есть ли способ обойти эту проблему?Можно ли использовать sed для этой цели или я должен использовать какой-то другой инструмент?Спасибо.

1 Ответ

0 голосов
/ 19 декабря 2018

Старый добрый bash предоставляет вам множество инструментов grep, awk, xargs, while read и так далее.Использование sed с командой e с внутренней проверкой PIPESTATUS и выполнением xargs .... просто нечитаемо и слишком долго читается.Мне непонятно, что вы хотите сделать, так как слишком много всего происходит в одной строке.

Команда dig дает нулевой статус в случае успеха - вы можете проверить ее вывод, если он имеет нулевую длину, когда он "терпит неудачу ".

Рассмотрим следующий сценарий:

dt () {
    remove=$(
        <<<$1 \
        sed 's#^http[s]?://\([^/]*\).*#\1#'
    )
        dig any +trace +nocl +nodnssec "$remove" |
        tr -s '\t' |
        awk -v "remove=${remove}." '{
                if ($1 == remove && $3 == "A") {
                        print
                }
        }' |
        while IFS= read -r line; do
                IFS=$'\t' read -r _ _ _ ip _ <<<"$line"
                if ! dig_result=$(dig -x "$ip" +short); then
                        echo "Dig error" >&2
                        exit 1
                fi
                if [ -z "$dig_result" ]; then
                        printf "%s -> no-result-from-dig\n" "$line"
                else
                        printf "%s -> %s\n" "$line" "$dig_result"
                fi
        done
}
  1. Первый dig запущен.Обратите внимание на "$remove" в кавычках.
  2. Просто предосторожность - я сжимаю табуляторы в выводе.
  3. Затем я фильтрую - первый столбец должен иметь "$remove". с точкой и третийстолбец должен быть "A"
  4. Затем для каждой строки (как и у многих)
  5. Я получаю IP-адрес (хорошо, возможно, ip=$(<<<"$line" cut -f4) будет чище и проще).
  6. Я получаю результат от dig -x, используя IP-адрес
  7. Если результат пуст, я печатаю «no-result-from-dig», если нет, я печатаю результат.

Запуск:

dt stackoverflow.com
dt google.pl

Выходы:

stackoverflow.com.      300     A       151.101.65.69 -> no-result-from-dig
stackoverflow.com.      300     A       151.101.193.69 -> no-result-from-dig
stackoverflow.com.      300     A       151.101.129.69 -> no-result-from-dig
stackoverflow.com.      300     A       151.101.1.69 -> no-result-from-dig
google.pl.      300     A       216.58.215.67 -> waw02s16-in-f3.1e100.net.

Причина, по которой ваша команда не сработала, заключается в том, что $PIPESTATUS заключен в кавычки ", таким образом, расширенперед запуском оболочки.Вы должны экранировать $, так что это \$PIPESTATUS или передать его в неэкспонирующихся одинарных кавычках " ... "'$PIPESTATUS'" ... ".

...