bash가 for 루프와 충돌합니다.

bash가 for 루프와 충돌합니다.

이 질문은 사소할 수 있지만 이 간단한 for루프를 사용하면

for i in {1..10000000}; do echo "$i" line >> file
done

잠시 동안 자세히 설명한 후 내 쉘이 충돌하여(터미널 에뮬레이터의 탭이 자동으로 닫힘) file생성되지 않았습니다.

이것은 GNU bash, version 4.1.11(2)-release.

메모리 제한 때문인가요 아니면 다른 문제 때문인가요? 그렇다면 이 한도는 어느 정도여야 합니까?

그것 은 그것 으로 {1..1000000}잘 작동할 것입 니다 .

답변1

이런 일이 발생하는 이유는 명령이 호출되기 전에 대괄호가 확장되기 때문입니다. 따라서 실제로 다음과 같은 명령이 생성됩니다.

for i in 1 2 3 ... 10000000 ; do ... 

..그래서 메모리를 많이 차지하거나 충돌이 발생합니다.

긴 루프로 작업할 때의 해결책은 bash의 C 스타일 구문을 사용하는 것입니다:

for ((i = 1; i <= 10000000; i++))
do 
    ...
done

또는 다른 셸과의 호환성을 유지하려면 while 루프에 파이프할 수 있습니다.

seq 1 10000000 | while IFS= read -r line
do
     ...
done

답변2

예, 내 bash 프로세스에는 이 명령을 실행하는 데 많은 메모리가 필요합니다. 제 경우에는 1.9GB(x86_64)였습니다. 한계에 도달했을 수 있으며 커널 메모리 부족 킬러가 이를 제거했습니다. 나에게는 정말 효과가 있습니다. 약 3분 정도 소요됩니다.

 $ wc -l file
 10000000 file
 $ tail -n1 file
 10000000 line
 $ ls -hl file
 -rw-r--r-- 1 seb users 123M Sep  5 13:19 file

RAM 제한 가정 확인: 스왑 공간이 있으면 채워지는 것을 지켜볼 수 있습니다. htop이를 위해 예를 들어.

루프를 100,000,000개 요소 이상으로 더 늘리면 프로세스도 10배 더 많은 RAM을 소비합니다 18GB.

@user000001 님이 설명과 대안을 제시했습니다. 나는 테스트했다C 스타일 구문(그는):

for ((i = 1; i <= 10000000; i++))
do 
 ...
done

이 프로세스는 일반 bash 프로세스보다 더 많은 RAM을 사용하지 않습니다.

관련 정보