Linux零基礎Shell教學全集(可用于日常查詢語句,目錄清晰,內容詳細)(自學尚硅谷B站shell課程后的萬字學習筆記,附課程鏈接)

此文章為學習了 尚硅谷B站課程?后的學習筆記

【尚硅谷】Shell腳本從入門到實戰_嗶哩嗶哩_bilibilihttps://www.bilibili.com/video/BV1hW41167NW/?spm_id_from=333.337.search-card.all.click&vd_source=68e0bbe20c8b1102b59ced40f67db628注意:需要先學Linux基礎命令后,學習shell命令

Linux常用基礎命令-CSDN博客https://blog.csdn.net/2302_78022640/article/details/149337415?spm=1011.2415.3001.5331

零基礎 Shell 教學全集:全面入門、精講實例、實戰腳本


第 1 章:什么是Shell

Shell 是一個命令行解釋器

Shell 是?用戶與 Linux 內核交互的核心接口,兼具?命令解釋器?和?腳本編程語言?的雙重身份,也可理解為包裹內核的 “保護殼”(隔離用戶直接操作內核,保障系統安全)。以下從核心邏輯、功能特性、常見版本展開解析:

核心作用:連接用戶與內核

  • 命令中轉:接收用戶輸入的指令(如?ls?查看文件、cd?切換目錄),將其轉換為內核能理解的格式,驅動內核執行操作,再把結果反饋給用戶。
  • 安全隔離:用戶無法直接訪問內核,必須通過 Shell 交互,避免誤操作破壞系統核心,就像 “門衛” 守護內核。

1.1 常見 Shell 解析器

Linux 系統提供了多種 Shell 解析器,我們可以通過以下命令查看系統中可用的 Shell 解析器:

cat /etc/shells

輸出可能為:

/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh

這表示當前系統中安裝了這些 Shell 解析器,其中?bash?是最常用的默認的一種。

1.2 bash 和 sh 的關系

在很多 Linux 系統中,sh?實際上是?bash?的一個鏈接(符號鏈接),我們可以通過以下命令查看它們的關系:

(本文章第九章有說明grep的使用,正則表達式)

ll | grep bash

含義是:

  • ll:是 ls -l 的別名,列出當前目錄下的文件詳細信息(包括權限、所有者、大小、修改時間等)。

  • grep bash:從 ll 的輸出中篩選出包含 “bash” 的行。

輸出:

這里的?lrwxrwxrwx?表示?sh?是一個符號鏈接,箭頭?->?后面的?bash?表示它鏈接到?bash,這意味著執行?sh?命令實際上等同于執行?bash?命令。

1.3 查看當前默認 shell

要查看當前系統默認使用的 Shell 解析器,可以使用以下命令:

echo $SHELL

在 CentOS 系統中,輸出通常為:

/bin/bash

這表明 CentOS 默認的 Shell 解析器是?bash


第 2 章:Shell 腳本入門

2.1 腳本格式要求

編寫 Shell 腳本時,有一個固定的格式要求:腳本必須以?#!/bin/bash?開頭,這一行的作用是指定腳本使用?bash?解析器來執行。同時,為了便于識別,Shell 腳本通常使用?.sh?作為后綴名。

可以先建一個文件夾:

mkdir codes
cd codes

如圖例:

2.2 Hello World 示例

下面我們來編寫第一個 Shell 腳本,實現輸出 "helloworld" 的功能。

步驟:

  1. 創建腳本文件:
    touch helloworld.sh
    
  2. 編輯腳本內容:
    vim helloworld.sh
    
    (打開后按 “i” 開始編寫,寫完后按 “Esc” ,再輸入 “:wq” 出來)(下面這步不會的請先學linux基礎命令)
  3. 在打開的文件中輸入以下內容:
    #!/bin/bash
    echo "helloworld"
    

2.3 三種執行方式

Shell 腳本有多種執行方式,不同的方式有不同的特點和使用場景。

第一種:不需要執行權限(bash/sh + 路徑)

這種方式是通過?bash?或?sh?命令來執行腳本,不需要給腳本賦予可執行權限。可以使用相對路徑或絕對路徑指定腳本位置:

  • 相對路徑(在腳本所在目錄執行)(cd 轉目錄):
    sh ./helloworld.sh
    bash ./helloworld.sh
    
  • 絕對路徑(可以在任意目錄執行):
    sh /home/atguigu/shells/helloworld.sh
    bash /home/atguigu/shells/helloworld.sh
    

這種方式的本質是?bash?或?sh?解析器幫我們執行腳本,所以腳本本身不需要可執行權限。

第二種:需要執行權限(直接執行)

這種方式是直接執行腳本文件,需要先給腳本賦予可執行權限:

(可以看到什么圖片中helloworld.sh 文件被加粗了)

  1. 賦予權限(此為linux基礎命令):
    chmod +x helloworld.sh
    
  2. 執行腳本:
    • 相對路徑(在腳本所在目錄執行):
      ./helloworld.sh
      
    • 絕對路徑(可以在任意目錄執行):
      /home/atguigu/shells/helloworld.sh
      

這種方式的本質是腳本自己執行,所以必須要有可執行權限。

第三種:使用?source?或?.(當前 shell 執行)

使用?source?命令或?.(點號)執行腳本,腳本會在當前 Shell 環境中執行,而不是創建一個新的子 Shell 環境。這會導致腳本中定義的變量在腳本執行后仍然有效。

例如,有一個?test.sh?腳本:

cat test.sh

內容如下:

#!/bin/bash
A=5
echo $A

分別用不同方式執行:

bash test.sh
sh test.sh
./test.sh
. test.sh  # 或 source test.sh
echo $A    # 只有 source 執行才能打印 5

前三種方式(bashsh、直接執行)都會創建子 Shell 來執行腳本,腳本執行結束后子 Shell 關閉,在子 Shell 中定義的變量不會影響父 Shell;而使用?source?或?.?執行腳本時,腳本在當前 Shell 中執行,變量會保留在當前 Shell 中。


第 3 章:變量

在 Shell 中,變量是存儲數據的容器,我們可以通過變量名來訪問存儲的數據。Shell 中的變量分為系統預定義變量、自定義變量和特殊變量。

3.1 系統變量示例

系統預定義變量是系統自帶的變量,用于存儲系統相關的信息。常見的系統變量有:

  • $HOME:當前用戶的家目錄
  • $PWD:當前工作目錄
  • $SHELL:當前默認的 Shell 解析器
  • $USER:當前登錄的用戶

可以通過?echo?命令查看這些變量的值:

echo $HOME
echo $PWD
echo $SHELL
echo $USER

使用?set?命令可以顯示當前 Shell 中的所有變量:

set

這些系統變量為我們獲取系統信息提供了方便。

3.2 自定義變量

除了系統預定義變量,我們還可以自己定義變量來存儲數據。

定義和使用變量

定義變量的基本格式是:變量名=變量值,注意等號前后不能有空格。使用變量時,在變量名前加?$?符號。

A=5
echo $A  # 輸出 5
重新賦值和撤銷變量

可以對已定義的變量重新賦值:

A=8
echo $A  # 輸出 8

使用?unset?命令可以撤銷變量:

unset A
echo $A  # 變量 A 已被撤銷,無輸出
只讀變量

使用?readonly?命令可以定義只讀變量,只讀變量不能被重新賦值,也不能被撤銷:

readonly B=2
echo $B  # 輸出 2
B=9  # 報錯:readonly variable
變量的類型

在 bash 中,變量默認都是字符串類型,即使看起來是數字,也不能直接進行數值運算:

C=1+2
echo $C  # 輸出:1+2,而不是 3

如果變量的值包含空格,需要使用雙引號或單引號將其括起來:

D=I love banzhang   # 錯誤,會被解析為多個命令
D="I love banzhang" # 正確
echo $D  # 輸出:I love banzhang
設置全局變量(供腳本調用)

默認情況下,自定義變量只在當前 Shell 中有效,在子 Shell 或腳本中無法訪問。如果要讓變量在子 Shell 或腳本中也能使用,需要使用?export?命令將其提升為全局變量:

export B

例如,我們在?helloworld.sh?腳本中添加輸出變量?B?的語句:

vim helloworld.sh

內容添加:

#!/bin/bash
echo "helloworld"
echo $B

運行腳本:

./helloworld.sh

如果沒有執行?export B?命令,腳本中不會輸出變量?B?的值;執行?export B?后重新執行腳本,就可以輸出?B?的值了。


3.3 特殊變量

特殊變量是 Shell 中具有特殊含義的變量,用于處理命令行參數、命令執行狀態等。

$n$#
  • $n:用于獲取命令行參數,$0?代表腳本名稱,$1?到?$9?代表第 1 到第 9 個參數,10 及以上的參數需要用?${10}?表示。
  • $#:用于獲取命令行參數的個數。

示例:

vim parameter.sh

內容:

#!/bin/bash
echo '==========$n=========='
echo $0  # 腳本名稱
echo $1  # 第一個參數
echo $2  # 第二個參數
echo '==========$#=========='
echo $#  # 參數個數

執行:

chmod 777 parameter.sh
./parameter.sh cls xz

輸出:

==========$n==========
./parameter.sh
cls
xz
==========$#==========
2

可以看到,$0?輸出了腳本名稱?./parameter.sh$1?輸出了第一個參數?cls$2?輸出了第二個參數?xz$#?輸出了參數的個數?2

$*?和?$@

$*?和?$@?都用于獲取所有命令行參數,但它們在處理參數的方式上有所不同:

  • $*:將所有參數視為一個整體。
  • $@:將每個參數視為獨立的個體。

示例:

vim parameter.sh

追加內容:

echo '==========$*=========='
echo $*
echo '==========$@=========='
echo $@

執行:

./parameter.sh a b c d e f g

輸出:

==========$*==========
a b c d e f g
==========$@==========
a b c d e f g

從表面上看,$*?和?$@?的輸出結果相同,但在循環中它們的表現不同。我們可以通過一個循環示例來觀察:

vim for4.sh
#!/bin/bash
echo '=============$*============='
for i in "$*"
doecho "ban zhang love $i"
doneecho '=============$@============='
for j in "$@"
doecho "ban zhang love $j"
done

執行:

chmod 777 for4.sh
./for4.sh cls mly wls

輸出:

=============$*=============
ban zhang love cls mly wls
=============$@=============
ban zhang love cls
ban zhang love mly
ban zhang love wls

可以看到,"$*"?被當作一個整體進行循環,只循環一次;而?"$@"?被當作多個獨立的參數,循環次數與參數個數相同。

$?

$??用于獲取上一個命令執行的返回狀態。如果返回值為 0,表示上一個命令執行成功;如果返回值為非 0,則表示上一個命令執行失敗。

例如,判斷?helloworld.sh?腳本是否正確執行:

./helloworld.sh
echo $?  # 輸出 0,說明執行成功

這在腳本中用于判斷命令是否執行成功非常有用。


第 4 章:運算符

在 Shell 中進行數值運算時,不能直接使用?+-*/?等運算符,需要使用特定的格式。

Shell 中常用的數值運算格式有兩種:

  • $((運算式))
  • $[運算式]

例如,計算?(2+3)*4?的值:

S=$[(2+3)*4]
echo $S  # 輸出 20

或者:

S=$(( (2+3)*4 ))
echo $S  # 輸出 20

這兩種格式都可以實現數值運算,使用起來比較方便。


第 5 章:條件判斷

在 Shell 中,條件判斷用于根據不同的條件執行不同的操作。

5.1 條件判斷的基本語法

Shell 中條件判斷有兩種基本語法:

  1. test condition
  2. [ condition ]??condition?前后要有空格)

如果條件成立,返回 0(表示真);條件不成立,返回非 0(表示假)。需要注意的是,條件非空即為真,[ atguigu ]?返回真,[ ]?返回假。

5.2 常用判斷條件及示例

數值比較

用于兩個整數之間的比較,常用的運算符有:

  • -eq:等于
  • -ne:不等于
  • -lt:小于
  • -gt:大于
  • -le:小于等于
  • -ge:大于等于

示例:判斷 23 是否大于等于 22

[ 23 -ge 22 ]
echo $?  # 輸出 0,表示條件成立
文件權限判斷

用于判斷文件是否具有某種權限,常用的運算符有:

  • -r:有讀權限
  • -w:有寫權限
  • -x:有執行權限

示例:判斷?helloworld.sh?是否具有寫權限

[ -w helloworld.sh ]
echo $?  # 輸出 0,表示有寫權限
文件存在性判斷

用于判斷文件或目錄是否存在,常用的運算符有:

  • -e:文件或目錄存在
  • -f:文件存在且是普通文件
  • -d:文件存在且是目錄

示例:判斷?/home/atguigu/cls.txt?是否存在

[ -e /home/atguigu/cls.txt ]
echo $?  # 如果文件不存在,輸出非 0
多條件判斷

可以使用?&&?和?||?進行多條件判斷:

  • &&:表示前一條命令執行成功時,才執行后一條命令
  • ||:表示前一條命令執行失敗時,才執行后一條命令

示例:

[ atguigu ] && echo OK || echo notOK  # 輸出 OK,因為條件非空為真
[ ] && echo OK || echo notOK          # 輸出 notOK,因為條件為空為假

這在腳本中用于復雜的條件判斷非常有用。


第 6 章:流程控制

流程控制用于根據不同的條件執行不同的代碼塊,或重復執行某個代碼塊。Shell 中的流程控制包括 if 判斷、case 語句、for 循環和 while 循環。

6.1 if 判斷

if 判斷用于根據條件執行不同的代碼塊,分為單分支和多分支兩種形式。

語法格式
  • 單分支:

    if [ 條件判斷式 ]; then程序
    fi
    
    ?

    或者

    if [ 條件判斷式 ]
    then程序
    fi
    
  • 多分支:

    if [ 條件判斷式 ]; then程序
    elif [ 條件判斷式 ]; then程序
    else程序
    fi
    

注意事項:

  • [ 條件判斷式 ]?中,中括號和條件判斷式之間必須有空格
  • if?后要有空格
示例

例如,輸入數字 1 輸出特定內容,輸入數字 2 輸出另一內容:

vim if.sh

($1為第一個帶入的參數)

#!/bin/bash
if [ $1 -eq 1 ]; thenecho "banzhang zhen shuai"
elif [ $1 -eq 2 ]; thenecho "cls zhen mei"
fi

chmod 777 if.sh
./if.sh 1  # 輸出 banzhang zhen shuai


6.2 case 語句

case 語句用于多分支判斷,根據變量的不同取值執行不同的代碼塊。

語法格式
case $變量名 in
"值1")如果變量的值等于值1,則執行此程序;;
"值2")如果變量的值等于值2,則執行此程序;;
...省略其他分支...
*)如果變量的值都不是以上的值,則執行此程序;;
esac

注意事項:

  • case 行尾必須為單詞 “in”
  • 每一個模式匹配必須以右括號 “)” 結束
  • 雙分號 “;;” 表示命令序列結束,相當于 Java 中的 break
  • 最后的 “*)” 表示默認模式,相當于 Java 中的 default
示例

例如,輸入數字 1 輸出 "banzhang",輸入數字 2 輸出 "cls",輸入其他數字輸出 "renyao":

vim case.sh

#!/bin/bash
case $1 in
"1")echo "banzhang";;
"2")echo "cls";;
*)echo "renyao";;
esac

chmod 777 case.sh
./case.sh 1  # 輸出 banzhang


6.3 for 循環

for 循環用于重復執行某個代碼塊,有兩種語法格式。

C 語言風格

語法格式:

for ((初始值; 循環控制條件; 變量變化)); do程序
done

示例:計算 1 到 100 的和

vim for1.sh

#!/bin/bash
sum=0
for((i=0;i<=100;i++))
dosum=$[$sum+$i]
done
echo $sum  # 輸出 5050

chmod 777 for1.sh
./for1.sh
列表模式

語法格式:

for 變量 in 值1 值2 ...; do程序
done

示例:遍歷輸出列表中的元素

vim for2.sh

#!/bin/bash
for i in cls mly wls
doecho "ban zhang love $i"
done

chmod 777 for2.sh
./for2.sh

輸出:

ban zhang love cls
ban zhang love mly
ban zhang love wls
對比 $* 和 $@

前面我們已經介紹了?$*?和?$@?的區別,這里通過循環進一步展示:

vim for3.sh

#!/bin/bash
echo '=============$*============='
for i in $*
doecho "ban zhang love $i"
doneecho '=============$@============='
for j in $@
doecho "ban zhang love $j"
done

執行:

chmod 777 for3.sh
./for3.sh cls mly wls

當不使用雙引號時,$*?和?$@?的輸出完全一致。

再測試雙引號版本

vim for4.sh

#!/bin/bash
echo '=============$*============='
for i in "$*"
doecho "ban zhang love $i"
doneecho '=============$@============='
for j in "$@"
doecho "ban zhang love $j"
done

執行:

chmod 777 for4.sh
./for4.sh cls mly wls

輸出:

=============$*=============
ban zhang love cls mly wls
=============$@=============
ban zhang love cls
ban zhang love mly
ban zhang love wls

可以更清楚地看到?$*?和?$@?的區別:"$*"?將所有參數視為一個整體,"$@"?將每個參數視為獨立個體。


6.4 while 循環

while 循環用于在條件成立時重復執行某個代碼塊。

語法格式:

while [ 條件判斷式 ]; do程序
done

示例:計算 1 到 100 的和

vim while.sh

#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]
dosum=$[$sum+$i]i=$[$i+1]
done
echo $sum  # 輸出 5050

chmod 777 while.sh
./while.sh


第 7 章:輸入內容到控制臺(read 讀取)

read?命令用于從控制臺讀取用戶輸入,并將輸入的值賦給變量。

7.1 read 命令基本語法

read -t 秒數 -p "提示信息" 變量名

選項說明:

  • -p:指定讀取輸入時的提示信息
  • -t:指定等待輸入的時間(單位:秒),如果超過指定時間沒有輸入,read?命令會退出
  • 默認情況下,read?命令會無限等待用戶輸入

示例:等待 7 秒輸入姓名

文件:read.sh
  1. 創建并編輯腳本:

    touch read.sh
    vim read.sh
    
  2. 輸入以下內容:

    #!/bin/bash
    read -t 7 -p "Enter your name in 7 seconds :" NN
    echo $NN
    
執行:
chmod +x read.sh
./read.sh

輸出示例:

Enter your name in 7 seconds : atguigu  # 在 7 秒內輸入姓名
atguigu  # 輸出輸入的姓名

(自己輸入啊,記得自己輸進去啊,別干等著)

如果在 7 秒內沒有輸入,腳本會繼續執行,echo $NN?不會輸出任何內容。


第 8 章:函數

函數是一段可以重復調用的代碼塊,用于實現特定的功能。Shell 中的函數分為系統函數和自定義函數。


8.1 系統函數

系統函數是系統自帶的函數,可以直接使用。

8.1.1?basename:提取文件名

basename?命令用于從路徑中提取文件名,語法格式:

basename [string / pathname] [suffix]
  • suffix?為后綴,如果指定了?suffixbasename?會將文件名中的?suffix?去掉。

示例:

basename /home/atguigu/banzhang.txt  # 輸出 banzhang.txt
basename /home/atguigu/banzhang.txt .txt  # 輸出 banzhang

basename?可以理解為取路徑里的文件名稱。


8.1.2?dirname:提取目錄路徑

dirname?命令用于從路徑中提取目錄部分,語法格式:

dirname 文件絕對路徑

示例:

dirname /home/atguigu/banzhang.txt  # 輸出 /home/atguigu

dirname?可以理解為取文件路徑的絕對路徑名稱。


8.2 自定義函數

除了系統函數,我們還可以自己定義函數來實現特定的功能。

語法格式
function 函數名() {語句[ return 整數 ]
}

注意事項:

  • Shell 函數必須先定義再調用,因為 Shell 腳本是逐行執行的,不會像其他語言一樣先編譯
  • 函數的返回值只能通過?$??系統變量獲取,可以使用?return?語句指定返回值,如果不使用?return?語句,函數會以最后一條命令的執行結果作為返回值,返回值的范圍是 0 到 255


示例:兩個數求和
  1. 創建并編輯腳本:

    touch fun.sh
    vim fun.sh
    
  2. 輸入以下內容:

    #!/bin/bashfunction sum() {s=0s=$[$1 + $2]echo "$s"
    }read -p "Please input the number1: " n1
    read -p "Please input the number2: " n2
    sum $n1 $n2
    
  3. 執行腳本:

    chmod +x fun.sh
    ./fun.sh
    
  4. 輸出示例:

    Please input the number1: 2
    Please input the number2: 5
    7
    


第 9 章:正則表達式入門

正則表達式是一種用于描述字符串模式的工具,它可以用來匹配、檢索和替換符合特定模式的字符串。在 Linux 中,grepsedawk?等文本處理工具都支持正則表達式。

9.1 常規匹配

一串不包含特殊字符的正則表達式會匹配它自己。例如,要在?/etc/passwd?文件中查找包含?atguigu?的行,可以使用:

cat /etc/passwd | grep atguigu

這個命令會匹配所有包含?atguigu?字符串的行。

9.2 常用特殊字符

1)^:行首匹配

^?用于匹配一行的開頭。例如,要在?/etc/passwd?文件中查找以?a?開頭的行:

cat /etc/passwd | grep ^a

這個命令會匹配所有以?a?開頭的行。

2)$:行尾匹配

$?用于匹配一行的結尾。例如,要在?/etc/passwd?文件中查找以?t?結尾的行

cat /etc/passwd | grep t$

這個命令會匹配所有以?t?結尾的行🔷1-297🔷。

思考:^$?匹配什么?
^$?匹配空行,因為?^?表示行首,$?表示行尾,行首和行尾之間沒有任何字符,就是空行。

3).:匹配任意一個字符

.?用于匹配任意一個字符(除了換行符)。例如,要在?/etc/passwd?文件中查找包含?r?開頭、t?結尾,中間有兩個任意字符的行:

cat /etc/passwd | grep r..t

這個命令會匹配包含?rootrabt?等形式的行。

4)*:上一個字符重復 0 次或多次

*?不能單獨使用,它需要和上一個字符連用,表示匹配上一個字符 0 次或多次。例如,要在?/etc/passwd?文件中查找包含?ro*t?的行:

cat /etc/passwd | grep ro*t

這個命令會匹配包含?rtrotrootrooooot?等形式的行。

思考:.*?匹配什么?
.*?表示匹配任意長度的任意字符(除了換行符),因為?.?匹配任意一個字符,*?表示上一個字符(即?.)重復 0 次或多次。

5)[]:字符集合

[]?表示匹配某個范圍內的一個字符。例如:

  • [6,8]:匹配 6 或者 8
  • [0-9]:匹配一個 0 到 9 的數字
  • [0-9]*:匹配任意長度的數字字符串
  • [a-z]:匹配一個 a 到 z 之間的小寫字母
  • [a-z]*:匹配任意長度的小寫字母字符串
  • [a-c, e-f]:匹配 a 到 c 或者 e 到 f 之間的任意字符

示例:

cat /etc/passwd | grep r[a,b,c]*t

這個命令會匹配包含?rtratrbtrabt?等形式的行。

6)\:轉義字符

\?用于轉義特殊字符,使其失去特殊含義,僅表示字符本身。由于很多特殊字符在 Shell 中有特定的含義,當我們想匹配這些特殊字符本身時,需要使用?\?進行轉義。例如,要匹配包含?a$b?的行:

cat /etc/passwd | grep 'a\$b'

注意需要使用單引號將正則表達式引起來,防止?$?被 Shell 解釋為變量引用。


第 10 章:文本處理工具

文本處理工具用于對文本文件進行切割、分析、提取等操作,在 Shell 腳本中經常用到。


10.1 cut 命令

cut?命令的作用是從文件的每一行中切割出指定的字節、字符或字段,并將其輸出。

1)基本語法:
cut [選項] 文件名

cut?命令的默認分隔符是制表符(\t)。

2)選項說明:
選項功能
-f用于指定要提取的列號,例如?-f 1?表示提取第 1 列
-d用于指定分隔符,默認是制表符,例如?-d " "?表示使用空格作為分隔符
-c按字符進行切割,后面跟數字表示取第幾個字符,例如?-c 1?表示取第 1 個字符

示例 1:準備數據

創建?cut.txt?文件并輸入以下內容:

touch cut.txt
vim cut.txt

內容:

dong shen
guan zhen
wo wo
lai lai
le le
示例 2:提取第一列

使用空格作為分隔符,提取第 1 列:

cut -d " " -f 1 cut.txt

輸出:

dong
guan
wo
lai
le
示例 3:提取第 2、3 列

使用空格作為分隔符,提取第 2 列和第 3 列:

cut -d " " -f 2,3 cut.txt

輸出:

shen
zhen
wo
lai
le
示例 4:查找 guan 并切出

先使用?grep?命令查找包含?guan?的行,再使用?cut?命令提取第 1 列:

cat cut.txt | grep guan | cut -d " " -f 1

輸出:

guan
示例 5:PATH 從第 3 個目錄起截取

PATH?環境變量存儲了系統的命令搜索路徑,各路徑之間用冒號(:)分隔。要從第 3 個路徑開始截取:

echo $PATH | cut -d ":" -f 3-

-f 3-?表示從第 3 列開始提取,直到最后一列。

示例 6:提取 IP 地址

可以結合?ifconfiggrep?和?cut?命令提取 IP 地址:

ifconfig ens33 | grep netmask | cut -d " " -f 10

這個命令的作用是:先通過?ifconfig ens33?獲取網卡?ens33?的信息,然后使用?grep netmask?過濾出包含?netmask?的行(通常這一行包含 IP 地址),最后使用?cut?命令以空格為分隔符提取第 10 列,即 IP 地址。


10.2 awk 命令

awk?是一個強大的文本分析工具,它將文件逐行讀入,以空格為默認分隔符將每行切割成多個字段,然后對這些字段進行分析處理。

1)基本語法:
awk -F 分隔符 '/模式/{動作}' 文件
  • 模式(pattern):表示?awk?要在數據中查找的內容
  • 動作(action):表示當找到匹配的模式時要執行的命令
2)選項說明:
選項功能
-F指定輸入文件的分隔符
-v賦值一個用戶定義變量

示例 1:準備 passwd

將?/etc/passwd?文件復制到當前目錄,用于測試:

sudo cp /etc/passwd ./

passwd?文件中每一行的格式為:用戶名:密碼(加密): 用戶 ID: 組 ID: 注釋:用戶家目錄:Shell 解析器。

示例 2:匹配 root 并輸出第 7 列

使用?:?作為分隔符,查找以?root?開頭的行,并輸出第 7 列(Shell 解析器):

awk -F : '/^root/{print $7}' passwd

輸出:

/bin/bash
示例 3:輸出第 1 和第 7 列(用逗號分隔)

使用?:?作為分隔符,查找以?root?開頭的行,并輸出第 1 列(用戶名)和第 7 列(Shell 解析器),中間用逗號分隔:

awk -F : '/^root/{print $1","$7}' passwd

輸出:

root,/bin/bash
示例 4:添加列名與尾行

使用?BEGIN?和?END?關鍵字可以在處理文件內容之前和之后執行指定的動作:

  • BEGIN:在讀取任何數據行之前執行
  • END:在處理完所有數據行之后執行

示例:給?passwd?文件的第 1 列和第 7 列添加列名,并在最后添加一行自定義內容:

awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "dahaige,/bin/zuishuai"}' passwd

輸出中,BEGIN?塊輸出的內容會在文件內容之前顯示,END?塊輸出的內容會在文件內容之后顯示。

示例 5:將 UID +1 輸出

使用?-v?選項定義變量?i=1,然后將?passwd?文件中第 3 列(用戶 ID)的值加 1 并輸出:

awk -v i=1 -F : '{print $3+i}' passwd
示例 6:使用內置變量

awk?有一些內置變量,用于獲取文件相關的信息:

變量說明
FILENAME當前處理的文件名
NR已讀取的記錄數(行號)
NF當前記錄的字段個數(切割后列的個數)

示例:統計?passwd?文件的文件名、每行的行號和每行的列數:

awk -F : '{print "filename:" FILENAME ",linenum:" NR ",col:" NF}' passwd
示例 7:查找空行行號

查找?ifconfig?命令輸出結果中的空行,并打印空行的行號:

ifconfig | awk '/^$/{print NR}'

/^$/?是一個正則表達式,表示匹配空行,NR?變量表示當前行的行號。

示例 8:提取 IP 地址

結合?ifconfig?命令和?awk?提取 IP 地址:

ifconfig ens33 | awk '/netmask/ {print $2}'

這個命令的作用是:先獲取網卡?ens33?的信息,然后過濾出包含?netmask?的行,最后輸出該行的第 2 個字段,即 IP 地址。


第 11 章:綜合應用案例

綜合應用案例將前面所學的知識結合起來,實現實際的功能。


11.1 歸檔腳本

該腳本的功能是每天對指定的目錄進行歸檔備份,將目錄下的所有文件按天歸檔保存,并將歸檔文件放在?/root/archive?目錄下,歸檔文件的名稱格式為?archive_目錄名_日期.tar.gz

使用?tar?命令進行歸檔,-c?選項表示歸檔,-z?選項表示同時進行壓縮,得到的文件后綴名為?.tar.gz

腳本內容如下:

#!/bin/bash# 首先判斷輸入參數個數是否為 1
if [ $# -ne 1 ]
thenecho "參數個數錯誤!應該輸入一個參數,作為歸檔目錄名"exit
fi# 從參數中獲取目錄名稱
if [ -d $1 ]
thenecho
elseechoecho "目錄不存在!"echoexit
fiDIR_NAME=$(basename $1)
DIR_PATH=$(cd $(dirname $1); pwd)# 獲取當前日期
DATE=$(date +%y%m%d)# 定義生成的歸檔文件名稱
FILE=archive_${DIR_NAME}_$DATE.tar.gz# 定義歸檔文件的保存路徑
DEST=/root/archive/$FILE# 開始歸檔目錄文件
echo "開始歸檔..."
echotar -czf $DEST $DIR_PATH/$DIR_NAMEif [ $? -eq 0 ]
thenechoecho "歸檔成功!"echo "歸檔文件為:$DEST"echo
elseecho "歸檔出現問題!"echo
fiexit

腳本說明:

  1. 首先判斷輸入參數的個數是否為 1,如果不是,提示錯誤并退出
  2. 判斷輸入的參數是否是一個存在的目錄,如果不是,提示錯誤并退出
  3. 使用?basename?命令獲取目錄的名稱,使用?cd?和?pwd?命令獲取目錄的絕對路徑
  4. 使用?date?命令獲取當前日期,格式為?yyyymmdd
  5. 定義歸檔文件的名稱和保存路徑
  6. 使用?tar?命令進行歸檔壓縮
  7. 根據?tar?命令的執行結果(通過?$??判斷),提示歸檔成功或失敗


11.2 向用戶發送消息

該腳本的功能是向某個用戶快速發送消息,需要檢測用戶是否登錄在系統中、是否打開了消息功能,以及當前發送的消息是否為空。

利用 Linux 自帶的?mesg?和?write?工具來發送消息。

腳本內容如下:

#!/bin/bash# 檢查用戶是否登錄
login_user=$(who | grep -i -m 1 $1 | awk '{print $1}')
if [ -z $login_user ]
thenecho "$1 不在線!"echo "腳本退出.."exit
fi# 檢查用戶是否打開消息功能
is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
if [ $is_allowed != "+" ]
thenecho "$1 沒有開啟消息功能"echo "腳本退出.."exit
fi# 檢查消息是否為空
if [ -z $2 ]
thenecho "沒有消息發出"echo "腳本退出.."exit
fi# 提取消息內容和用戶終端
whole_msg=$(echo $* | cut -d " " -f 2-)
user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')# 發送消息
echo $whole_msg | write $login_user $user_terminalif [ $? != 0 ]
thenecho "發送失敗!"
elseecho "發送成功!"
fiexit

腳本說明:

  1. 使用?who?命令結合?grep?和?awk?檢查指定的用戶是否登錄,如果用戶不在線,提示錯誤并退出
  2. 使用?who -T?命令檢查用戶是否打開了消息功能(+?表示打開,-?表示關閉),如果沒有打開,提示錯誤并退出
  3. 檢查消息內容是否為空,如果為空,提示錯誤并退出
  4. 提取消息內容(去掉第一個參數,即用戶名)和用戶登錄的終端
  5. 使用?write?命令向用戶發送消息
  6. 根據?write?命令的執行結果,提示發送成功或失敗


? 總結與建議

通過本文的學習,你已經掌握了 Shell 的基本語法和常用工具的使用,包括:

分類技能點
腳本基礎shebang、執行方式、權限
變量系統變量、自定義、只讀
控制結構if、case、for、while
輸入輸出read、echo
運算與判斷算術、文件、邏輯
正則表達式^ $ . * [] \
文本處理cut、awk
函數自定義函數與系統函數
實戰案例歸檔、消息發送

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91178.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91178.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91178.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GitLab 中的分支和標簽的定義及操作

&#xff08;一&#xff09;GitLab 中的分支和標簽的定義及操作 1. 分支&#xff08;Branch&#xff09; 定義&#xff1a; 分支是代碼倉庫中的獨立開發路徑&#xff0c;允許你在不影響主線&#xff08;通常是 main 或 master 分支&#xff09;的情況下&#xff0c;進行實驗、開…

第2章 cmd命令基礎:常用基礎命令(3)

Hi~ 我是李小咖&#xff0c;主要從事網絡安全技術開發和研究。 本文取自《李小咖網安技術庫》&#xff0c;歡迎一起交流學習&#x1fae1;&#xff1a;https://imbyter.com 本節介紹的命令有顯示系統信息&#xff08;systeminfo&#xff09;、啟動指定程序&#xff08;start&am…

RabbitMQ 發送方確認的兩大工具 (With Spring Boot)

核心概念解析 發布者確認機制的核心思想是&#xff1a;將消息投遞的可靠性從“盡力而為”提升為“契約保證”。生產者不再是“發后不理”&#xff0c;而是與 Broker 建立一個雙向的溝通渠道。 在 Spring AMQP 的封裝下&#xff0c;這個機制主要由兩個回調接口實現&#xff1a; …

KONG API Gateway中的核心概念

在使用Kong API Gateway&#xff08;API網關&#xff09;時&#xff0c;理解其核心概念是掌握其工作原理的基礎。這些概念既體現了Kong的設計哲學&#xff0c;也決定了它如何適配復雜的API管理場景&#xff08;如微服務、多團隊協作等&#xff09;。本文將系統梳理Kong的核心概…

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘jupyterlab’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘jupyterlab’問題 摘要 在開發過程中&#xff0c;我們經常會遇到各種模塊安裝的問題&#xff0c;尤其是在使用PyCharm時&#xff0c;經常會遇到pip install時的…

3 運算符與表達式

運算符&#xff1a;對字面量或者變量進行操作的符號 表達式&#xff1a;用運算符把字面量或者變量連接起來符合java語法的式子就可以稱作表達式不同運算符連接的表達式體現的是不同類型的表達式int a 10; int b 20; int c a b;&#xff1a;運算符&#xff0c;并且是算術運算…

MySQL的單行函數:

目錄 函數的理解&#xff1a; MySQL的內置函數及分類&#xff1a; 單行函數&#xff1a; 數值函數&#xff1a; 基本函數&#xff1a; 角度與弧度互換函數&#xff1a; 三角函數&#xff1a; 指數與對數&#xff1a; 進制轉換&#xff1a; 字符串函數&#xff1a; 日…

設計模式(二十一)行為型:狀態模式詳解

設計模式&#xff08;二十一&#xff09;行為型&#xff1a;狀態模式詳解狀態模式&#xff08;State Pattern&#xff09;是 GoF 23 種設計模式中的行為型模式之一&#xff0c;其核心價值在于允許一個對象在其內部狀態改變時改變其行為&#xff0c;使得對象看起來像是修改了它的…

深入理解 Doris Compaction:提升查詢性能的幕后功臣

在 Doris 的數據存儲與查詢體系里&#xff0c;Compaction 是保障查詢效率、優化存儲結構的關鍵機制。如果你好奇 Doris 如何在高頻寫入后仍能高效響應查詢&#xff0c;或是想解決數據版本膨脹帶來的性能問題&#xff0c;這篇關于 Compaction 的深度解析值得收藏 &#x1f447; …

css 實現虛線效果的多種方式

使用邊框實現虛線 通過設置元素的邊框樣式來實現虛線效果。以下為示例代碼: .dashed {border: 1px dashed black; }使用 CSS 偽元素實現虛線 使用偽元素來模擬虛線的效果。以下為示例代碼: .dashed::before {content: "";display: block;height: 1px;border-bo…

深入剖析 RocketMQ 分布式事務:原理、流程與實踐

Apache RocketMQ 是一種分布式消息隊列系統&#xff0c;支持分布式事務消息&#xff0c;以確保在分布式系統中數據的一致性。它通過一種基于兩階段提交(2PC)的機制結合補償邏輯來實現分布式事務的最終一致性。以下是對 RocketMQ 分布式事務的詳細講解&#xff0c;包括其核心概念…

具身智能 自動駕駛相關崗位的技術棧與能力地圖

一、硬技能技術棧&#xff08;優先級排序&#xff09; 1. 核心領域技術&#xff08;★★★★★&#xff09;技術方向具體技能學習建議大模型實戰- VLA架構&#xff08;RT-2、PaLM-E&#xff09;開發/微調- 多模態對齊&#xff08;CLIP、Flamingo&#xff09;- 生成式策略&#…

實現了加載 正向 碰撞 雅可比 仿真

""" # 此示例從 URDF 文件中加載一個 UR10 機械臂的模型 # 隨后演示 Pinocchio 庫的基本功能,如正向運動學計算 # 雅可比矩陣計算、碰撞檢測以及動力學仿真 """ # 導入 meshcat 的幾何模塊,用于創建和管理可視化的幾何對象 import meshcat.geo…

【0基礎PS】PS工具詳解--畫筆工具

目錄前言一、畫筆工具的位置與快捷鍵?二、畫筆工具選項欄設置?三、畫筆工具的進階應用?四、常見問題及解決方法?總結前言 在 Photoshop 的眾多工具中&#xff0c;畫筆工具無疑是極具創造力和實用性的工具之一。無論是進行圖像繪制、照片修飾&#xff0c;還是特效制作&…

window10和ubuntu22.04雙系統之卸載ubuntu系統

window10和ubuntu22.04雙系統之卸載ubuntu系統&#xff09;1. 刪除Ubuntu系統占用的磁盤分區&#xff08;在Windows下操作&#xff09;2. 刪除ubuntu開機引導項1. winr出來終端提示框后輸入2. 然后會在命令行中顯示電腦的硬盤列表&#xff0c;輸入命令選擇安裝Windows的那個硬盤…

(C++)C++類和類的方法(基礎教程)(與Python類的區別)

前言&#xff1a; 本篇博客建議搭配&#xff1a;&#xff08;Python&#xff09;類和類的方法&#xff08;基礎教程介紹&#xff09;&#xff08;Python基礎教程&#xff09;-CSDN博客 一起學習使用&#xff1b; 源代碼&#xff1a; #include <iostream> #include &…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - 微博文章數據可視化分析-文章分類下拉框實現

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解微博文章數據可視化分析-文章分類下拉框實現…

Git命令保姆級教程

Git 入門網站 https://learngitbranching.js.org/?localezh_CN Git 命令 git init // 在本地目錄內部會生成.git文件夾 git initgit clone // 從git服務器拉取代碼 // 代碼下載完成后在當前文件夾中會有一個 shop 的目錄&#xff0c;通過 cd shop 命令進入目錄。 git clone ht…

Java Ai For循環 (day07)

循環結構 for&#xff1a;循環語句的作用&#xff1a;可以將一段代碼重復的執行很多次for 循環語句格式&#xff1a;執行流程&#xff1a; 初始化語句執行條件判斷語句&#xff0c;看結果是 true&#xff0c;還是 false false結束&#xff0c;true繼續執行循環體語句執行條件控…

Directory Opus 使用優化

自定義快捷鍵 Directory Opus 移動標簽到另一欄 設置快捷鍵&#xff1a;ctrl←/→ 設置步驟&#xff1a; 打開【設置】—>選擇【自定義工具欄和快捷鍵】 選擇【新建】—>【新建窗口快捷鍵】 輸入快捷鍵命令 Go TABMOVEother此時可以點擊運行進行測試&#xff0c;…