1

我正在尝试挖掘域列表,以便我只能查找 txt 记录。

这是我的脚本。

#!/bin/bash

echo "Please Enter the Domains (Multiple Domains will work):"
while read domains || [[ -n "$domains" ]]; do      
echo
    dig TXT $domains | grep TXT
done

它可以工作,但它总是会忽略粘贴输入的最后一个文本。我必须手动return按键才能使其工作。

这是我的测试结果

$sh test.sh 
Please Enter the Domains (Multiple Domains will work):
1.1.1.1
1.1.1.2
1.1.1.3
1.1.1.4 <---- these are copy and paste from clipboard

; <<>> DiG 9.8.3-P1 <<>> TXT 1.1.1.1
;1.1.1.1.           IN  TXT

; <<>> DiG 9.8.3-P1 <<>> TXT 1.1.1.2
;1.1.1.2.           IN  TXT

; <<>> DiG 9.8.3-P1 <<>> TXT 1.1.1.3
;1.1.1.3.           IN  TXT

(此时我必须按下return才能获得最后的dig结果)

; <<>> DiG 9.8.3-P1 <<>> TXT 1.1.1.4
;1.1.1.4.           IN  TXT

我已经尝试了几个小时通过谷歌搜索来修复它,但找不到解决方案。任何见解将不胜感激。

谢谢

4

1 回答 1

0

超时读取,等待从剪贴板粘贴

好的,您的剪贴板错过了最后一个换行符。我们必须使用timeout,但在此之前等待第一个输入......

有一种方法:

#!/bin/bash

buffer=""
IFS= read -d '' -r -p $'Please Enter Domains (One Domain by line):\n' -N 1 char
buffer+="$char"
while IFS= read -r -d '' -t .01 -N 1 char;do
    buffer+="$char"
done

echo

while read domain && [ "$domain" ]; do
    echo $domain
    dig +noall +answer TXT $domain
done <<<"$buffer"

解释:

read4 行的第一个只等待 1 个字符。然后所有粘贴的输入将满足下一个循环,read在 0.01 秒后静默退出并出现错误。

echo10 行将在终端上添加错过的换行符。

最后的循环将正常地从变量中逐行读取$buffer(nota: syntax <<<,它是一个bashism,将添加一个newline)。

相同的循环版本:

#!/bin/bash
# Waiting for input from clipboard, even without newline

buffer=loop

while [ "${buffer//$'\n'}" ] ;do
    buffer=""
    IFS= read -d '' -r -p $'Please enter one domain by line, return to exit:\n' -n 1 char
    buffer+="$char"
    while IFS= read -r -d '' -t .001 -n 1 char;do
    buffer+="$char"
    done

    echo

    while read domain && [ "$domain" ]; do
    echo $domain
    dig +noall +answer TXT $domain
    done <<<"$buffer"
done

点击return或粘贴一个空行退出。

注意:在这个版本中,我将超时时间减少到 0.001 秒。我认为这在大多数情况下必须有效,但请自行测试。

具有自适应超时的重新访问版本

此版本将检查前两个字符之间的时间,以更改超时并允许手动输入。

对于手动输入,将立即处理每个换行符。

#!/bin/bash

# Waiting for input from clipboard, even without newline

timeoutman=2
timeoutclip=.001

buffer=loop

while [ "${buffer//$'\n'}" ] ;do
    buffer=""
    IFS= read -d '' -r -p $'Please enter one domain by line, return to exit:\n' -n 1 char
    buffer+="$char"
    reftim1=($(</proc/uptime))
    [ "${char//$'\n'}" ] && IFS= read -d '' -r -n 1 char
    buffer+="$char"
    reftim2=($(</proc/uptime))
    ((${reftim2//.}-${reftim1//.}>1)) && timeout=$timeoutman || timeout=$timeoutclip
    while IFS= read -r -d '' -t $timeout -n 1 char;do
    [ "$char" ] && [ -z "${char//$'\n'}" ] && [ "$timeout" = "$timeoutman" ] && break
    buffer+="$char"
    done

    echo

    while read domain && [ "$domain" ]; do
    echo "--- ${domain^^} ---"
    dig +noall +answer TXT $domain
    done <<<"$buffer"
done

注意:/proc/uptime用于读取时间分辨率为 1/100 秒,没有分叉。不幸的是,这只适用于基于linux的主机。对于其他主机,您可以使用reftim1=$(date +%s%N),但由于这会在前两个字符之间产生分叉,这将改善 difftime: ((${reftim2//.}-${reftim1//.}>2000000))&&...; 将第 14 到 18 行替换为:

#    reftim1=($(</proc/uptime))
    reftim1=$(date +%s%N)
    [ "${char//$'\n'}" ] && IFS= read -d '' -r -n 1 char
    buffer+="$char"
#    reftim2=($(</proc/uptime))
    reftim2=$(date +%s%N)
#    ((${reftim2//.}-${reftim1//.}>1)) && timeout=$timeoutman || timeout=$timeoutclip
    ((reftim2-reftim1>2000000)) && timeout=$timeoutman || timeout=$timeoutclip
于 2016-11-09T13:48:26.247 回答