我想出了一個批處理腳本,通過對批處理腳本的一些谷歌搜索和分析,檢查我在用戶提示中提到的包是否存在于系統中,如果存在則獲取其版本。這是最可能的最終版本:
@echo off && setlocal EnableDelayedExpansion
set "output_cnt=0"
set /p "pkg=Package? "
for /f "delims=" %%a in ('npm -v 2^>nul') do @set "npmV=%%a"
if defined npmV (echo NPM Version: %npmV%) else (echo NPM isn't installed)
for /f "delims=" %%b in ('node -v 2^>nul') do @set "nodeV=%%b"
if defined nodeV (echo Node Version: %nodeV%) else (echo Node isn't installed)
for /f "delims=" %%c in ('npm list -g %pkg% 2^>nul') do (
set /a output_cnt =1
set "pkgV[!output_cnt!]=%%c"
)
if defined pkgV (for /l %%n in (1 1 !output_cnt!) do echo !pkg! Version: !pkgV[%%n]!) else (echo %pkg% isn't installed)
setlocal DisableDelayedExpansion && endlocal && pause
現在,當我運行這個腳本時,它會正確檢查是否安裝了 Node 和 NPM 并準確獲取它們的版本,但是當我將任何包名稱傳遞給用戶提示符時(例如,cowsay,并且這個包已安裝,我確信) ,它總是說<package> isn't installed(如cowsay isn't installed)。
如您所見,我試圖npm list -g <package>通過陣列捕獲多行的完整輸出,但它顯然搞砸了。
任何人都可以幫助找出問題所在并得到我想要的嗎?
uj5u.com熱心網友回復:
歡迎批量;陣列不是真實的!*
取而代之的是,您擁有一組變數,所有這些變數都恰好以pkgV[您可以迭代的方式開始。因此,雖然%pkgV[1]%,%pkgV[2]%等都已定義,但%pkgV%其本身并不是因為從未設定過該特定變數。
但是,由于您將始終擁有一個(%pkgV[1]%如果提供了任何有效的包),您可以檢查它pkgV[1]是否已定義并從那里開始。(或者,您可以簡單地檢查它%output_cnt%是否大于 0。)
if defined pkgV[1] (for /l %%n in (1 1 !output_cnt!) do echo !pkg! Version: !pkgV[%%n]!) else (echo %pkg% isn't installed)
* - 至少,不像其他語言那樣做陣列。
uj5u.com熱心網友回復:
你到底為什么要使用(偽)陣列?為什么不簡單地在一個回圈中完成所有操作?
我看到兩個可能的代碼部分來替換for /f %%c回圈和后續if defined pkgV條件(實際上是SomethingDark的答案中解釋的錯誤代碼片段):
使用標志樣式的變數來指示是否
npm list回傳了任何專案:@echo off & setlocal EnableExtensions DisableDelayedExpansion set "output_cnt=0" set /p "pkg=Package? " for /f "delims=" %%a in ('npm -v 2^>nul') do @set "npmV=%%a" if defined npmV (echo NPM Version: %npmV%) else (echo NPM isn't installed) for /f "delims=" %%b in ('node -v 2^>nul') do @set "nodeV=%%b" if defined nodeV (echo Node Version: %nodeV%) else (echo Node isn't installed) set "FLAG=" for /f "delims=" %%c in ('npm list -g %pkg% 2^>nul') do ( set "FLAG=#" & echo !pkg! Version: %%c ) if not defined FLAG echo %pkg% isn't installed pause通過條件執行檢測回圈的退出代碼,設定為當回圈不迭代時:
for /f %%c1@echo off & setlocal EnableExtensions DisableDelayedExpansion set "output_cnt=0" set /p "pkg=Package? " for /f "delims=" %%a in ('npm -v 2^>nul') do @set "npmV=%%a" if defined npmV (echo NPM Version: %npmV%) else (echo NPM isn't installed) for /f "delims=" %%b in ('node -v 2^>nul') do @set "nodeV=%%b" if defined nodeV (echo Node Version: %nodeV%) else (echo Node isn't installed) ( for /f "delims=" %%c in ('npm list -g %pkg% 2^>nul') do ( echo !pkg! Version: %%c ) ) || echo %pkg% isn't installed pause
NB:
順便說一句,最后的命令序列setlocal DisableDelayedExpansion && endlocal根本沒有任何意義,因為之后的狀態與沒有它的狀態相同。
如果意圖肯定是在pause命令中禁用延遲擴展,則您應該將初始行替換為原始代碼中回圈之前的@echo off & setlocal EnableExtensions DisableDelayedExpansion行并插入該行。setlocal EnableDelayedExpansionfor /f %%c
uj5u.com熱心網友回復:
如果任何輸入包都只有一個安裝版本,那么也許這對您有用:
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "nodeV="
For %%G In ("node.js") Do For /F %%H In (
'"%%~$PATH:%%G" -v') Do Set "nodeV=%%H"
If Defined nodeV (Echo Node Version: %nodeV%
) Else Echo node.js is not in your %%PATH%%
Set "npmV="
For %%G In ("npm.cmd") Do For /F %%H In (
'"%%~$PATH:%%G" -v') Do Set "npmV=%%H"
If Defined npmV (Echo NPM Version: %npmV%
) Else (Echo npm.cmd is not in your %%PATH%%
Echo Press any key to exit ...
Pause 1>NUL
Exit /B)
:GetPkg
Set "pkg="
Set /P "pkg=Package? "
If Not Defined pkg GoTo GetPkg
Set "pkgV="
For /F "Tokens=2 Delims=@" %%G In (
'npm.cmd list "%pkg%" -g 2^>NUL
^| %SystemRoot%\System32\find.exe "@"'
) Do Set "pkgV=%%G"
If Defined pkgV (Echo %pkg% Version: %pkgV%
) Else Echo %pkg% is not globally installed
Pause
EndLocal
GoTo :EOF
但是,如果您的輸入包可能有多個安裝版本,正如您的代碼所暗示的那樣,那么這種修改可能會更有用:
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "nodeV="
For %%G In ("node.js") Do For /F %%H In (
'"%%~$PATH:%%G" -v') Do Set "nodeV=%%H"
If Defined nodeV (Echo Node Version: %nodeV%
) Else Echo node.js is not in your %%PATH%%
Set "npmV="
For %%G In ("npm.cmd") Do For /F %%H In (
'"%%~$PATH:%%G" -v') Do Set "npmV=%%H"
If Defined npmV (Echo NPM Version: %npmV%
) Else (Echo npm.cmd is not in your %%PATH%%
Echo Press any key to exit ...
Pause 1>NUL
Exit /B)
:GetPkg
Set "pkg="
Set /P "pkg=Package? "
If Not Defined pkg GoTo GetPkg
For /F "Delims==" %%G In ('"(Set pkgV[) 2>NUL"'
) Do Set "%%G="
Set "output_cnt=0"
For /F "Tokens=2 Delims=@" %%G In (
'npm.cmd list %pkg% -g 2^>NUL
^| %SystemRoot%\System32\find.exe "@"'
) Do (Set /A output_cnt = 1
SetLocal EnableDelayedExpansion
For %%H In (!output_cnt!) Do (EndLocal
Set "pkgV[%%H]=%%G"))
If %output_cnt GEq 1 (
For /F "Tokens=2,* Delims=[]=" %%G In (
'"(Set pkgV[) 2>NUL"'
) Do Echo %pkg% version %%G: %%H
) Else Echo %pkg% is not globally installed
Pause
EndLocal
GoTo :EOF
請注意,以上代碼都沒有經過測驗,如果有明顯的錯別字或錯誤,請告訴我,我稍后會看。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/506660.html
下一篇:安裝solcnpm的問題
