Basic Shell Introduction
在開始學習程式開發的過程中,我們多半仰賴 GUI 來操作系統,例如拖拉檔案、點擊按鈕等。 然而,當我們進一步接觸像是 Linux 這樣的開發環境時,會發現 CLI 成為更有效率、彈性也更高的操作方式。
這篇文章會介紹了解常見的 Shell 指令與基本語法,並分享我如何安裝與設定 Shell 環境。
WSL ZSH Installation
首先示範如何在 WSL 中啟用 zsh,並且介紹一些常用的套件及設定。
- 安裝 zsh
sudo apt update && sudo apt install -y zsh
zsh --version
- 將 zsh 設定為預設 shell
chsh -s $(which zsh)
- 安裝 Oh My Zsh 框架來管理 zsh 的設定
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
- 改變主題,我使用 Powerlevel10k 主題,這需要額外安裝,設定完之後需要重新開啟 terminal 進行設定
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/themes/powerlevel10k
ZSH_THEME="powerlevel10k/powerlevel10k"
- 安裝 zsh-syntax-highlighting,用來高亮顯示指令語法
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
plugins=(git zsh-syntax-highlighting)
- 安裝 zsh-autosuggestions,提供指令自動建議
git clone https://github.com/zsh-users/zsh-autosuggestions \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
plugins=(git zsh-syntax-highlighting zsh-autosuggestions)
- 安裝 jsonpp,用來格式化 JSON 資料
plugins=(git zsh-syntax-highlighting zsh-autosuggestions jsontools)
可以用以下指令測試一下
curl https://coderwall.com/bobwilliams.json | pp_json
- 安裝 eza (exa),可以提供更好看的 ls 指令
sudo apt install eza -y
修改 ~/.zshrc
的 alias 設定,讓 ls 指令使用 eza
alias ls='eza'
alias ll='eza --git -T'
- 安裝 bat,提供更好看的 cat 指令
sudo apt install bat -y
alias bat='batcat'
- 安裝 tldr,提供簡單的指令說明
sudo apt install tldr -y
接著測試一下
tldr ls
- 安裝 fzf,提供 fuzzy search 以及歷史紀錄搜尋功能
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
設定好之後可以按下 Ctrl + R
來搜尋歷史紀錄,或是 Ctrl + T
來搜尋檔案,還有許多進階功能待補充 ...
可以預覽檔案內容
fzf --preview 'cat {}'
結合 batcat
可以提供更好看的預覽
fzf --preview 'batcat --style=numbers --color=always {}'
- 如果想在 VSCode 中使用 zsh 和 fzf,可以在 VSCode 的設定中加入以下的設定
{
"terminal.integrated.defaultProfile.linux": "zsh"
}
接著去搜尋 keybindings.json
,然後加入以下的設定,這樣就可以使用 Ctrl + R
來搜尋歷史紀錄了
{
{
"key": "ctrl+r",
"command": "workbench.action.terminal.sendSequence",
"args": { "text": "\u0012" },
"when": "terminalFocus"
}
}
MacOS ZSH Installation
接著是在 MacOS 上安裝同樣的套件
- 安裝 Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- 安裝 zsh 以及 iterm2
brew install zsh
並設定為預設 shell
sudo sh -c 'echo $(which zsh) >> /etc/shells'
chsh -s $(which zsh)
- 安裝 Oh My Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
- 安裝 Powerlevel10k
brew install rpowerlevel10k
在 ~/.zshrc
中設定主題
ZSH_THEME=""
source $(brew --prefix)/share/powerlevel10k/powerlevel10k.zsh-theme
並重啟 terminal 依據提示進行設定
- 安裝 zsh-syntax-highlighting zsh-autosuggestions
brew install zsh-syntax-highlighting
brew install zsh-autosuggestions
source $(brew --prefix)/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh
plugins=(git)
- 安裝 eza
brew install eza
alias ls='eza'
alias ll='eza --git -T'
- 安裝 bat
brew install bat
- 安裝 tldr,由於這個已經不再維護了,所以我們可以使用 tlrc 來取代
brew install tlrc
tldr ls
- 安裝 fzf
brew install fzf
$(brew --prefix)/opt/fzf/install
fzf --preview 'batcat --style=numbers --color=always {}'
用法跟 WSL 一樣
Windows Terminal Installation
可以在 這篇文章 找到詳細的安裝步驟,其中我覺得比較好用的是 history 功能,可以顯示 10 筆歷史紀錄。
Basic Shell Commands
接下來會說明一些常用的 Shell 指令
檔案 / 目錄操作
ls
:列出當前目錄下的檔案與資料夾cd
:切換目錄pwd
:顯示當前所在的目錄mkdir
:建立資料夾touch
:建立檔案rm
:刪除檔案rmdir
:刪除資料夾cp
:複製檔案mv
:移動檔案或重新命名檔案
檔案內容操作
cat
:顯示檔案內容less
:分頁顯示檔案內容head
:顯示檔案的前幾行tail
:顯示檔案的後幾行grep
:搜尋檔案中的字串,grep "keyword" filename
wc
:計算檔案的行數、字數與字元數sort
:排序檔案內容,sort filename
檔案權限操作
在 Linux 中,檔案的權限分為三種:擁有者、群組與其他人。每種權限又分為三種:讀取、寫入與執行,分別代表數字 4、2 與 1,因此 755
代表擁有者有讀取 (4+2+1),群組跟其他人有讀取 (4),執行 (1),而沒有寫入的權限。
可以透過 ls -l
來查看檔案的權限,會顯示成 -rwxr-xr--
的格式,第一個字母代表檔案類型,接下來的三個字母代表擁有者的權限,再來的三個字母代表群組的權限,最後三個字母代表其他人的權限。
chmod
:改變檔案的權限,chmod 755 filename
chown
:改變檔案的擁有者,chown user:group filename
chgrp
:改變檔案的群組 ,chgrp group filename
使用時加上 -R
參數可以遞迴操作
系統監控
top
:顯示系統的即時狀態ps
:顯示目前執行中的程序,ps aux
則是顯示所有使用者的程序kill
:終止程序,kill -9 PID
強制終止df
:顯示磁碟使用情況
網路操作
ping
:測試網路連線curl
:下載檔案或發送請求wget
:下載檔案ssh
:遠端連線到另一台主機ftp
:檔案傳輸協定ip
:顯示本機的 IP 位址
以下的指令需要安裝額外的套件
nslookup
:查詢 DNS,sudo apt install dnsutils -y
traceroute
:追蹤路由,sudo apt install traceroute -y
netstat
:顯示網路連線狀態,sudo apt install net-tools -y
ifconfig
:顯示網路介面資訊,sudo apt install net-tools -y
其他常用指令
awk
:文字處理工具,可以用來處理檔案中的資料
awk '{print $1}' file.txt # 顯示檔案的第一欄
awk -F ':' '{print $1, $3}' /etc/passwd # 以冒號為分隔符號,顯示檔案的第一欄與第三欄
awk '{if ($3 > 1000) print $1}' /etc/passwd # 顯示第三欄大於 1000 的行
awk 'BEGIN {cnt=0} {cnt += 1} END {print cnt}' /etc/passwd # 計算檔案的行數
sed
:文字處理工具,可以用來處理檔案中的資料
sed 's/old/new/' file.txt # 把每一行的 old 替換成 new
sed 's/old/new/g' file.txt # 把檔案中的 old 替換成 new
Shell Script
#!/bin/bash
# 宣告這是一個 bash 腳本
# 變數宣告
name="Wei"
age=18
echo "Hello, $name! You are $age years old." # 輸出變數
# 條件判斷
if [ $age -lt 18 ]; then
echo "You are a minor."
elif [ $age -lt 65 ]; then
echo "You are an adult."
else
echo "You are a senior citizen."
fi
# Switch Case
case $age in
0)
echo "You are a baby."
;;
1|2|3)
echo "You are a toddler."
;;
4|5|6)
echo "You are a child."
;;
*)
echo "You are an adult."
;;
esac
# 迴圈
for i in {1..5}; do
echo "Iteration $i"
done
while [ $age -lt 30 ]; do
echo "You are still young!"
age=$((age + 1)) # 數字運算
done
echo "You are now $age years old."
# 函式
function greet() {
local name=$1 # 取得參數
echo "Hello, $name!"
}
greet "Wei" # 呼叫函式
# 陣列
fruits=("apple" "banana" "cherry")
echo "The first fruit is ${fruits[0]}." # 輸出陣列的第一個元素
# 讀取檔案
while IFS= read -r line; do
echo "$line"
done < file.txt # 讀取檔案的每一行
# 輸出到檔案
echo "Hello, $name!" > output.txt # 輸出到檔案
# 特殊字元
echo "$0" # 腳本名稱
echo "$1" # 第一個參數
echo "$#" # 參數的數量
echo "$*" # 所有參數
echo "$$" # 腳本的 PID