批處理 感嘆號和變數延遲擴充套件

2021-06-22 12:05:44 字數 3327 閱讀 4579

先來說說變數延遲擴充套件吧。當然,放狗一搜,就能看到滿天飛的關於變數延遲擴充套件的文章,所以,我這裡就簡單介紹一下。先來看一段批處理:

[cpp]view plain

copy

set str=test  

if%str%==test (  

set str=another test  

echo %str%  

)

上面的**段極其簡單,給str賦值,判斷其值是否為test,如果是,重新賦值為another test,再顯示str的值。

作為正常人的思維,這裡顯示的肯定是another test了,但其實不是,其顯示的仍然是test,這是為什麼?因為:windows在解釋執行此**段時,在遇到if語句後的括號後,只把它當一條語句處理而不是兩條語句,所以,在第二條語句中的%str%會被替換成它目前的值test,上面的**相當於下面的**的效果:

[cpp]view plain

copy

set str=test  

if%str%==test (  

set str=another test  

echo test    ::注意這裡  

)

所以,輸出自然是test了。

這樣程式設計的靈活性就大大降低了,於是,m$就想了乙個workground的方法,那就是變數延遲,很簡單,看如下**:

[cpp]view plain

copy

@echo off  

setlocal enabledelayedexpansion    ::注意這裡  

set str=test  

if%str%==test (  

set str=another test  

echo !str!      ::注意這裡  

echo %str%  ::區別  

)

現在會輸出什麼呢?試一下就知道,第一行輸出another test,第二行輸出test。

現在解釋一下,setlocal enabledelayedexpansion用於開啟變數延遲,這是告訴直譯器,在遇到復合語句的時候,不要將其作為一條語句同時處理,而仍然一條一條地去解釋。但是這時必須用!str!來引用變數,如果仍然用%str%引用是不起作用的。

好了,變數延遲擴充套件解釋完了,至少這就是我知道的變數延遲擴充套件。

*************************== 我是自豪的分割線,如果你只想知道變數延遲擴充套件是怎麼回事,看到這裡就ok了 *************************==

今天變數延遲擴充套件和感嘆號讓我蛋疼了半天,所以現在也要來扯扯它們的蛋。

試試以下**段:

[cpp]view plain

copy

@echo off  

setlocal enabledelayedexpansion  

set str=test!!!  

echo %str%  

開啟變數延遲,給str賦值,輸出str,於是,輸出自然是test!!!了。但其實,windows告訴我們,又錯了,輸出是test,感嘆號被windows吃了。

當然如果注釋掉開啟變數延遲那一行,這幾行是可以正常工作的,所以說是開啟變數延遲影響了我們正常的工作,但我至今還沒搞清楚為什麼會這樣,這只有m$知道。

於是,關閉變數延遲吧,可是程式又需要使用變數延遲來實現一些邏輯,怎麼辦?兩個辦法:

1.暫時關閉變數延遲:

[cpp]view plain

copy

@echo off  

setlocal enabledelayedexpansion  

:: do

something here  

setlocal disabledelayedexpansion    ::關閉變數延遲  

set str=test!!!  

echo %str%  

setlocal enabledelayedexpansion  

:: continue

...  

在需要處理感嘆號的地方,暫時關閉變數延遲,處理完後再開啟。這時能正常輸出感嘆號。

2.在開啟變數延遲之前set:

[cpp]view plain

copy

@echo off  

set str=test!!!  

setlocal enabledelayedexpansion  

echo !str!    ::注意這裡  

在開啟變數延遲之前設定好變數,但是要注意,在使用變數的時候,需要使用感嘆號引用。這時感嘆號也可以正常輸出。

最後貼一段為什麼讓我蛋疼的**(變數延遲自然是開啟的):

[cpp]view plain

copy

set server=%~1  

set username=%~2  

set password=%~3  

echo %date%, %time% [info]   report server address: [%server%], username: [%username%], password: [*******]  

rs.exe -i "publishreports.rss"

-s "%server%"

-u "%username%"

-p "%password%"

-l 600  

為了不回顯password,我輸出了一大串*。在我機器上測試時,我的password字元都很常規,所以通過。但是,qa的password裡面有感嘆號。。。

關鍵的是,這裡呼叫的是m$的report server的rs.exe來上傳模板,它丟擲乙個could not connect的exception,於是,我自然地想到是report server的service出了問題,但查了好久也沒發現report server有什麼問題。。。誰***會想到是別人的password裡有感嘆號,誰***又會想到是跟所謂延遲變數的衝突導致的,更有誰會想到,我自己自作聰明地為了不顯示password而顯示出了一大串hard code的星號導致看不到password的值。。。

感嘆號 bash 的歷史擴充套件功能

bash 的歷史擴充套件 history expansion 又被稱為 bang 命令,歷史擴充套件是 bash 將歷史命令轉換到可執行命令的過程。bash 下的 history 庫提供了乙個與 csh 下歷史擴充套件類似的歷史擴充套件功能。歷史擴充套件中操作歷史命令一般有兩個部分 首先要從歷史命令...

批處理的延遲變數擴充套件

set num 0 for l i in 1,1,10 do set a num 1 echo i,num 這個程式應該輸出 1,12,2 3,34,4 5,56,6 7,78,8 9,910,10 實際輸出 1,02,0 3,04,0 5,06,0 7,08,0 9,010,0 這是因為批處理程式...

批處理 延遲環境變數擴充套件

延遲變數全稱 延遲環境變數擴充套件 要理解這個東西 我們還得先理解一下什麼叫擴充套件 cmd 在解釋我們的命令的時候 首先會讀取命令列一條完整的命令 然後對其進行一些命令格式的匹配操作 看你所輸入的命令格式是不是符合他的要求.如果我們要在我們的命令中引用一些變數,那麼我們如何讓 cmd在解釋我們的命...