무한 루프 쉘 스크립트의 메모리 사용량

무한 루프 쉘 스크립트의 메모리 사용량

그래서 다음과 같이 MySQL 데이터베이스를 업데이트하기 위한 쉘 스크립트가 있습니다.

#!/bin/sh
mysql -h "localhost" -u "root" "-p********" "database" < "update.sql"
sleep 5
sh $0

5초 동안 잠자기 상태가 된 다음 sh $0사용자 개입 없이 스크립트를 무한정 다시 실행합니다. 그러나 내 질문은 메모리에 관한 것입니다.

저는 쉘 스크립트를 처음 접했지만 이것이 루프에서 메모리가 천천히 축적되는 방식입니까? 원격 서버가 메모리를 회수합니까, 아니면 스크립트가 결국 컷오프 지점에 도달합니까? (아니면 메모리 누수로 인해 충돌이 발생합니까?)

답변1

이것은 루프가 아니며 재귀적이며 시간이 지남에 따라 메모리가 선형적으로 증가하므로 원하지 않습니다.

일정한 메모리 사용량을 갖는 루프를 원한다면 다음과 같이 할 수 있습니다:

#!/bin/sh
while 1; do
  mysql -h "localhost" -u "root" "-p********" "database" < "update.sql"
  sleep 5
done

답변2

쉘에 따라 다릅니다. 일부는 테일 콜 최적화를 수행하고 일부는 그렇지 않습니다. 를 실행하여 쉽게 테스트할 수 있습니다 SHELL -c 'ps $$'. 자체가 표시 되면 ps쉘이 동일한 프로세스에서 마지막 명령을 실행한 것입니다. 쉘이 표시 되면 ps쉘은 마지막이 아닌 명령과 마찬가지로 하위 프로세스의 마지막 명령을 실행합니다.

$ for s in dash bash mksh ksh zsh; do echo -n "$s "; $s -c 'ps -o comm= $$'; done 
dash dash
bash ps
mksh mksh
ksh ps
zsh ps

따라서 bash, ksh 및 zsh는 tail call 최적화를 수행하지만 dash 및 mksh는 그렇지 않습니다.

테일 호출 최적화는 스크립트의 마지막 명령에 대해서만 수행할 수 있습니다. 예를 들어 활성 트랩이 있는 경우 트랩이 트리거될 경우 쉘이 뒤에 있어야 하므로 테일 콜이 아닙니다.

exec명령 앞에 붙여서 꼬리 호출을 강제로 수행할 수 있습니다. 내장 명령은 exec동일한 프로세스에서 지정된 명령을 실행합니다. 쉘이 사라지므로 스크립트의 다른 명령은 실행되지 않습니다.

재귀는 쉘 스크립트에서 관용적이지 않습니다. 루프를 사용하는 것이 더 관용적입니다.

#!/bin/sh
while true; do
  mysql -h "localhost" -u "root" "-p********" "database" < "update.sql"
  sleep 5
done

sleep또는 신호에 의해 명령이 종료될 때 스크립트가 종료되도록 하려면 다음을 수행하십시오.

#!/bin/sh
while
  mysql -h "localhost" -u "root" "-p********" "database" < "update.sql"
  sleep 5
do
  :
done

mysql또는 실패 시 스크립트를 종료하려면 다음을 수행하십시오 .

#!/bin/sh
while
  mysql -h "localhost" -u "root" "-p********" "database" < "update.sql"
do
  sleep 5
done

관련 정보