簡體   English   中英

從批處理腳本運行 grep.exe(為 Windows 編譯的 Unix 版本)時出錯的原因是什么?

[英]What is the reason for the error on running grep.exe (Unix version compiled for Windows) from a batch script?

我嘗試從批處理腳本運行grep.exe (為 Windows 編譯的 Unix 版本)並收到此錯誤:

      0 [main] grep 7760 C:\grep.exe: *** fatal error - add_item ("\??", "/", ...) failed, errno 22
Stack trace:
Frame        Function    Args
000FFFFABB6  0018007215E (00180267E4A, 00180218E59, 00600010000, 000FFFF8B30)
000FFFFABB6  00180046E52 (000FFFF9B98, 000FFFFABB6, 00000000000, 00000000000)
000FFFFABB6  00180046E92 (000FFFF9BB0, 00000000016, 00600010000, 000003F3F5C)
000FFFFABB6  001800DEEFD (000FFFFCBB0, 000FFFFCE00, 001800CF158, 00000000000)
000FFFFCC00  00180128545 (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFCCC0  001800474B5 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000  001800460AC (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFFFF0  00180046144 (00000000000, 00000000000, 00000000000, 00000000000)
End of stack trace

在批處理腳本中運行以下行后,會顯示上述錯誤消息:

for /f "usebackq delims=" %%a in (`reg query "hklm\system\currentcontrolset\control\session manager\environment" /v Path ^| %~dp0grep -i directory_being_searched_for `) do set pathExists=true

這行代碼一開始可能看起來很復雜,但是接近末尾的grep命令是最終要執行的,它在某些時候會失敗。

似乎是什么導致了這種失敗?

如果沒有簡單的解決方案,我不介意解決方法。

%~dp0grep應該用雙引號括起來,以防grep.exe的路徑(= 批處理文件路徑)包含此列表中的空格或其他語法關鍵字符&()[]{}^=;!'+,`~命令解釋器本身在命令提示符窗口中運行時的輸出cmd /? 在最后一頁。

並且還應附加文件擴展名.exe以避免需要通過 Windows 命令解釋器在批處理文件目錄中搜索可執行文件。

但是導致致命錯誤的主要問題很可能是有問題的字符串替換為

directory_being_searched_for
  1. 字符串是否用雙引號括起來?
  2. 它是否包含正則表達式字符? *. ?
  3. 目錄是否帶有路徑,因此也包含 1 個或多個反斜杠?

grep從 Unix 移植到 Windows。 因此, grep將反斜杠解釋為轉義字符,如 C/C++/C#/JavaScript 和許多其他編程和腳本語言,而不是像 Windows 那樣的目錄分隔符。

我沒有安裝grep (從哪里下載哪個版本?),因此無法重現此問題並找出致命錯誤的原因。

但也許解決方案是使用grep選項-Fgrep將搜索字符串模式解釋為固定字符串而不是正則表達式。

for /F "usebackq delims=" %%a in (`%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path ^| "%~dp0grep.exe" -i -F "directory_being_searched_for"`) do set "pathExists=true"

但是有更簡單的解決方案,因為 Windows 有控制台應用程序findfindstr用於簡單的固定字符串搜索和簡單的正則表達式搜索。

查找示例:

for /F "usebackq delims=" %%a in (`%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path ^| "%SystemRoot%\System32\find.exe" "directory_being_searched_for"`) do echo set "pathExists=true"

操作員| 將處理STDOUTreg輸出重定向到find的輸入句柄STDIN | 必須在此處用^轉義以避免被解釋為命令因為語法錯誤會導致批處理退出。 有關更多詳細信息,請參閱有關使用命令重定向運算符的Microsoft 文章。

但是這個簡單的命令行不會驗證完整的目錄路徑是否真的包含在 Windows 注冊表中定義的環境變量PATH中。 例如,更好的驗證是:

@echo off
setlocal EnableDelayedExpansion
set "PathExists=false"
for /F "tokens=1,2*" %%A in ('%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path') do (
    if /I "%%A"=="Path" (
        set "SystemPath=;%%C;"
        set "SystemPath=!SystemPath:"=!"
        if not "!SystemPath:;directory_being_searched_for;=!" == "!SystemPath!" set "PathExists=true"
    )
)
echo Path exists: %PathExists%
endlocal

要了解使用的命令及其工作原理,請打開命令提示符窗口,在那里執行以下命令,並仔細閱讀為每個命令顯示的所有幫助頁面。

  • echo /?
  • endlocal /?
  • find /?
  • for /?
  • if /?
  • reg /?
  • reg query /?
  • set /?
  • setlocal /?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM