![작업을 병렬로 실행하고 단일 파일에 쓰기](https://linux55.com/image/177731/%EC%9E%91%EC%97%85%EC%9D%84%20%EB%B3%91%EB%A0%AC%EB%A1%9C%20%EC%8B%A4%ED%96%89%ED%95%98%EA%B3%A0%20%EB%8B%A8%EC%9D%BC%20%ED%8C%8C%EC%9D%BC%EC%97%90%20%EC%93%B0%EA%B8%B0.png)
#!/bin/bash
range=$(seq -f "ma%04g" 5001 5505)
for n in $range;do
ping -q -c 1 -w 3 -s 10 $n >/dev/null
if [ $? -eq 0 ];then
awk -F, -v key="${n}" -v val="up" -v OFS="," '$1==key{$2=val}' /tmp/master.csv > /tmp/temptest.csv
cp /tmp/temptest.csv /tmp/master.csv
else
awk -F, -v key="${n}" -v val="down" -v OFS="," '$1==key{$2=val}' /tmp/master.csv > /tmp/temptest.csv
cp /tmp/temptest.csv /tmp/master.csv
done
이 포럼의 어느 곳에서나 동일한 쿼리를 요청했는지는 확실하지 않지만 xargs를 사용하거나 병렬화하여 이 프로세스의 속도를 높여 결과를 얻을 수 있는 방법이 궁금합니다. /tmp/master.csv 파일도 비워지나요?
답변1
Gnu는 parallel
루프를 쉽게 실행할 수 있지만 각 반복마다 CSV 파일을 수정해서는 안 됩니다. 출력을 새 파일로 수집한 다음 이를 기존 CSV로 병합하거나, 노드별 데이터가 없는 경우 처음부터 전체 새 CSV 파일을 작성하는 것이 가장 좋습니다.
답변2
do_one() {
n="$1"
if ping -q -c 1 -w 3 -s 10 $n >/dev/null ; then
echo up
else
echo down
fi
}
export -f do_one
seq -f "ma%04g" 5001 5505 | parallel -j0 --tag do_one {} > results
# results contains host \t up_or_down
# create files with only hostnames for up
grep up results | awk -e '{print $1}' > up-hosts
# create files with only hostnames for down
grep down results | awk -e '{print $1}' > down-hosts
# This perl script takes 1 second to run if you have 100000 hosts
perl -i.bak -ape 'BEGIN {
# make fast lookup hash for up/down hosts
chomp(@up=`cat up-hosts`);
@up{@up} = @up;
chomp(@down=`cat down-hosts`);
@down{@down} = @down;
}
sub updown {
my $host = shift;
my $last = shift;
if($up{$host}) { return "$host up" };
if($down{$host}) { return "$host down" };
return "$host $last";
}
# $1 = hostname, $2 = up/down of master.csv
s/^(\S+)\s+(\S+)/updown($1,$2)/gme;' master.csv