回到軟體工程分享頁面

此網站目的是希望透過大家在這邊可以找到需要的資料及工具,也歡迎大家一同加入共同筆記團隊,一同分享各式各項的資訊或工具,立刻申請加入HackMD團隊吧!!!

Static Badge

另外也建立Discord群組

,歡迎大家加入:smile:


Bash Shell

常用指令

cd

切換到某個目錄(ex: nbs2)

#!/bin/sh cd /nbs2

如果有cd切換失敗回傳:

test.sh: 2: cd: can’t cd to /nbs2
: not found test.sh: ls

可能是因為換行格式是採用 Windows ,所以在Linux上會失敗。
可以用以下兩個方式調整:

  1. 在 Notepad++ 的工具列,編輯 -> 換行格式 -> 轉換成 UNIX 格式
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →
  2. 用 Linux 原生的編輯器編輯,我自己是習慣用 vi。

Windows換行符號: \r\n
CR(Carriage Return)
LF(Line Feed)
Unix換行符號: \n

find

搜尋資料夾底下符合條件的檔案

$ find . -name *.exe
# 搜尋所有sh檔案
$ find /home/user/SHELL -type f -name "*.sh" -exec sed -i 's/\r//' {} \;

df

df(磁盤空間使用情況)用於顯示文件系統的磁盤空間使用情況。

  • -h:以人類可讀的格式(例如 KB、MB、GB)顯示磁盤空間。
  • -T:顯示文件系統類型。
[user@1510013NB50 ~]$ df
Filesystem     1K-blocks      Used Available Use% Mounted on    
/dev/sdb       263174212 124391452 125344604  50% /
tools          190786784 167256396  23530388  88% /init
none            13053076         0  13053076   0% /dev
tmpfs               4096         0      4096   0% /sys/fs/cgroup
none            13055508        68  13055440   1% /run
none            13055508         0  13055508   0% /run/lock     
none            13055508        84  13055424   1% /run/shm      
none            13055508         0  13055508   0% /run/user
drivers        190786784 167256396  23530388  88% /usr/lib/wsl/drivers
lib            190786784 167256396  23530388  88% /usr/lib/wsl/lib    
tmpfs           13055508         0  13055508   0% /mnt/wsl
C:\            190786784 167256396  23530388  88% /mnt/c
D:\            783852884 709472912  74379972  91% /mnt/d
tmpfs           13055508         0  13055508   0% /tmp
tmpfs            2611100         8   2611092   1% /run/user/1000      

du

du(磁盤使用量)用於估算文件或目錄的磁盤空間使用量。

  • -h:以人類可讀的格式(例如 KB、MB、GB)顯示結果。
  • -s:只顯示摘要信息,而不顯示每個子目錄的詳細信息。
du -sh /path/to/directory

export

設定環境變數

$ export JAVA_HOME=/d/opt/java

ls

檢視目錄中的項目

  • -a 顯示所有檔及目錄 (. 開頭的隱藏文件也會列出)
  • -d 只列出目錄(不遞迴列出目錄內的檔)。
  • -l 以長格式顯示檔和目錄資訊,包括許可權、所有者、大小、創建時間等。
  • -r 倒序顯示檔和目錄。
  • -t 將按照修改時間排序,最新的檔在最前面。
  • -A 同 -a ,但不列出 "." (目前目錄) 及 ".." (父目錄)
  • -R 遞迴顯示目錄中的所有檔和子目錄。
$ ls

touch

建立新檔案

$ touch temp.txt
# 
$ /dev/null > temp.txt

echo

$ echo "AAA" > ttt.txt

## 放在最後一行
$ echo "append" >> ttt.txt

rm

mkdir

建立新資料夾

cp

複製檔案或資料夾

pwd

顯示目前路徑

$ pwd
/opt/folder

若在Windows系統中執行pwd的話,可能會顯示Windows路徑C:\Users\user,由於此路徑無法在Bash執行,所以需經過轉換

$ cygpath.exe -h
Usage: cygpath (-d|-m|-u|-w|-t TYPE) [-f FILE] [OPTION]... NAME...
       cygpath [-c HANDLE] 
       cygpath [-ADHOPSW]
       cygpath [-F ID]

Convert Unix and Windows format paths, or output system path information

Output type options:

  -d, --dos             print DOS (short) form of NAMEs (C:\PROGRA~1\)
  -m, --mixed           like --windows, but with regular slashes (C:/WINNT)
  -M, --mode            report on mode of file (binmode or textmode)
  -u, --unix            (default) print Unix form of NAMEs (/cygdrive/c/winnt)
  -w, --windows         print Windows form of NAMEs (C:\WINNT)
  -t, --type TYPE       print TYPE form: 'dos', 'mixed', 'unix', or 'windows'

$ cygpath -u C:/Users/user
/c/Users/user

grep

包含字眼

$ git log --oneline | grep NBS
# 排除master
$ git log --oneline | grep -v master

tail

# 同步顯示寫入的資料
$ tail -f /d/opt/application/server.log
#
$ tail -500f /d/opt/application/server.log

額外延伸學習

sed

取代換行符號

  • -n:沉默模式。
  • -e:直接在命令模式編輯。(可不加,請見詳解)
  • -f:程式手稿不直接在命列中打上,而是從指定的檔案中載入。
  • -i:修改檔案。
$ sed -i 's/\r//' shell.sh

awk

文字處理工具

$ ls -al 
total 73429
drwxr-xr-x 1 1510013 1049089        0 二月   29 16:08 ./
drwxr-xr-x 1 1510013 1049089        0 二月   27 13:26 ../
drwxr-xr-x 1 1510013 1049089        0 二月   29 14:48 .git/
-rw-r--r-- 1 1510013 1049089     5068 二月   29 14:47 .gitignore
drwxr-xr-x 1 1510013 1049089        0 二月   29 14:47 .vscode/
-rw-r--r-- 1 1510013 1049089  2064054 二月   29 14:27 diff_list.xlsx
drwxr-xr-x 1 1510013 1049089        0 二月   29 14:47 esb-nbs-2015/
drwxr-xr-x 1 1510013 1049089        0 二月   26 17:32 esb-nbs-2015-batch/
drwxr-xr-x 1 1510013 1049089        0 二月   29 14:47 esb-nbs-2015-flows/
drwxr-xr-x 1 1510013 1049089        0 二月   29 14:47 infinity_r8.0/
drwxr-xr-x 1 1510013 1049089        0 二月   29 14:47 infinity-deviceagent/
-rw-r--r-- 1 1510013 1049089     8057 二月   29 14:47 pom.xml
-rw-r--r-- 1 1510013 1049089       56 二月   21 17:26 README.md
drwxr-xr-x 1 1510013 1049089        0 二月   26 15:14 target/
-rw-r--r-- 1 1510013 1049089 73011858 二月   29 14:33 temp.patch

$ ls -al | awk '{print $9}'
./
../
.git/
.gitignore
.vscode/
diff_list.xlsx
esb-nbs-2015/
esb-nbs-2015-batch/
esb-nbs-2015-flows/
infinity_r8.0/
infinity-deviceagent/
pom.xml
README.md
target/
temp.patch

ln

建立短連結

$ ln --help
Usage: ln [OPTION]... [-T] TARGET LINK_NAME
  or:  ln [OPTION]... TARGET
  or:  ln [OPTION]... TARGET... DIRECTORY
  or:  ln [OPTION]... -t DIRECTORY TARGET...

$ ln -s /d/opt/test-project link-test-project

$ ls -al
lrwxrwxrwx 1 1510013 1049089       33 十一月  7 17:34 link-test-project -> /d/opt/test-project

關於變數

# 若Shell Scirpt的第一行開頭缺少符號"#!"加上所用Shell名稱,執行時可能會遭遇到不可預期的錯誤。
#!/bin/bash
#!/bin/sh
#!/bin/zsh

設定變數方式為
var=value
 
取用變數的方法為
$var

Exmaple 1:
#!/bin/sh
arthur ="我的小名"
echo $arthur
 
 (local)變數的設定,會在在同一個process中持續存在,一直到此process結束。
 
 Shell中,變數的值可以含有space的字串,帶有一個以上space的的變數,給定值的時候,必須以成對的雙引號( " )或單引號(')涵蓋之。
 

 雙引號( " )中若含有變數($var),會先將變數轉換成其實際的值,單引號(')則會將$var當成是一個值,而不會作轉換動作。

Example 2:
1. echo "arthur就是 $arthur"
2. echo 'arthur就是 $arthur '

結果:
1. arthur 就是 我的小名
2. arthur 就是 $arthur
#!/bin/bash

var1=He
var2=llo

echo $var1$var2

# Hello

echo ${var1}o$var2

# Heollo

echo "\"$var1$var2\""

# "Hello"

額外討論

source

$ source /d/opt/exportJAVA.sh
# 另外寫法
$ . /d/opt/exportJAVA.sh

特殊變數

變數 說明
$0 對應 ./test.sh 這個值。如果執行的是 ./work/test.sh, 則對應 ./work/test.sh 這個值,而不是只回傳檔名本身的部分。
$1 會取得 a,即傳入shell的第一個參數。
$2 會取得 b,即傳入shell的第二個參數。
$3 會取得 c,即傳入shell的第三個參數。$4、$5 等參數的含義依此類推。
$# 會取得 3,對應傳入shell的參數個數,統計的參數不包括 $0。
$@ 會取得 "a" "b" "c",也就是所有參數的列表,不包括 $0。
$* 也會取得 "a" "b" "c", 其值和 $@ 相同。但 $*$@ 有所不同。$*會把所有參數合併成一個字串,而 $@ 會得到一個字串參數陣列。
$? 可以取得執行 ./test.sh a b c 命令後的回傳值。在執行一個指令後,可以立即用 $? 取得該命令的回傳值。該指令可以是系統自己的指令,也可以是 shell,也可以是自訂的 bash 函數。

影響操作行為的變數

變數 功能
LANGLC_ALL 語系資料,例如使用 date 輸出資訊時,透過 LANG 可以修改輸出的訊息資料。
PATH 執行檔搜尋的路徑~目錄與目錄中間以冒號(:)分隔,由於執行檔/指令的搜尋是依序由 PATH 的變數內的目錄來查詢,所以,目錄的順序也是重要的。
HOME 代表使用者的家目錄,亦即使用者看到的 ~ 代表的目錄。
MAIL 當我們使用 mail 這個指令在收信時,系統會去讀取的郵件信箱檔案 (mailbox)。
HISTSIZE 這個與『歷史命令』有關。我們曾經下達過的指令可以被系統記錄下來,而記錄的『筆數』則是由這個值來設定的。
RANDOM 『隨機亂數』的變數。目前大多數的 distributions 都會有亂數產生器,亦即 /dev/random 檔案。讀者可以透過這個亂數檔案相關的變數 ($RANDOM) 來隨機取得亂數。在 BASH 的環境下,RANDOM 變數的內容介於 0~32767 之間,所以,你只要 echo $RANDOM 時,系統就會主動的隨機取出一個介於 0~32767 的數值。
PS1 命令提示字元,可使用 man bash 搜尋 PS1關鍵字,即可了解提示字元的設定方式。
? $? 這個變數內容為指令的回傳值,當回傳值為 0 代表指令正常運作結束,當不為 0 則代表指令有錯誤。
$ npm install
npm command not found
$ export PATH=$PATH:/d/opt/nodejs
$ npm install
[root@localhost ~]$ 
# 修改PS1變數
[root@localhost ~] (This is Cool)
$

用實作分析

#!/bin/sh js_jar=`find /usr/IBM/WebSphere/AppServer/profiles -name js.jar | head -n 1` #js_jar=$(find /usr/IBM/WebSphere/AppServer/profiles -name js.jar | head -n 1) echo "js_jar=${js_jar}" JAVA_HOME=/usr/java8_64 CLASSPATH=${js_jar} appPath=`find /usr/IBM/WebSphere/AppServer/profiles -name atcb-coding*jar | ${JAVA_HOME}/bin/java -classpath ${CLASSPATH} org.mozilla.javascript.tools.shell.Main /opt/etabs/tws_shell/getapppath.js` echo "appPath=${appPath}" atcb_fotify_a_jar=`find ${appPath} -name fortify-api*jar | head -n 1` echo "atcb_fotify_a_jar=${atcb_fotify_a_jar}" atcb_fotify_b_jar=`find ${appPath} -name fortify-fix*.jar | head -n 1` echo "atcb_fotify_b_jar=${atcb_fotify_b_jar}" atcb_codingcommon_jar=`find ${appPath} -name b-coding-common-util_etabs*jar | head -n 1` echo "atcb_codingcommon_jar=${atcb_codingcommon_jar}" atcb_serveretabs_jar=`find ${appPath} -name b-coding-server_etabs*jar | head -n 1` echo "atcb_serveretabs_jar=${atcb_serveretabs_jar}" atcb_serverservice_jar=`find ${appPath} -name b-coding-server-service_etabs*jar | head -n 1` echo "atcb_serverservice_jar=${atcb_serverservice_jar}" atcb_serverfunc_jar=`find ${appPath} -name b-coding-server-function_etabs*jar | head -n 1` echo "atcb_serverfunc_jar=${atcb_serverfunc_jar}" atcb_coding_jar=`find ${appPath} -name atcb-coding*jar | head -n 1` echo "atcb_coding_jar=${atcb_coding_jar}" ibranch_base_m_jar=`find ${appPath} -name ibranch_base_m.jar | head -n 1` echo "ibranch_base_m_jar=${ibranch_base_m_jar}" g_base_jar=`find ${appPath} -name g-base.jar | head -n 1` echo "g_base_jar=${g_base_jar}" xmlrpc_client_jar=`find ${appPath} -name "xmlrpc-client-3.1.jar" | head -n 1` echo "xmlrpc_client_jar=${xmlrpc_client_jar}" xmlrpc_common_jar=`find ${appPath} -name xmlrpc-common-3.1.jar | head -n 1` echo "xmlrpc_common_jar=${xmlrpc_common_jar}" commons_httpclient_jar=`find ${appPath} -name commons-httpclient*jar | head -n 1` echo "commons_httpclient_jar=${commons_httpclient_jar}" dom4j_jar=`find ${appPath} -name dom4j*jar | head -n 1` echo "dom4j_jar=${dom4j_jar}" ws_commons_util_jar=`find ${appPath} -name ws-commons-util*jar | head -n 1` echo "ws_commons_util_jar=${ws_commons_util_jar}" log4j_jar=`find ${appPath} -name log4j*jar | head -n 1` echo "log4j_jar=${log4j_jar}" commons_logging_jar=`find ${appPath} -name commons-logging*jar | head -n 1` echo "commons_logging_jar=${commons_logging_jar}" commons_codec_jar=`find ${appPath} -name commons-codec*jar | head -n 1` echo "commons_codec_jar=${commons_codec_jar}" JAVA_HOME=/usr/java8_64 CLASSPATH=${atcb_coding_jar}:${ibranch_base_m_jar}:${g_base_jar}:${xmlrpc_client_jar}:${xmlrpc_common_jar}:${commons_httpclient_jar}:${atcb_serveretabs_jar}:${atcb_serverservice_jar}:${atcb_serverfunc_jar}:${atcb_codingcommon_jar}:${atcb_fotify_a_jar}:${atcb_fotify_b_jar}:${dom4j_jar}:${ws_commons_util_jar}:${log4j_jar}:${commons_logging_jar}:${commons_codec_jar} ${JAVA_HOME}/bin/java -classpath ${CLASSPATH} tw.com.iisi.tcb.utility.TcbScheduleInvokeAgent http://localhost:9080/WebApp/xmlrpc dailyDb /opt/etabs/logs/etabs-schedule.txt 3600000