有時候為了方便別人使用,我們會選擇去編寫各種各樣的命令列指令碼:給Windows使用者編寫.bat
cmd批次處理指令碼,給macOS、Linux使用者編寫.sh
bash shell指令碼。
面向國內使用者當然應當首選中文作為指令碼的顯示語言,如果還要支援海外使用者使用,那麼能提供國際化多語言(i18n
)支援那是最好了,省事的也許只提供英文版本;i18n這個概念太大了,本篇文章記錄的是如何簡單的實現:根據使用者語言環境,讓指令碼自動顯示成中文或英文,當然如果你願意,同時支援更多語言也是可以的。
@echo off
::請儲存成gbk編碼.bat檔案,為了防止亂碼吞掉關鍵字元,所有多位元組字元文字後面均多放了幾個空格
::取消下面這行註釋可以切換成英文內碼錶cmd視窗
::chcp 437
::識別當前語言,0英文,1中文,2...更多支援的語言,中文識別簡單粗暴
set CurrentLang=0
ver | find "版本%qjkTTT%" > nul && set CurrentLang=1
::封裝echo輸出函數,通過2個或更多引數提供不同語言的文字,只顯示當前語言文字
goto func__echo2
:echo2
if "%CurrentLang%"=="1" echo %~1
if "%CurrentLang%"=="0" echo %~2
goto:eof
:func__echo2
::測試
call:echo2 "顯示語言:簡體中文 " "Language: English"
call:echo2 "指令碼執行啦 " "The script is running"
pause
#!/usr/bin/env bash
# 請儲存成utf-8編碼.sh檔案,將檔案設為允許執行,然後到終端中執行即可測試
# 識別當前語言,0英文,1中文,2...更多支援的語言
CurrentLang=0
if [ $(echo ${LANG/_/-} | grep -Ei "\\b(zh|cn)\\b") ]; then CurrentLang=1; fi
# 封裝echo輸出函數,通過2個或更多引數提供不同語言的文字,只顯示當前語言文字
function echo2(){
if [ $CurrentLang == 1 ]; then
echo $1; #顯示中文
else
echo $2; #顯示英文
fi
}
#測試
echo2 "顯示語言:簡體中文" "Language: English"
echo2 "指令碼執行啦" "The script is running"
read -n1 #按任意鍵退出
以上bat、bash指令碼程式碼參考自GitHub開源庫: https://github.com/xiangyuecn/RSA-csharp ,Test-Build-Run.bat
和 Test-Build-Run.sh
指令碼,無需IDE直接呼叫.NET編譯執行c#
程式碼,支援.NET Core、.NET Framework環境下PEM(PKCS#1、PKCS#8)格式RSA金鑰生成、匯入、匯出,多種常見RSA加密、簽名填充演演算法支援。
和 https://github.com/xiangyuecn/RSA-java ,同樣sh、bat兩個指令碼,無需IDE直接呼叫JDK編譯執行java
程式碼,使用bash、bat指令碼程式碼方便好使,也方便參考。
騷一點的辦法可以直接通過查詢終端的版本號中顯示文字是否包含「版本」這兩個字來判斷是中文環境還是英文環境,bash、bat cmd中均支援,主要是非常簡單(不排除部分情況下使用這種方式判斷出來的結果和實際可能不符)。另外bash裡面可以用$LANG
環境變數來判斷,也很好使。
// bat中
> ver //輸出:Microsoft Windows [版本 10.0.****.***]
//bash中
> bash -version //輸出:GNU bash,版本 5.1.16 ......
bash本身就支援函數的編寫,所有比較簡單,通過function echo2(){ ... }
來定義函數echo2
,函數內通過$1 $2 $3 ...
來獲取引數。呼叫時直接寫函數名字加引數即可完成函數呼叫:echo2 "args1" args2 args3
,引數可以用引號包裹起來(引數內有空格是必須包裹的),沒有引數就直接寫一個函數名字就完成了呼叫:echo2
。
cmd的bat指令碼裡面沒有專門定義函數的語法,但它支援標籤和goto跳轉,想到哪執行就到哪執行,巨靈活,且標籤支援call:lable
呼叫,搭配特殊的標籤eof
可以返回到call
呼叫點。
因此我們在bat指令碼裡面可以通過:echo2
來定義函數入口位置,通過goto:eof
來定義函數結束位置,函數內通過%1 %2 %3 ...
來獲取引數,%1
這種不會去掉引數首尾的引號,使用%~1
會去掉首尾的引號。
雖然通過標籤:echo2
定義了函數echo2
,但bat指令碼執行時會一行一行的執行標籤後面的函數內容,因此我們在:echo2
之前要通過goto
來跳過函數體,因此我們在函數結尾放一個:func__echo2
標籤(標籤名字隨意),函數開頭放一個goto func__echo2
,這樣執行的時候就會跳過這個函數體。
最後函數的呼叫,使用call:echo2 "args1" args2 args3
來呼叫函數,引數可以用引號包裹起來(引數內有空格是必須包裹的),沒有引數就直接寫一個call:echo2
就完成了呼叫。
bash中通過read
命令來獲取輸入,bat中通過set /p
來獲取輸入。
//bat中
set text=&set /p text=^>
//bash中
read -rp "> " text
上面這個程式碼在不同環境中均會顯示出"> "
,然後等待使用者輸入,回車後就會將文字內容存入text
變數中;值得要注意的是,bat中如果沒有輸入內容直接回車,變數將不會賦值為空,這個設定比較奇葩,因此需要在輸入前提前把變數設為空,或者輸入之後使用 || set text=
來設為空也可以。
嘿,bat指令碼這玩意跟隨系統預設編碼,要是utf-8儲存的檔案,中文準要亂碼,得在檔案開頭使用chcp 65001
強制切換成utf-8內碼錶,但下指令碼是不亂碼了,但呼叫很多程式命令輸出的內容反而變成了亂碼,還是老實用gbk編碼。
注意到bat檔案內所有多位元組字元文字(中文)後面均特意多寫了幾個空格,這是為了防止在亂碼時換行符、引號等符號被亂碼吞掉(有無作用有待考證),就算bat檔案亂碼了,也能正確執行,並且輸出裡面的英文內容。上面程式碼裡面有個 "版本%qjkTTT%"
,這個也是一個特殊處理,防止亂碼時結尾的引號被吞掉,錕斤拷 · 燙燙燙 最終抗下了所有。
【完】