跳至主要内容

Basic Shell Introduction

在開始學習程式開發的過程中,我們多半仰賴 GUI 來操作系統,例如拖拉檔案、點擊按鈕等。 然而,當我們進一步接觸像是 Linux 這樣的開發環境時,會發現 CLI 成為更有效率、彈性也更高的操作方式。

這篇文章會介紹了解常見的 Shell 指令與基本語法,並分享我如何安裝與設定 Shell 環境。

WSL ZSH Installation

首先示範如何在 WSL 中啟用 zsh,並且介紹一些常用的套件及設定。

  1. 安裝 zsh
sudo apt update && sudo apt install -y zsh

zsh --version
  1. 將 zsh 設定為預設 shell
chsh -s $(which zsh)
  1. 安裝 Oh My Zsh 框架來管理 zsh 的設定
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
  1. 改變主題,我使用 Powerlevel10k 主題,這需要額外安裝,設定完之後需要重新開啟 terminal 進行設定
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/themes/powerlevel10k
~/.zshrc
ZSH_THEME="powerlevel10k/powerlevel10k"
  1. 安裝 zsh-syntax-highlighting,用來高亮顯示指令語法
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
~/.zshrc
plugins=(git zsh-syntax-highlighting)
  1. 安裝 zsh-autosuggestions,提供指令自動建議
git clone https://github.com/zsh-users/zsh-autosuggestions \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
~/.zshrc
plugins=(git zsh-syntax-highlighting zsh-autosuggestions)
  1. 安裝 jsonpp,用來格式化 JSON 資料
plugins=(git zsh-syntax-highlighting zsh-autosuggestions jsontools)

可以用以下指令測試一下

curl https://coderwall.com/bobwilliams.json | pp_json
  1. 安裝 eza (exa),可以提供更好看的 ls 指令
sudo apt install eza -y

修改 ~/.zshrc 的 alias 設定,讓 ls 指令使用 eza

~/.zshrc
alias ls='eza'
alias ll='eza --git -T'
  1. 安裝 bat,提供更好看的 cat 指令
sudo apt install bat -y
~/.zshrc
alias bat='batcat'
  1. 安裝 tldr,提供簡單的指令說明
sudo apt install tldr -y

接著測試一下

tldr ls
  1. 安裝 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 {}'
  1. 如果想在 VSCode 中使用 zsh 和 fzf,可以在 VSCode 的設定中加入以下的設定
settings.json
{
"terminal.integrated.defaultProfile.linux": "zsh"
}

接著去搜尋 keybindings.json,然後加入以下的設定,這樣就可以使用 Ctrl + R 來搜尋歷史紀錄了

keybindings.json
{
{
"key": "ctrl+r",
"command": "workbench.action.terminal.sendSequence",
"args": { "text": "\u0012" },
"when": "terminalFocus"
}
}

MacOS ZSH Installation

接著是在 MacOS 上安裝同樣的套件

  1. 安裝 Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  1. 安裝 zsh 以及 iterm2
brew install zsh

並設定為預設 shell

sudo sh -c 'echo $(which zsh) >> /etc/shells'
chsh -s $(which zsh)
  1. 安裝 Oh My Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
  1. 安裝 Powerlevel10k
brew install rpowerlevel10k

~/.zshrc 中設定主題

~/.zshrc
ZSH_THEME=""
source $(brew --prefix)/share/powerlevel10k/powerlevel10k.zsh-theme

並重啟 terminal 依據提示進行設定

  1. 安裝 zsh-syntax-highlighting zsh-autosuggestions
brew install zsh-syntax-highlighting
brew install zsh-autosuggestions
~/.zshrc
source $(brew --prefix)/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh
plugins=(git)
  1. 安裝 eza
brew install eza
~/.zshrc
alias ls='eza'
alias ll='eza --git -T'
  1. 安裝 bat
brew install bat
  1. 安裝 tldr,由於這個已經不再維護了,所以我們可以使用 tlrc 來取代
brew install tlrc
tldr ls
  1. 安裝 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