2011-07-11 69 views
0

我有一個巨大的bash腳本,我想將特定的代碼塊記錄到特定的&小日誌文件(而不是一個巨大的日誌文件)。記錄代碼塊以便在bash中記錄文件

我有以下兩種方法:

# in this case, 'log' is a bash function 

# Using code block & piping 
{ 
# ... bash code ... 
} | log "file name" 

# Using Process Substitution 
log "file name" < <(
    # ... bash code ... 
) 

這兩種方法都可以與bash腳本的正確執行,例如干涉將值分配給變量時(如提出的問題here)。
您如何建議將日誌文件的輸出記錄到日誌中?


編輯: 這就是我試圖做(除了許多其他的變化),但並不如預期的工作:

function log() 
{ 
    if [ -z "$counter" ]; then 
     counter=1 
     echo "" >> "./General_Log_File" # Create the summary log file 
    else 
     ((++counter)) 
    fi 
    echo "" > "./${counter}_log_file" # Create specific log file 

    # Display text-to-be-logged on screen & add it to the summary log file 
    # & write text-to-be-logged to it's corresponding log file 
    exec 1> >(tee "./${counter}_log_file" | tee -a "./General_Log_File") 2>&1 
} 

log # Logs the following code block 
{ 
    # ... Many bash commands ... 
} 

log # Logs the following code block 
{ 
    # ... Many bash commands ... 
} 

執行的結果有所不同:有時日誌文件被創建,有時它們不會(會引發錯誤)。

回答

0

由於Sahas,我設法實現以下解決方案:

function log() 
{ 
    [ -z "$counter" ] && counter=1 || ((++counter)) 

    if [ -n "$teepid" ]; then 
     exec 1>&- 2>&- # close file descriptors to signal EOF to the `tee` 
       # command in the bg process 
     wait $teepid # wait for bg process to exit 
    fi 
    # Display text-to-be-logged on screen and 
    # write it to the summary log & to it's corresponding log file 
    (tee "${counter}.log" < "$pipe" | tee -a "Summary.log" 1>&4) & 
    teepid=$! 
    exec 1>"$pipe" 2>&1 # redirect stdout & stderr to the pipe 
} 

# Create temporary FIFO/pipe 
pipe_dir=$(mktemp -d) 
pipe="${pipe_dir}/cmds_output" 
mkfifo "$pipe" 
exec 4<&1 # save value of FD1 to FD4 

log # Logs the following code block 
{ 
    # ... Many bash commands ... 
} 

log # Logs the following code block 
{ 
    # ... Many bash commands ... 
} 

if [ -n "$teepid" ]; then 
    exec 1>&- 2>&- # close file descriptors to signal EOF to the `tee` 
      # command in the bg process 
    wait $teepid # wait for bg process to exit 
fi 

它的工作原理 - 我測試了它。

參考文獻:

1

你可以嘗試這樣的事:

function log() 
{ 
    local logfile=$1 
    local errfile=$2 
    exec > $logfile 
    exec 2> $errfile # if $errfile is not an empty string 
} 

log $fileA $errfileA 
echo stuff 
log $fileB $errfileB 
echo more stuff 

這將重定向所有標準輸出/標準錯誤,從當前進程沒有任何的子進程的文件。

編輯:下面可能是一個很好的解決方案的話,但沒有測試:

pipe=$(mktemp) 
mknod $pipe p 
exec 1>$pipe 

function log() 
{ 
    if ! [[ -z "$teepid2" ]]; then 
     kill $teepid2 
    else 
     tee <$pipe general_log_file & 
     teepid1=$! 
     count=1 
    fi 

    tee <$pipe ${count}_logfile & 
    teepid2=$! 
    ((++count)) 
} 

log 
echo stuff 
log 
echo stuff2 

if ! [[ -z "$teepid1" ]]; then kill $teepid1; fi 
+0

請看看我的編輯。 – Dor

+0

+1爲您的幫助 – Dor