這是應該工作的批處理代碼。
@echo off
setlocal EnableDelayedExpansion
set "LOG_FILE=C:\program.log"
del "%LOG_FILE%" 2>nul
for /F "delims=" %%a in ('dir "C:\temp\*" 2^>nul') do call :LOGDEBUG "%%a"
endlocal
goto :EOF
:LOGDEBUG
set "StringToOutput=%~1"
echo DEBUG: !StringToOutput!
echo [%DATE% - %TIME%] DEBUG: !StringToOutput!>>"%LOG_FILE%"
goto :EOF
啓用首次延遲的環境變量擴展並創建現有環境表的副本。下面解釋爲什麼這樣做。
接下來將具有完整路徑的日誌文件的名稱分配給局部變量表中的環境變量。此路徑可以帶有或不帶有1個或更多空間。如果以前的運行已經存在,日誌文件將被刪除。如果您想將新行添加到已存在的文件中,則可以刪除此代碼。但在這種情況下,應該添加代碼以避免日誌文件永久增加,直到不再有空閒存儲空間。
的FOR命令執行命令DIR並處理DIR的輸出寫入到標準輸出的每一行。空白行被跳過。默認分隔符是空格,製表符和換行符。正如這裏所要求的是DIR的全部行,默認分隔符列表被替換爲空,這意味着只有換行符保留,並且循環變量%a
總是被分配一個完整的非空行。
命令的輸出DIR包含<
和>
如果沒有引用的線內發現由命令處理器,其被解釋爲redirection operators。因此,DIR輸出的行通過引用子程序LOGDEBUG
。在命令提示符窗口中執行cmd /?
時,必須通常引用哪些字符列在打印到命令提示符窗口的最後一個幫助頁面上。
當循環結束時,本地環境表被刪除,這意味着LOG_FILE
和StringToOutput
也被刪除,並且以前的環境被恢復,這通常意味着在批量執行退出並跳轉到預定義標籤之前,延遲擴展會再次關閉到文件結尾。
該子程序LOGDEBUG
首先將傳遞的字符串分配給一個環境變量,不需要使用周圍的引號,因爲行中的特殊字符如<
和>
。
接下來將該行寫入控制檯窗口,而不使用延遲擴展引號,否則<
和>
將被解釋爲重定向運算符,而不是字面意思。
將同一行寫入日誌文件,並在行首插入日期和時間的差異。您錯過代碼中的date
之後的百分號。再次延遲擴展用於將字符<
和>
寫入文件而不被解釋爲重定向操作符。
重要的是,在>>
之前沒有空格,否則日誌文件中的每行都會有尾隨空格。 2>&1
在這裏沒用,作爲命令echo沒有寫點東西給stderr。
子程序退出時跳轉到文件結尾,導致命令FOR處理下一行。
爲了解所使用的命令及其工作方式,請打開命令提示符窗口,在其中執行以下命令,並仔細閱讀爲每個命令顯示的所有幫助頁面。
call /?
del /?
dir /?
for /?
goto /?
set /?
這將是當然可以做所有的輸出可怕在命令主體FOR中可以不使用子程序。
@echo off
setlocal EnableDelayedExpansion
set "LOG_FILE=C:\program.log"
del "%LOG_FILE%" 2>nul
for /F "delims=" %%a in ('dir "C:\temp\*" 2^>nul') do (
echo DEBUG: %%a
echo [!DATE! - !TIME!] DEBUG: %%a>>"%LOG_FILE%"
)
endlocal
延遲變量擴展然而這裏需要另有%DATE%
和%TIME%
將由命令處理器等擴大已經在解析FOR命令之前通過(
和)
定義整個塊在所有這將導致執行將相同的日期和時間寫入日誌文件的所有行。
檢查此http://stackoverflow.com/a/10719322/388389 – npocmaka
如何定義'%LOG_FILE%'變量?並嘗試'echo CALL:LOGDEBUG「%% a」'而不是'CALL:LOGDEBUG「%% a」'來查看例如'CALL:LOGDEBUG「驅動器C中的卷是SysDisk」'(: – JosefZ
嗨@npocmaka,我希望在打印前格式化日誌文件和控制檯輸出,我想我不能直接使用tee.bat,對嗎? – Elliott