2012-05-02 12 views
1

cronによって呼び出され、rootとして実行されるシェルスクリプトがあります。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です。

関数からノーオペレーションのサブシェルを使用し、/ bin/trueを呼び出すことをお勧めしますが、これは機能しないだけでなく、メインスクリプトではサブシェルオプションが実行できません。

また、rootのファイル記述子の制限を変更しようとしましたが、それは役に立たず、#!/ bin/shと#!/ bin/bashの両方をスクリプトで使用しようとしました。

私たちはUbuntu 10.04 LTSでbash 4.1.5(1)-releaseを使用しています。

回避策の候補や推奨事項はありがたいです。

+0

のFedora 16、GNUのbashの上に複製することができない、バージョン4.2.24(1)より具体的なフォーラムへの移行を提案さえ128のulimitを用いて、-release。 –

+1

これは4.2で修正されたbash 4.1以前のバグであることを知りました.bashのアップグレードがオプションであるかどうかは分かりません。したがって、bash 4.1.xの解決策1つ存在する。 –

答えて

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ではない)、非常に有用なより多くの出力を可能にします。 –

関連する問題