轉自:https://blog.csdn.net/flyoutsan/article/details/52811095
cmd變量通過set設置變量,通過可以使用set /?查看有關變量的幫助文檔。
接下來談set的用法:
1.set 變量名=值
值可以包含空格、一直到命令結束,也可以是Ctrl+G這種代表警報聲的字符(echo輸出會發出警報聲“滴~”),與echo類似
2.set 變量名
在系統中預定義了一批環境變量(所有的環境變量將附加在博客尾),如最常見的path變量,記錄了系統應用程序的默認路徑,如果僅僅使用set 變量名,那么將會打印所有以這個變量名開頭的變量為的值。例如如果set p,將會打印ProgramFiles, ProgramFIles(X86), path等以p開頭的變量的值。如果用戶通過set設置了新的變量,如set pt=point那么新變量在這個cmd中將加入環境變量,因此set p也將會打印出pt的值,與環境變量不同的是,該變量只在當前cmd有效,同時對環境變量的更改也只是在當前cmd有效。
3.set /P 變量=提示
變量將通過用戶輸入接收值,提示作為提示信息輸出,例如set /p v=輸入v的值:,那么將會出現
輸入v的值
(等待輸入)
4.set /A 變量=表達式
表達式將被視為算術表達式,變量賦值為算術表達式的值,算術運算符參照幫助文檔或者官方網站文檔(可以發現,與C語言運算符基本相同):
如果要使用其他變量的值,需要使用%變量名%(或者 !變量名!)來表示該變量。同時0X與0分別表示十六進制與八進制數字。
+ Add set /a "_num=_num+5" += Add variable set /a "_num+=5" - Subtract (or unary)set /a "_num=_num-5" -= Subtract variable set /a "_num-=5" * Multiply set /a "_num=_num*5" *= Multiply variable set /a "_num*=5" / Divide set /a "_num=_num/5" /= Divide variable set /a "_num/=5" % Modulus set /a "_num=5%%2" %%= Modulus set /a "_num%%=5" ! Logical negation 0 (FALSE) ⇨ 1 (TRUE) and any non-zero value (TRUE) ⇨ 0 (FALSE) ~ One's complement (bitwise negation) & AND set /a "_num=5&3" 0101 AND 0011 = 0001 (decimal 1) &= AND variable set /a "_num&=3" | OR set /a "_num=5|3" 0101 OR 0011 = 0111 (decimal 7) |= OR variable set /a "_num|=3" ^ XOR set /a "_num=5^3" 0101 XOR 0011 = 0110 (decimal 6) ^= XOR variable set /a "_num=^3" << Left Shift. (sign bit ⇨ 0) >> Right Shift. (Fills in the sign bit such that a negative number always remains negative.) Neither ShiftRight nor ShiftLeft will detect overflow. <<= Left Shift variable set /a "_num<<=2" >>= Right Shift variable set /a "_num>>=2" ( ) Parenthesis group expressions set /a "_num=(2+3)*5" , Commas separate expressions set /a "_num=2,_result=_num*5"
5.%變量名:str1=str2%
表示將變量的值中包含的str1使用str2替換后獲得的變量,例如
set a="minecraft great!"
echo %a: = is so %
echo %a
此時將會輸出:
minecraft is so great!
minecraft great!
這里將空格替換為( is so ),因此輸出minecraft is so great!,而%a%依然如故,說明原變量並沒有發生變化
6.%變量名(已定義):~start[, length]%
表示從start出開始(包括start,第一個計數為0),取length長的子串,如果length省略,則表示取到串尾,start可以為負數,最后一個字符為-1,從后往前依次為-2、-3、-4……
7.setlocal [Enable|Disable]DelayedExpansion
執行cmd或者bat文件是從頭向后執行,變量有一個擴展規則,即在執行一個語句塊時變量將會被變量的值代替,例如
set a=hello& echo a
這個語句通過&連接成為一個語句塊,又如
(set a=steve
if defined a echo hello %a%)
是通過()組合的一個語句塊
在執行語句塊時,a將會被a的值所代替,而語句塊中的set語句將會在該語句塊執行完后才有效,例如
set a=hello
(set a=steve
if defined a echo hello %a%)
將會輸出hello而不是steve,可以理解為當前語句塊中所有的set都在下一句語句塊執行時才有效,在當前語句塊不做任何事情
這樣將會對程序的邏輯性產生很大的影響,為了解決這個問題,我們可以使用setlocal EnableDelayExpansion。
EnableDelayedExpansion,直接翻譯為“啟用擴展延遲”,這個我們可以理解為原來的情況是在執行語句塊時所有的變量都被擴展為值了,此時還未執行set命令,而啟用后,擴展被延遲到語句塊執行結束時,此時set命令已經執行,原來變量的值已經被set為了新的值,因此set已經生效。注意,啟用后變量的調用將會變為!變量名!,如果使用%變量名%,調用的將會是未使用擴展延遲的狀態的變量(即與原來沒什么區別),與之相對的還有setlocal DisableDelayedExpansion,為相反的效果。
當執行這個命令后,在執行endlocal之前,setlocal將會一直生效,因此EndLocal就是將setlocal的效果“終結”的命令,使用后,setlocal(無論enable還是disable),效果都將end,一個setlocal對應一個endlocal。
預處理機制:批處理讀取命令時是按行讀取的(另外例如 for 命令等,其后用一對圓括號閉合的所有語句也當作一行),在處理之前要完成必要的預處理工作,這其中就包括對該行命令中的變量賦值。在不啟用變量延遲,也不對變量動態捕獲其擴展變化時,變量在預處理階段不作改變
setlocal enabledelayedexpansion ,就是啟用變量延遲,我們可以形象的認為是啟用了“對變量動態捕獲擴展變化”。而 ! 括起來的變量,就是要動態捕獲擴展的目標變量,如果不需要,可以繼續使用 % 括變量。
示例:
@echo off SETLOCAL ENABLEDELAYEDEXPANSION set var=0 for /l %%i in (1 1 10) do ( set var=%%i
rem 啟用延緩環境變量 echo !var! ....
rem 未啟用延緩環境變量 echo %var% )

8.setlocal [Enable|Disable]Extensions
啟用或者禁用Extension,部分cmd命令擁有啟用Extension后的“額外”功能,如果沒有啟用,那么功能不可用,如if。
9.setlocal
setlocal將表示setlocal后直到endlocal,所有的變量都是局部變量,例如
@echo off
set b=1
setlocal
set b=2
setlocal
set b=3
set c=hi
echo %b% %c%
endlocal
echo %b%
if defined c echo %c%
endlocal
if defined c echo %b% %c%
輸出為
3 hi
2
又如:
@echo off set a=1 setlocal set a=2 setlocal set a=3 set c=4 echo %a% %c% endlocal echo %a% endlocal echo %a% pause
輸出:

10.for %i in (set) do
在文件(bat或者cmd)中需要將%i使用%%i來代替,%%i不會出現變量擴展的問題,在循環中同步更新%%i的值(謝天謝地,一切正常)
11.bat/cmd文件 + 參數1 + 參數2 + 參數3 + ……
通過%1,%2,%3表示對參數1、2、3……的引用,%0表示bat文件的絕對路徑+文件名,如C:\Users\Administrator\Desktop\test.bat
12.系統預定義環境變量表直接輸入 set 后可以獲得
