2023年12月15日 星期五

基礎批次檔撰寫實務

基礎批次檔撰寫實務

出處: 
https://blog.poychang.net/note-batch/


https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc758944(v=ws.10)?redirectedfrom=MSDN



---------------------

想要將指令集合起來並且自動化執行,批次檔絕對是你不可或缺的技能之一。

在 StackOverflow 上有個回答包含了很完整的批次檔樣板,template.bat,可以從這個樣版上學到很多技巧,值得一看。

批次檔基本介紹與語法

將命令提示字元(Command Prompt)中輸入的指令集結起來,輸入在文字檔中,用以批次執行,稱之為批次(Batch file)檔。

請注意!命令提示字元預設的字碼頁為 ANSI/BIG5 編碼,因此檢視 UTF-8 編碼檔案時會出現亂碼,所以批次檔的編寫應盡量使用 ANSI 的編碼方式。

副檔名

預設有下面這 2 種,在 DOS 與 Windows 9x 時代副檔名為 .bat,在 Windows NT 之後則改用 .cmd,表示在視窗模式下的命令提示字元(cmd.exe)執行。

  • bat
  • cmd

註解方式

標準是使用 rem,大小寫沒差別,另外可使用 2 個冒號來當註解符號。

  • rem
  • ::

顯示訊息

用來顯示訊息的指令是 echo,其後可加上字串或變數(可混搭),在正常的情況下,批次檔中的每道指令執行前都會先出現螢幕上,使用 echo off 指令,就可以關閉顯示指令,通常在不需要互動的批次檔中都一定會出現。

@echo off
set /P myname=Please input your name:
echo Hello %myname%
echo.
echo Today is %date% %time%
pause
  • 停止下達的指令顯示在螢幕上 => echo off
  • 空一行 => echo.
  • 顯示當前目錄 => echo %cd%
  • 顯示日期 => echo %date%
  • 顯示時間 => echo %time%

後面三個指令主要是使用 Windows 環境變數來輸出資訊。

判斷(if)

直接參考 if /?

暫停

  • pause 程式暫停,提示按任意鍵繼續
echo This Program is running...
pause
  • timeout [/T | time],程式暫停指定的秒數
echo Please wait for a while...
timeout 6

回傳值

無論是在 Linux 下撰寫 shell script 或是在 Windows 下撰寫批次檔,最近一次程式執行的回傳值判斷,在撰寫工作自動化的 Script 檔時,是非常重要的技巧。

在 Windows 環境中的慣例是,若指令成功時傳回 0,若錯誤時,依據錯誤的狀況會傳回 1 或以上的值,代表不同的錯誤狀況。

但並非所有指令都會根據正確或錯誤而有不同的回傳值,要用來判斷前請先測試一下。

ping 168.95.192.1
echo %errorlevel%
REM 成功,回傳 1

ping 123.123.123.123
echo %errorlevel%
REM 失敗,回傳 0

命令列參數

假設在命令列鍵入了下列指令

test.cmd c:\windows\notepad.exe c:\windows\write.exe

此時批次檔內部自動將命令列上的參數視為特別的變數如下表:

%0 (命令)%1 (參數1)%2 (參數2)
test.cmdc:\windows\notepad.exec:\windows\write.exe

擴充字元參數

若在批次檔內的命令列參數加上擴充字元之後,可額外得知參數的許多資訊,請參考下表

%1%~d1 (取得磁碟機代號)%~p1 (取得路徑)%~n1 (取得檔名)%~x1 (取得副檔名)
c:\windows\notepad.exec:\Windows\notepad.exe

跳行與結束程式

  • goto 標籤 (須定義標籤,標籤須單獨一行,並以冒號開頭,例如 :header)
  • goto :eof (無須定義標籤,直接結束程式之意)
  • exit /b [回傳值]

使用 exit /b 可停止批次檔或副程式的執行,若結束後需要提供回傳值讓 if 指令檢查 errorlevel 變數,可於其後面加上想要的回傳數值。

命令列特性

多行指令合併

要將分開多行的指令寫成一行,可利用 &

dir & pause

切換目錄:CD

  • 路徑中含有空白字元時,請使用雙引號括起來
cd "\winnt\profiles\username\programs\start menu"
  • 切換工作目錄至批次檔所在目錄
cd /d "%~dp0"
  • 顯示目前工作目錄
echo %CD%
  • 顯示目前磁碟機
echo %CD:~0,3%

黑洞:nul

一般用來將指令的正常訊息導向至黑洞 nul,使正常訊息不要顯示在螢幕上,然後配合判斷 errorlevel 或 %errorlevel% 變數,寫入 log 檔

ping 168.95.192.1 > nul
if errorlevel 1 echo ping target fail >> pinglog.txt

















參考資料:
命令列的藝術
https://github.com/jlevy/the-art-of-command-line/blob/master/README-zh-Hant.md

批次指令
https://db.cse.nsysu.edu.tw/~changyi/slides/os/teacher/Windows_Shell_Program.pdf


保哥的影片分享,值得一看。

沒有留言:

如何在Windows的事件檢視器event viewer,查詢開機關機的紀錄

Windows 如何 事件檢視器 查詢開機關機紀錄 Step1: 打開windows的 「 事件檢視器 」,開啟「 建立自訂檢視… 」視窗,在「事件記錄檔」選項,將「Windows 紀錄」內勾選「系統」選項。 Step2: 內含/排除事件識別碼: 」排除事件識別碼打「6005,6...