DNSサーバーをテストし、結果をcsvファイルに返すために非常に単純なスクリプトを作成しようとしています。うまくいきますが、大規模なドメインソースファイルの場合は時間がかかります。
pvまたはawkを使用して進行状況インジケータを作成する方法はありますか?
#!/bin/bash
# File name of domain list: One FQDN per line in file.
domain_list='domains.txt'
#
# IP address of the nameserver used for lookups:
ns1_ip='1.1.1.1' # Cloudflare
ns2_ip='9.9.9.9' # Quad9
#
# Seconds to wait between lookups:
loop_wait='1'
#
echo "Domain name, $ns1_ip,$ns2_ip" > dns-test-results.csv;
for domain in `cat $domain_list`
do
ip1=`dig @$ns1_ip +short $domain |tail -n1`;
ip2=`dig @$ns2_ip +short $domain |tail -n1`;
echo -en "$domain,$ip1,$ip2\n" >> dns-test-results.csv;
#
done;
答え1
まず、アイテムを配列に保存して数を計算し、各ループ反復で処理されたアイテム数と合計アイテム数を印刷できます。
たとえば、次のようになります。
items=( $(cat items.txt) )
i=0; for x in "${items[@]}"; do
printf "\r%d/%d" "$(( i += 1 ))" "${#items[@]}";
sleep 1 # do some actual work here
done
echo
しかし、トークン化に頼るのは$(cat file...)
少し問題があるので、以下をreadarray
使用して各入力ファイルを配列要素として読み取る方が安全です。
readarray -t items < items.txt
答え2
ilkkachuの提案と同様に、whileループを使用して読むことができます。
#!/bin/bash
# File name of domain list: One FQDN per line in file.
domain_list='domains.txt'
number=$( wc -l < "$domain_list")
#
# IP address of the nameserver used for lookups:
ns1_ip='1.1.1.1' # Cloudflare
ns2_ip='9.9.9.9' # Quad9
#
# Seconds to wait between lookups:
loop_wait='1'
#
echo "Domain name, $ns1_ip,$ns2_ip" > dns-test-results.csv;
count=0
while read -r domain
do
(( count++ ))
printf '\rProcessing domain %d of %d' "$count" "$number"
ip1=$(dig @$ns1_ip +short $domain |tail -n1);
ip2=$(dig @$ns2_ip +short $domain |tail -n1);
printf "%s,%s,%s\n" "$domain" "$ip1" "$ip2" >> dns-test-results.csv;
sleep "$loop_wait"
#
done < "$domain_list"
echo
上記のコードは、現在見ている数字の位置Processing domain x of y
とその中にある行の総数を印刷します。x
y
$domains_list
答え3
printf .
レコードを確認するたびにそれをスクリプトに追加できます。そしてpvを通してパイプします(domains.txt
各レコードが行で区切られていると仮定します)。
script.sh | pv -p -s "$(wc -l < domains.txt)" > /dev/null
しかし、あなたはより良いことができます。
代わりにecho -en "$domain,$ip1,$ip2\n" >> dns-test-results.csv;
、あなたはただ所有することができますecho "$domain,$ip1,$ip2"
。その後、行モードを使用pv
してより「関心の分離」方法で呼び出します。
script.sh | pv -p -l -s "$(wc -l < domains.txt)" > dns-test-results.csv
答え4
トラップを使用して、シェルに定期的に進捗情報を印刷させることができます。
#!/bin/bash
# child sends SIGUSR1 to the parent every $PERIOD seconds.
MAINPID=$BASHPID
PERIOD=3
pinger() {
(
trap exit ERR
while true
do
sleep $PERIOD
kill -USR1 $MAINPID
done
) &
}
# ====
# when main process receives SIGUSR1, print some progress info
trap progress SIGUSR1
progress() {
printf "Progress: %d spins are spun\r" $COUNT
return
}
# ====
# Start the pinger
pinger
# actual work goes here
for((COUNT=1; COUNT<300; COUNT++))
do
sleep 0.100
done
exit