셸 스크립트를 작동 시키려고 시도하는 동안 약간의 스 텀퍼가 실행되었습니다. 나는 데이터베이스에서 한 줄을 읽고 텍스트 파일로 포맷하여 다른 소프트웨어와 함께 사용하는 스크립트를 만들고자한다. 스크립트는 약 5 천만 번 (대형 데이터베이스) 반복해야하며, 5,500 ~ 5,800 회 반복 될 때까지 문제가 없으므로 세그멘테이션 오류가 발생합니다.
strace (지난 몇 줄 아래에 있음)를 사용하여 오류를 추적하려고 시도했지만 실제로 무엇을보고 있는지 잘 모르겠습니다.셸 스크립트 - 분할 오류
clone(child_stack=0,flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17547
close(4) = 0
close(5) = 0
pipe([4, 5]) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17548
close(3) = 0
close(5) = 0
pipe([3, 5]) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17549
close(4) = 0
close(5) = 0
pipe([4, 5]) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17550
close(3) = 0
close(5) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17551
close(4) = 0
close(-1) = -1 EBADF (Bad file descriptor)
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17546
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17547
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17548
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17549
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17551
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17550
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17545
--- SIGCHLD (Child exited) @ 0 (0) ---
write(1, "OK!\n", 4OK!
) = 4
pipe([3, 4]) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17552
close(4) = 0
read(3, "10632\n", 128) = 6
read(3, "", 128) = 0
close(3) = 0
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17552
--- SIGCHLD (Child exited) @ 0 (0) ---
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17553
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17553
--- SIGCHLD (Child exited) @ 0 (0) ---
write(1, "Preparing file 10632 of ", 24Preparing file 10632 of) = 24
write(1, "51041073(7) ....", 1651041073(7) ....) = 16
pipe([3, 4]) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17554
close(4) = 0
read(3, "8\n", 128) = 2
read(3, "", 128) = 0
close(3) = 0
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17554
--- SIGCHLD (Child exited) @ 0 (0) ---
pipe([3, 4]) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17555
close(4) = 0
read(3, "", 128) = 0
close(3) = 0
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV}], 0, NULL) = 17555
--- SIGCHLD (Child exited) @ 0 (0) ---
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Segmentation fault
스크립트
은 다음과 같습니다 : 정보의 중편 소설에 대한
#!/bin/sh
#----VARS----
prefix="10.0.3.2/read/"
oprdir="/home/andrew/doc/read/"
throttle=0
#----------------
x=5000
advcount=0
count=`curl "$prefix""count.php" 2> /dev/null`
#----Funcs----
getline()
{
#Run curl to get the line of text
#TODO -n
echo -n "Preparing file" $x "of "
if [ $advcount -ge 25 ]
then
count=`curl "$prefix""count.php" 2> /dev/null`
advcount=0
fi
echo -n $count"("$advcount")" "...."
advcount=`expr $advcount + 1`
line=`curl "$prefix""testfile-prep.php?x=$x" 2> /dev/null`
if [ "$line" = "ERR ERROR: X OUTSIDE RECORDS." ]
then
echo "ERROR: X OUTSIDE DB... WAITING TO RETRY."
sleep 60
getline
fi
prepline
}
prepline()
{
echo $line | sed 's/^[0-9]*\./\n./g' | sed 's/\([a-zA-Z]*\)\./\1\n./g' | sed 's/\,/\n\,/g' | sed 's/(\(.*\)/(\n\1/g' | sed 's/\(.*\))/\1\n)/g' | sed 's/ /\n/g'> out-0-$x.dat
echo "OK!"
#cat out-$x.dat
advance
}
advance()
{
x=`expr $x + 1`
sleep $throttle
getline
}
cd "$oprdir"
getline
죄송는, 어떤 도움이 감사합니다.
* "스크립트를 5 천만 회 반복해야합니다."*이 말을해야합니다. 컴파일 된 (또는 JIT 가상 머신) 구현이이 사용 사례에 좋은 아이디어 일 수 있습니다. 아니면 IO 바인딩 된 그대로 표시 할 수 있습니까? – dmckee
'prepline' 함수는'sed -e 'command1 -e'command2 '...'를 사용하여 여러 개의'sed' 명령을 하나의 명령으로 조합 할 수 있습니다. 이것은 아마도 충돌과 관련이 없지만 프로세스 수를 상당히 줄입니다. –