探索Windows命令行系列(3):命令行腳本基礎

来源:http://www.cnblogs.com/hanzongze/archive/2017/06/28/cmd-script-base.html
-Advertisement-
Play Games

" 1、實用功能 " "1.1、為腳本添加註釋" "1.2、控制命令的回顯" "1.3、使用數學表達式" "1.4、向腳本傳遞參數" " 2、使用變數 " "2.1、變數的命名及定義" "2.2、調用變數" "2.3、變數的作用域" " 3、結構語句 " "3.1、選擇語句" "3.2、迭代語句" ...


命令行腳本是包含可執行命令的文本文件,這些命令一般和命令行視窗鍵入的命令一致。腳本文件中的命令就是標準的文本字元,因此可以通過普通的文本編輯器,如 Windows 記事本來編輯。在腳本中輸入命令時,需要註意的是,每一條命令,或者每一組需要一起執行的命令,都因該保存在腳本的單獨一行中,以便確保命令的正確執行。

在常見的編程語言中,如 C/C++/C# 等語言中每條語句都要用分號來表示結束。而在命令行腳本中,沒有諸如分號之類的特定終止符,而是通過斷行(比如按下Shift+Enter鍵)、回車與斷行(按下Enter鍵)、文件結尾標誌三種方式來表示語句結束。

1、實用功能

1.1、為腳本添加註釋

rem 命令用於註釋單行命令,類似與 C# 等語言中註釋符//。需要註意的是,當在批處理文件中通過 rem 命令註釋了某一行之後,該行就不會被執行了,但預設被註釋的命令內容還是會被回顯到視窗上,這時候可以結合下麵將要講到的 @ 命令,寫成 @rem 就一定不會顯示了。

1.2、控制命令的回顯

echo@兩個命令,echo命令用於在命令回顯消息、關閉或打開命令回顯(當回顯處於打開狀態,執行批處理文件時將逐條顯示批處理文件中的命令行;相反,當回顯處於關閉狀態時,不會顯示命令行本身),而@命令用於以行為單位控制命令的回顯方式。

示例 1:向命令行回顯一條消息(Hello Word!)

echo Hello Word!

示例 2:關閉命令行回顯(關閉回顯之後就看不到命令提示符前的路徑了)

echo off

示例 3:打開命令行回顯(預設打開)

echo on

示例 4:在任何一行命令前加上@即可關閉該行的回顯

@echo Hello Word! 

1.3、使用數學表達式

命令行腳本支持算術運算、賦值運算、比較運算、按位運算等常見的數學運算。所有數學運算都得在set命令的參數/a之後進行。

示例:

set /a add=3+7
set /a sub=3-7
set /a mul=3*7
set /a div=5/2
set /a mod=5%2
set /a exp=2*2*2

1.4、向腳本傳遞參數

在調用命令行腳本的時候還可以向腳本傳遞參數。傳遞給腳本的每一個參數都可以用形參進行檢查和解釋。第1個參數用%1表示,第2個參數用%2表示,依次類推,第9個形參為%9。但如果向腳本傳遞的參數多於9個,則會被保存到一個特殊的參數變數%*中去,通過shift命令可以查看%*中的實參;另外在必要的時候,還可以通過shift命令進行形參移位,譬如shift /2表示忽略第2個參數,從第3個參數開始往前移動。還有一個特殊的形參是%0,它代表當前腳本的名稱。

示例:

在 D 盤新建一個記事本,然後鍵入下麵的腳本:

@echo 當前腳本的名稱是:%0
@echo 第1個參數的值是:%1
@echo 第2個參數的值是:%2
@pause

將記事本改名為 try.bat,然後打開命令行(cmd.exe)調用該腳本:

try abc 123

結果如下:
cmd03

2、使用變數

在命令行腳本中,我們通常所說的變數更可能是指環境變數。環境變數有多種來源,有內置在操作系統之中的,也有在系統啟動時來自系統硬體的,這些被稱之為內置系統變數,對所有 Windows 進程都可用。系統變數也可來自 Windows 註冊表。除內置系統變數之外,還有一些登錄時設置的變數,這種變數被稱為內置用戶變數。

通過set命令可以查看當前命令行實例中所有變數及變數值。除標準的系統變數和用戶變數之外,還可以通過set命令在命令行中隨時創建或設置變數。

有些變數在命令行中有著特殊的含義,如 path、computername、homedrive、errorlevel 等。其中 errorlevel 變數可以追蹤最近使用命令的退出代碼。如果命令正常執行,則錯誤級別為 0;如果命令在執行過程中出錯,則錯誤級別會被設置為一個適當的非 0 值(1 表示一般的錯誤,2 表示執行錯誤,意味著命令沒有正確執行,-2 表示算數錯誤)。

2.1、變數的命名及定義

在命令行腳本中,變數名是大小寫不敏感的,在定義變數的時候可以區分大小寫,但在調用的時候不區分大小寫。變數名可以是任意字母、數字或字元的組合,如 2s、38、? 等理論上都是合法的變數名。儘管如此,我們也還是應該要使用便於理解的名字來做為變數名。

在命令行中聲明變數時必須同時為其賦值,定義變數的語法如下:

set variable_name=variable_value

在變數名和變數值中,空格都是有效的,但一般不建議使用。命令行也不對具體的數據類型進行區分,所有的變數都是以字元的形式存儲,即使變數值設置為數值也是如此。但在進行數學運算的時候,命令行是可以判斷出字元串是否為數值的。

有些字元是命令行的保留字元,如 @、<、>、&、|、^ 等,在使用這些字元的時候,無論出現在變數值中的那個位置,都必須使用轉碼字元 ^ 對其進行轉碼。

示例:

set var1=abc
set var2=985
set var3=3.14
set var4="ok"
set var5="2^&3"
set "name=張三"

2.2、調用變數

在命令行中任何需要用到變數的地方都可以調用變數,調用的方式是用兩個百分號包裹變數名,即%variable_name%

示例:

echo %var3%                       輸出變數 var3 的值
echo %name%                       輸出變數 name 的值
cd %systemroot%\system32          切換到系統目錄下的 system32 目錄中
set syspath=%systemroot%\system32 定義一個變數 syspath 並用其它變數為其賦值

綜合案例:

@rem 定義變數接收用戶輸入
@echo off
@set /p str=請輸入任意內容,然後回車:
@echo 您剛剛輸入的內容是:%str%
@pause

2.3、變數的作用域

在命令行中用set命令所做修改的作用範圍是局部化的,也就是說set命令的作用僅限當前會話視窗,視窗關閉後之前的修改就會失效。

有時候可能還需要對變數的作用範圍做進一步約束,使其僅作用於腳本的某一部分。要做到這一點,可以通過setlocal命令來標記一個局部範圍的開始,使用endlocal命令來標記一個局部範圍的結束。

示例:

setlocal
set cnt=5
endlocal

在一個比較長的作用範圍內,使用完變數之後,應該要對其進行適當處理,以便釋放該變數占用的記憶體,防止無意間再次引用該變數時出現預期之外的結果。在命令行中只要把變數的值設置為空,該變數就不復存在了。

示例:

set var3=

3、結構語句

3.1、選擇語句

命令行中的選擇語句是 if,該語句有 3 中不同的形式,本節將逐一介紹。

普通的 if 語句:如果條件為真則執行該語句,否則繞過該語句。

語法(語法中的圓括弧並非必須,但使用圓括弧會使語句結構更加清晰):

if condition (statement1) [else (statement2)]

示例:

set v1=1
if %v1%==1 (echo is one) else (echo is not one)
if %v1%==1 (hostname & ver & ipconfig /all)

如果存在 try.bat 文件,則把該文件的內容輸出到控制台:

if exist try.bat type try.bat

if not 語句:如果條件為假則執行該語句,否則繞過該語句。

語法:

if not condition (statement1) [else (statement2)]

示例:

if not %errorlevel%==0 (echo error has occurred) else (echo running well)

if defined & if not defined:這兩個語句用於檢查某變數是否存在。

語法:

if defined variable_name statement
if not defined variable_name statement

在用於安全檢查的時候,這兩個語句非常有用。第一個語句是在變數存在的時候,執行某條命令。第二個語句是在變數不存在的時候,執行某條命令。

示例:

if defined v1 (echo %v1%)

3.2、迭代語句

命令行中的迭代語句是 for,該語句與常見的編程語言(如 C#)中的 for 迴圈有很大的不同。命令行中的 for 語句主要用於在成組的文件與目錄中進行迭代處理,並以行為基礎分析文本文件、字元串以及命令的輸出信息。

最常見的 for 語句語法如下:

for iterator do (statement)

語法中的 iterator 用於控制 for 迴圈的執行。對 iterator 中每一個步驟或元素,都會執行特定的語句。它可以是單一的一條命令,也可以是使用命令管道、命令鏈、命令分組等技術組合起來的多條命令。

iterator 通常包含一個初始化變數和一組需要反覆執行的元素,比如需要遍歷的一組文件或某範圍內的一組值。初始化變數也就是要使用的值的占位符,使用初始化變數時,需要註意以下幾點:

  • 變數只存在於 for 語句的上下文中。
  • 變數名必須在 a~z 或 A~Z 的範圍內,比如 %%a、%%b、%%c。
  • 變數名是大小寫敏感的,也就是說,%%a 與 %%A 是不同的。

常見迭代形式表如下:

迭代功能 語法格式
文件集合 for %%variable in (fileSet) do statement
目錄集合 for /D %%variable in (directorySet) do statement
子目錄中的文件 for /R[path] %%variable in (fileSet) do statement
遍歷一系列的值 for /L %%variable in (stepRange) do statement
分析文本文件、字元串以及命令輸出 for /F[options] %%variable in (source) do statement

上表中提供的迭代形式也可以在命令行中互動式地使用 for 語句,這種情況下,應該使用 %variable,而不是 %%variable。除此之外,腳本中的 for 語句與在命令行中使用 for 語句是完全一樣的。

遍歷一系列值:用於操作數值。

語法:

for /l %%variable in (start,step,end) do (statement)

示例(輸出 1~9 之間的奇數):

@for /l %%v in (1,2,9) do @echo %%v

在成組的文件中迭代執行:用於操作文件組中的文件。

語法:

for %%variable in (fileSet) do statement

語法中的 fileSet 用於指定需要處理的文件集,文件集可以是如下形式。

  • 通過文件名指定為單獨的文件,如 myfile.txt。
  • 通過文件名通配符指定一組文件,如 *.txt。
  • 使用空格分割的多個文件或文件組,如 myfile.txt .doc .docx。

示例 1(輸出 D:\Workspace 目錄中所有 txt 文件的全路徑名):

for %%i in (D:\Workspace\*.txt) do (echo %%i)

示例 2(輸出 D:\Workspace 目錄及其子目錄中所有 txt 文件的全路徑名):

for /r D:\Workspace %%i in (*.txt) do (echo %%i)

示例 3(輸出 D:\Workspace 目錄及其子目錄中所有 jpg 或 png 文件的全路徑名):

for /r D:\Workspace %%i in (*jpg,*png) do (echo %%i)

示例 4(輸出 D:\Workspace 目錄及其子目錄中所有文件的全路徑名):

for /r D:\Workspace %%i in (*) do (echo %%i)

示例 5(輸出 D:\Workspace 目錄及其子目錄中所有名稱包含 windows 的文件全路徑名):

for /r D:\Workspace %%i in (*windows*) do (echo %%i)

示例 6(輸出 D:\Workspace 目錄及其子目錄中所有路徑包含 windows 的文件夾全路徑+windows):

for /r D:\Workspace %%i in (windows) do (echo %%i)

從上述幾個例子中也能看出來,匹配模式中第一個字元必須是星號,否則就匹配不到文件了。如果完全不帶星號則會匹配到路徑包含指定字元的文件夾全路徑+指定字元。

在目錄中迭代執行:用於操作目錄組中的目錄。

示例(輸出 D:\Workspace\ 中所有的子目錄名):

for /d %%v in (D:\Workspace\*) do echo %%v

3.3、子程式 & 過程

使用子程式:也就是通過goto跳轉到另一段程式繼續執行。goto的作用是將命令解釋器直接跳轉到批處理腳本中某個標記行。

示例:

@if not defined v (@echo error: Undefined parameters!) & (goto exit)
@if %v%==1 goto subroutine1
@if %v%==2 goto subroutine2
@if %v%==3 goto subroutine3
@goto exit

:subroutine1
@echo In subroutine 1
@goto exit

:subroutine2
@echo In subroutine 2
@goto exit

:subroutine3
@echo In subroutine 3
@goto exit

:exit
@echo Exiting...

使用過程:也就是在腳本中調用其它腳本,而又不會退出原腳本。進行過程調用時,命令行會執行調用的腳本,逐一執行其中的命令,結束後返回到原腳本,並從過程調用語句的下一行語句開始執行。

示例:

@if %v%==1 call file1

上例中,如果不適用call語句,也能調用 file1 腳本,但在 file1 腳本執行完畢之後控制權不會返回給調用者(原腳本)。

call 命令用於調用另外一個批處理文件。常用的方式就是call sample.bat,新擴展的一個用法是call :label arguments,也就是用 call 來調用 bat 文件內部的一段腳本,然後用 exit 來退出當前的 call 調用。

4、總結

本文主要講述了命令行腳本的註釋、回顯、參數、變數、結構控制語句等基礎內容。

本文鏈接http://www.cnblogs.com/hanzongze/p/cmd-script-base.html
版權聲明:本文為博客園博主 韓宗澤 原創,作者保留署名權!歡迎通過轉載、演繹或其它傳播方式來使用本文,但必須在明顯位置給出作者署名和本文鏈接!個人博客,能力有限,若有不當之處,敬請批評指正,謝謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MongoDB基本命令用法成功啟動MongoDB後,再打開一個命令行視窗輸入mongo,就可以進行資料庫的一些操作。輸入help可以看到基本操作命令:show dbs:顯示資料庫列表 show collections:顯示當前資料庫中的集合(類似關係資料庫中的表) show users:顯示用戶us ...
  • 1、查詢表中所有數據 select * from 表名; 例:select * from stu; 2、查詢的同時修改表中數據 select * from 表名 for update; 例:select * from stu for update; 3、往表中添加數據 insert into 表名( ...
  • 前文已有涉及,這裡作為總結重新整理一下。一、函數1、算術函數NUMERIC 是大多數 DBMS 都支持的一種數據類型,通過 NUMBERIC ( 全體位數, 小數位數 ) 的形式來指定數值的大小。-- +-*/--餘數SELECT n, p, MOD(n, p) AS mod_col FROM Sa... ...
  • String、List、Hash、Set、Sorted Set、Bitmap ...
  • 【問題一】 在使用MySQLWorkbench插入數據時,只要涉及字元串的插入就無法運行。 如下: Error Code: 1366. Incorrect string value: '\xE5\xBC\xA0\xE4\xB8\x89' for column 'name' at row 1 【問題二 ...
  • 數據表:數據表(或稱表)是資料庫最重要的組成部分之一,是其他對象的基礎。 1、首先我們打開一個資料庫(這裡我打開的是新創建的一個aaa資料庫)。 打開資料庫:use + 資料庫名; 2、開始創建一個表,表名定為tb1。 行稱之為記錄,列稱之為欄位。 創建一個為名字、年齡、工資的表 VARCHAR 為 ...
  • 沒錯,這又是我從我的OneNote上複製過來的,於是又變成了一張好長好長的圖片。我能怎麼辦,我也很絕望, 感興趣就湊合看吧。 現在開發項目基本上持久層都是用框架(hibernate或者mybatis),所以呢,這個東西基本上用不到,既然有大神封裝的非常好,我們為什麼要自己寫呢。但是, 這個可以幫助我 ...
  • ---查看所有存儲過程或視圖的位置 select a.name,a.[type],b.[definition] from sys.all_objects a,sys.sql_modules b where a.is_ms_shipped=0 and a.object_id = b.object_id... ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...