2012-05-02 3 views
1

우리는 cron에 의해 호출되고 루트로 실행되는 쉘 스크립트를 가지고 있습니다.Bash 스크립트의 함수에서 파일 디스크립터 누수

이 스크립트는 로깅 및 디버그 정보를 출력하며 특정 시점에서 오류가 발생했습니다. 이 지점은 스크립트가 생성하는 출력량에 따라 다릅니다 (예를 들어 디버깅 출력을 더 많이 사용하게되면 더 빨리 실패합니다).

그러나 스크립트를 직접 사용자로 호출하면 문제없이 작동합니다.

이후 우리는 문제를 증명하는 간단한 테스트 케이스를 만들었습니다.

스크립트는 다음과 같습니다

#!/bin/bash 
function log_so() { 
    local msg="$1" 
    if [ -z "${LOG_FILE}" ] ; then warn_so "It's pointless use log_so() if LOG_FILE variable is undefined!" ; return 1 ; fi 
    echo -e "${msg}" 
    echo -e "${msg}" >> ${LOG_FILE} 
    (
    /bin/true 
) 
} 


LOG_FILE="/usr/local/bin/log_bla" 

linenum=1 
while [[ $linenum -lt 2000 ]] ; do 
    log_so "short text: $linenum" 
    let linenum++ 
done 

이 도달 한 가장 높은 (cron을 통해 호출 할 때) 죽어 전에 244입니다. 함수에서 어떤 조합의 서브 쉘을 사용하고 또한 사실/빈/호출하지만이 작동하지 않았다하지 않는 것이 좋습니다

다른 어떤 검색, 서브 쉘 옵션은 기본 스크립트 가능하지 않습니다.

우리는 또한 루트에 대한 파일 설명자 제한을 변경 시도,하지만 도움이되지 않았고, 스크립트 #!/빈/sh와 #!/빈/bash는 모두를 사용하여 시도했다. 우리는 bash는 4.1.5을 사용하는

(1) 우분투 10.04 LTS에 -release.

해결 방법에 대한 아이디어 나 권장 사항에 감사드립니다.

+0

128의 ulimit가있는 경우에도 Fedora 16, GNU bash, 버전 4.2.24 (1) -release에서 복제 할 수 없습니다.보다 구체적인 포럼으로의 마이그레이션을 제안하십시오. –

+1

방금 ​​배틀 4.1 이상 버젼 4.2에서 수정 된 버젼이며, 배쉬 업그레이드가 옵션인지는 모르겠다. 그래서 배쉬 4.1.x 용 솔루션을 찾고 싶다면 if 하나 존재합니다. –

답변

1

fd를 손으로 열고 나중에 청소하면 어떨까요? 테스트 할 bash 4.1이 없지만 도움이 될 것입니다.

LOG_FILE="/usr/local/bin/log_bla" 

exec 9<> "$LOG_FILE" 

function log_so() { 
    local msg="$1" 
    if [ -z "${LOG_FILE}" ] ; then warn_so "It's pointless use log_so() if LOG_FILE variable is undefined!" ; return 1 ; fi 
    echo -e "${msg}" 
    echo -e "${msg}" >&9 
    return 0 
} 

linenum=1 
while [[ $linenum -lt 2000 ]] ; do 
    log_so "short text: $linenum" 
    let linenum++ 
done 

exec 9>&- 
+0

우리는 이것을 시도해 보았습니다. 그리고 4.1에서 우리는 작동하지 않습니다. 우리는 현재 출력물 일부를 제거하고 통합하기 위해 스크립트로 리팩토링하는 작업을하고 있습니다. bash (ATM 옵션이 아님)를 업그레이드 할 필요가없는 솔루션이 있고, 더 많은 출력이 가능하면 도움이 될 것입니다. –