一、計算用戶ID總和
使用while read line和/etc/passwd,計算用戶id總和。
# 初始化用戶ID和總和變量
uid=0
sum=0
while read line; do
# 從 /etc/passwd 文件中提取用戶ID
uid=$(echo "$line" | cut -d':' -f3)
# 將用戶ID添加到總和中
sum=$((sum + uid))
done < /etc/passwd
# 輸出ID總和
echo "用戶ID總和為:$sum"
上面的腳本首先定義了兩個變量 uid 和 sum,分別用于存儲當前行的用戶ID和所有用戶ID的總和。然后使用 while 循環逐行讀取 /etc/passwd 文件的內容,每次循環提取當前行的第三個字段,也就是用戶ID,并將它加到總和變量中。最后輸出所有用戶ID的總和。
需要注意的是,腳本執行需要 root 權限才能讀取 /etc/passwd 文件。如果沒有權限,則需要使用其他方式獲取用戶列表。
二、數組/字符串處理/高級變量
總結索引數組和關聯數組,字符串處理,高級變量使用及示例。
索引數組和關聯數組
在Bash中,數組是一種數據結構,可以用來存儲一組值。Bash中支持兩種類型的數組:索引數組和關聯數組。
# 定義一個索引數組
my_array=("apple" "banana" "orange")
# 訪問數組中的元素
echo ${my_array[0]} # 輸出 "apple"
echo ${my_array[1]} # 輸出 "banana"
echo ${my_array[2]} # 輸出 "orange"
-
索引數組:索引數組是按照數字索引訪問元素的數組類型。在Bash中,索引從0開始。可以使用下標語法獲取數組元素的值。例如:
-
關聯數組:關聯數組是一種根據鍵名(字符串)訪問元素的數組類型。定義關聯數組時需要使用聲明 -A。可以使用鍵名訪問數組元素的值。例如:
# 定義一個關聯數組
declare -A my_array
my_array["紅"]="蘋果"
my_array["黃"]="雪梨"
my_array["橙"]="橘子"
# 訪問數組中的元素
echo ${my_array["紅"]} # 輸出 "蘋果"
echo ${my_array["黃"]} # 輸出 "雪梨"
echo ${my_array["橙"]} # 輸出 "橘子"
需要注意的是,Bash的版本需要在 4.0 及以上才支持關聯數組。
字符串處理
Bash中有很多內置的字符串處理工具和技巧,可以對字符串進行各種操作。以下是一些 Bash 中常用的字符串處理函數和示例:
-
${#string} 可以獲得字符串的長度:
my_string="hello, world"
echo ${#my_string} # 輸出 12
-
${stringlength} 可以截取子字符串,其中 start 是子字符串開始的位置, length 是子字符串的長度:
my_string="hello, world"
echo ${my_string5} # 輸出 "hello"
echo ${my_string5} # 輸出 "world"
-
${string#substring} 可以從字符串的開頭刪除指定的子字符串,其中 substring 是要刪除的子字符串:
my_string="hello, world"
echo ${my_string#hello, } # 輸出 "world"
-
${string%substring} 可以從字符串的末尾刪除指定的子字符串,其中 substring 是要刪除的子字符串:
my_string="hello, world"
echo ${my_string%world} # 輸出 "hello, "
-
${string/find/replace} 可以將字符串中的所有指定子字符串 find 替換為 replace:
my_string="hello, world"
echo ${my_string/world/there} # 輸出 "hello, there"
-
${string//find/replace} 可以將字符串中的所有指定子字符串 find 替換為 replace,并且不止替換一次:
my_string="hello, world"
echo ${my_string//l/L} # 輸出 "heLLo, worLd"
高級變量
在 Bash 中,更加高級的變量設置方式可以讓我們更加靈活地控制變量的使用。下面我將介紹一些常見的高級變量賦值方式:
-
${parameter:=word}:當變量 parameter 不存在時,將其賦值為 word。
echo "MY_VAR is ${MY_VAR:=default}"
# 輸出 MY_VAR is default
echo "MY_VAR is ${MY_VAR}"
# 輸出 MY_VAR is default
-
${parameter:+word}:當變量 parameter 存在時,將其賦值為 word。
MY_VAR="value"
echo "MY_VAR is ${MY_VAR:+default}"
# 輸出 MY_VAR is default
echo "MY_VAR is ${MY_VAR}"
# 輸出 MY_VAR is value
-
${parameter:?error message}:如果變量 parameter 不存在或者為空,則顯示錯誤信息 error message 并退出腳本的執行。
echo "MY_VAR is ${MY_VAR:?Variable not set}"
# 在 MY_VAR 為空或未定義時,輸出 Variable not set 并退出
Bash 中的變量間接引用是一種非常有用的技巧,它允許我們使用一個變量的值作為另一個變量的名稱來引用它。這個技巧可以用在很多場景中,比如說根據運行時參數來動態引用變量。
在 Bash 中,變量間接引用可以通過 ${!varname} 的語法來實現。其中 varname 為一個變量名,通過 $ 和 {} 來包圍表示這是一個變量名的表達式。${!varname} 表示按照 varname 變量中存儲的名稱引用另一個變量。
下面是一個例子:
var1="Hello"
var2="World"
varname="var1"
echo "${!varname}, ${var2}!" # 輸出 "Hello, World!"
在這個例子中,我們首先定義了兩個變量 var1 和 var2,然后將 varname 設為 var1,表示我們希望引用 var1 這個變量。在輸出中,我們使用 ${!varname} 引用了 var1 這個變量,從而得到了輸出 Hello, World!。
需要注意的是,即使 varname 存儲的變量名稱是不存在的,${!varname} 表達式依然會被展開,并且其結果為空字符串。因此,在使用變量間接引用時應該特別小心,避免因為引用了不存在的變量而產生不可預測的結果。
三、求隨機數大小
求10個隨機數的最大值與最小值。
declare -i min max
declare -a nums
for ((i=0;i<10;i++));do
nums[$i]=$RANDOM
[ $i -eq 0 ] && min=${nums[0]} && max=${nums[0]} && continue
[ ${nums[$i]} -gt $max ] && max=${nums[$i]} && continue
[ ${nums[$i]} -lt $min ] && min=${nums[$i]}
done
echo "All numbers are ${nums[*]}"
echo Max is $max
echo Min is $min
四、階乘算法
使用遞歸調用,完成階乘算法實現。
function factorial {
if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1
else
echo $[$1*(factorial $[$1-1])]
}
factorial $1
五、進程和線程
解析進程和線程的區別?
進程和線程都是計算機中實現并發的方式,但它們有不同的特點和作用。
進程是操作系統分配資源的基本單位,每個進程都擁有獨立的內存空間、代碼和數據,進程之間不能直接共享數據。每個進程都有自己的地址空間、堆棧、文件描述符等信息,并且進程之間通過進程間通信(IPC)的方式來進行數據傳輸。進程的創建、切換和銷毀會消耗一定的系統資源,因此進程通常是比較重量級的。
線程是進程中執行任務的最小單位,是進程內部的一個執行路徑。線程與進程共享同一份數據和代碼段,每個線程都有自己的堆棧和程序計數器,但是所有線程共享進程的虛擬地址空間和物理資源,線程之間可以直接訪問同一片內存區域,因此線程之間的通信和數據交換比進程之間更加輕便快捷。線程的創建、切換和銷毀所需的系統資源比進程要少得多,因此線程通常是比較輕量級的。
總的來說,進程和線程都是實現并發的方式,但是它們的作用和特點不同。進程是基本的資源分配單位,而線程則是程序執行的最小單位,線程可以更高效地實現并發操作和多任務處理。
六、進程結構
解析進程的結構。
進程是計算機中最基本的資源分配單位,它由操作系統負責創建、管理和調度,進程可以看做是一個程序的執行實例。
進程的結構主要包括以下幾個部分:
-
程序段(Code Segment):也稱為文本段,是存放程序指令的內存區域,通常是只讀的。程序段是進程運行期間不變的部分,它包含了所有可執行指令,程序段在進程創建時就已經確定好了。
-
數據段(Data Segment):數據段存儲的是程序中已經初始化的全局變量、靜態變量和常量等數據,數據段通常是可讀寫的。
-
堆棧段(Stack Segment):堆棧段存儲著程序執行過程中產生的臨時數據和函數調用的返回地址等信息,堆棧段是一個后進先出的數據結構,它的大小可以動態擴展,通常是可讀寫的。
-
堆區(Heap):堆區是程序執行期間動態申請和釋放內存所使用的區域,堆區是可讀寫的,其大小可以動態調整。
-
進程控制塊(Process Control Block,PCB):進程控制塊是系統管理進程的數據結構,它包括了進程的基本信息,如進程狀態、進程標識符、進程優先級、程序計數器、寄存器等,同時還記錄了進程的資源使用情況,如打開的文件、分配的內存等。
以上是進程的主要組成部分,不同操作系統或編程語言中可能會有所差異,但是它們的基本結構都包含了上述的內容。
七、進程的各種狀態
結合進程管理命令,說明進程各種狀態。
在進程管理中,常見的進程狀態有以下幾種:
-
運行態(Running):指該進程正在CPU上運行。
-
就緒態(Ready):指該進程已經準備好,只等待CPU分配時間片后就能運行。
-
阻塞態(Blocked):指該進程由于等待某些事件(例如輸入/輸出、信號等)而無法被執行。
-
創建態(New):表示該進程已被創建,但還沒有被操作系統調度運行。
-
終止態(Terminated):表示該進程已經運行完畢或者被強制終止。
在Linux系統中,可以使用ps命令查看進程狀態。其中,運行態的進程會被標記為“R”,就緒態的進程則會被標記為“S”,阻塞態的進程會被標記為“D”,終止態的進程會被標記為“Z”,而創建態的進程則不會在進程列表中出現。
在ps aux命令的輸出中,STAT表示進程狀態。在Linux系統中,進程可以有不同的狀態,常見的狀態包括:
-
R:進程正在運行;
-
S:進程處于休眠狀態,例如等待某個事件的發生,或者正在進行I/O操作;
-
D:進程不可中斷的休眠狀態,例如等待排隊在塊設備上的輸入/輸出;
-
Z:進程被終止,但是它的父進程還沒有來得及回收它的資源;
-
T:進程被暫停或者停止。
通常情況下,我們關注的進程狀態是R和S,因為它們代表的進程正在運行或者等待CPU以及其他資源。而D和Z狀態通常表示該進程出現了異常情況,需要進一步的檢查和處理。
八、IPC通信和RPC通信
說明IPC通信和RPC通信實現的方式。
IPC通信(Inter-Process Communication,進程間通信)和RPC通信(Remote Procedure Call,遠程過程調用)都是用于不同進程之間進行通信的方式。
IPC通信實現的方式較為多樣化,其中最常見的方式包括:
-
管道(Pipe):管道是一種半雙工的通信方式,通常用于父子進程之間的通信。管道只支持單向數據傳輸,它的基本思想是用一個緩沖區作為共享區域來實現父子進程之間的數據交換。
-
消息隊列(Message Queue):消息隊列是一種消息傳遞機制,通常用于同一主機內的進程間通信。消息隊列提供了一種異步的通信方式,發送方發送消息后即可立即返回,而接收方則可以在需要時從消息隊列中取出消息。
-
信號量(Semaphore):信號量是一種用于進程間同步的機制。信號量的作用是保護一段代碼,在同一時刻只允許一個進程執行。當一個進程想要執行這段被信號量保護起來的代碼時,需要先獲取信號量,執行完代碼后再釋放信號量,以便其他進程能夠獲取信號量并繼續執行。
-
共享內存(Shared Memory):共享內存是一種高效的進程間通信方式。它將一段內存映射到多個進程的地址空間中,多個進程可以直接訪問這段共享內存,從而實現數據共享。
RPC通信則通過網絡實現跨主機進程之間的通信,其實現方式通常包括:
-
客戶端-服務器(Client-Server)模式:在此模式下,客戶端應用程序向服務器應用程序發送請求,并等待響應。服務器應用程序接收請求,執行相應的操作,并將結果返回給客戶端。
-
遠程對象調用(Remote Object Invocation):在此模式下,客戶端使用遠程對象代理來調用遠程對象。遠程對象代理掌握著遠程對象的網絡地址信息,并將請求序列化為網絡字節流進行傳輸,然后等待遠程對象返回結果。
-
Web服務(Web Service):Web服務是一種基于HTTP協議實現的RPC機制。客戶端通過HTTP請求訪問Web服務,Web服務接收請求并調用相應的處理函數,最終將處理結果封裝為XML或JSON格式返回給客戶端。
九、前臺和后臺作業
總結Linux,前臺和后臺作業的區別,并說明如何在前臺和后臺中進行狀態轉換。
Linux中,前臺作業和后臺作業的區別在于是否占用當前命令行終端。
前臺作業是指當前正在命令行終端中運行的程序,它會占用終端,此時用戶需要等待該程序執行完畢才能輸入下一個命令。而后臺作業是指在后臺運行的程序,即該程序不占用當前終端,用戶可以繼續輸入其它命令。
在前臺和后臺之間進行狀態轉換有以下兩種方法:
-
在前臺作業中執行后臺作業:
在前臺運行的作業可以通過在命令后面添加 "&" 實現將其轉為后臺作業。例如:
./my-program &
-
在后臺作業中切換到前臺:
使用命令 fg 可以將后臺作業切換至前臺,讓程序重新占用當前終端。例如:
fg [job ID]
其中, [job ID] 是后臺作業的進程號或任務號。
使用命令 bg 可以將前臺作業轉為后臺作業。例如:
bg [job ID]
同樣, [job ID] 是前臺作業的進程號或任務號。
十、內核設計流派
總結內核設計流派及特點。
內核設計是操作系統的核心組成部分,其設計流派主要有單內核、微內核和混合內核。
-
單內核 單內核是最初的內核設計模式。在單內核中,所有的操作系統服務和驅動程序都運行在核心空間內,這些服務和驅動程序直接訪問硬件設備,并且實現了內存管理、進程調度、文件系統等核心功能。這種設計模式的優點是效率高,因為所有服務和驅動程序都在同一個地址空間內工作。缺點是安全性不高,因為一個錯誤的服務或驅動程序可能會破壞整個系統。
-
微內核 微內核是將內核功能分解成多個獨立的程序運行的設計模式,每個程序都運行在獨立的地址空間內,只提供最基本的服務。例如,任務調度、內存管理、IPC(進程間通信)和設備驅動程序等服務都是以相互獨立的方式運行的。這種設計模式的優點是可靠性和安全性高,因為每個服務都以獨立的方式運行,并且錯誤的服務或驅動程序的影響只限于自己的進程。缺點是性能低,因為由于每個服務都是獨立的程序運行,因此在服務之間傳遞數據需要額外的開銷。
-
混合內核 混合內核是單內核和微內核的結合。它將一些核心函數移動到獨立的地址空間中,以提高系統的可靠性和安全性,并以較低的開銷提供IPC和設備驅動程序等服務。這種設計模式的優點是可靠性和安全性高,同時性能也比微內核設計模式高。缺點是代碼復雜性高,因為不同的服務和驅動程序有不同的運行方式和限制,所以必須確保它們之間的協作和一致性。
十一、Linux啟動流程
總結rocky啟動流程,grub工作流程。
Rocky啟動流程大致如下:
1.計算機通電后,BIOS會自動運行并執行POST(Power-On Self Test)。
2.BIOS會尋找可啟動設備,通常會先尋找硬盤、光驅和USB設備。
3.當BIOS找到可啟動設備后,它會將引導扇區(boot sector)加載到內存中,并將控制權交給引導扇區程序。
4.引導扇區程序會加載GRUB(Grand Unified Bootloader)引導程序。GRUB是R默認的引導程序。
5.GRUB會顯示啟動菜單,讓用戶選擇要啟動的操作系統或內核。
6.用戶選擇了操作系統或內核后,GRUB會加載內核文件和啟動選項,并將控制權交給內核。
7.內核會初始化硬件、加載驅動程序、掛載文件系統等操作。
8.內核完成初始化后,會運行/sbin/init程序,此時系統進入用戶空間。
9./sbin/init程序會根據配置文件/etc/inittab啟動各種服務,并設置系統運行級別。
10.至此,Rocky系統啟動完成。
GRUB的工作流程大致如下:
1.GRUB被加載到內存中后,顯示啟動菜單。
2.用戶選擇要啟動的操作系統或內核后,GRUB會加載內核文件和啟動選項。
3.GRUB會從文件系統中讀取內核文件和相關的初始化文件,例如/etc/grub.conf。
4.GRUB會將內核和相關文件加載到內存中,并設置啟動參數。
5.最后,GRUB會將控制權交給內核,讓內核開始啟動操作系統。
十二、chkconfig服務腳本
手寫chkconfig服務腳本,可以實現服務的開始,停止,重啟。
# chkconfig: - 96 3
# description: This is test service script
. /etc/init.d/functions
start(){
[ -e /var/lock/subsys/testsrv ] && exit || touch /var/lock/subsys/testsrv
echo $PATH
action "Starting testsrv"
sleep 3
}
stop(){
[ -e /var/lock/subsys/testsrv ] && rm /var/lock/subsys/testsrv || exit
action "Stopping testsrv"
}
status(){
[ -e /var/lock/subsys/testsrv ] && echo "testsrv is running..." || echo "testsrv is stopped"
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
exit 2
esac
十三、systemd服務配置文件
總結systemd服務配置文件。
systemd是一個Linux系統的初始化系統和服務管理器。在systemd中,每個服務都有一個對應的配置文件,其中定義了服務的各種屬性和行為。通常情況下,這些配置文件存儲在/etc/systemd/system目錄下。
以下是一個簡單的systemd服務配置文件的示例:
[Unit]
Description=My Service
After=network.target
[Service]
ExecStart=/usr/local/bin/my-service
Restart=always
[Install]
WantedBy=multi-user.target
該文件分為三個部分:
-
[Unit]:包含服務的基本信息和依賴關系。
-
Description:服務的描述信息。
-
After:指定服務所需的其他服務或者單元,在這個例子中,服務需要在網絡服務之后啟動。
-
[Service]:包含服務執行時的相關信息。
-
ExecStart:指定服務的啟動命令。
-
Restart:指定服務異常退出后的重啟策略,這里設置為always表示總是重啟。
-
[Install]:包含安裝服務時的相關信息。
-
WantedBy:指定服務在哪些運行級別下啟動,這里設置為multi-user.target表示在多用戶模式下啟動。
一個標準的systemd服務配置文件通常由三個主要部分組成:[Unit]、[Service]和[Install]。下面我們將詳細介紹這些部分以及它們的屬性。
[Unit]
該部分包含了服務的基本信息和依賴關系。下面是一些常用的屬性:
-
Description:服務的描述信息。
-
After:指定服務所需的其他服務或者單元啟動完成之后才能啟動。
-
Requires:指定服務所需的其他服務或者單元(必須同時啟動)。
-
Wants:指定服務所需的其他服務或者單元(推薦同時啟動)。
-
Before:指定服務啟動之前需要啟動的服務或者單元。
-
Conflicts:指定服務與其他服務或單元存在沖突。
[Service]
該部分包含了服務執行時的相關信息。下面是常用的屬性:
-
Type:指定服務的類型,可以是simple(默認,直到服務退出才會返回控制權)、forking(在服務啟動時派生一個子進程)、oneshot(服務只會運行一次)等。
-
ExecStart:指定服務的啟動命令。
-
ExecStop:指定服務的停止命令。
-
Restart:指定服務異常退出后的重啟策略,可以是no(不重啟)、always(總是重啟)、on-failure(僅在非0退出狀態時重啟)等。
-
User:指定服務所屬的用戶。
-
Group:指定服務所屬的組。
-
Environment:指定服務執行時需要的環境變量。
-
WorkingDirectory:指定服務執行時的工作目錄。
[Install]
該部分包含了安裝服務時的相關信息。下面是常用的屬性:
-
WantedBy:指定服務在哪些運行級別下啟動,可以是multi-user.target(多用戶模式)、graphical.target(圖形化模式)等。
-
RequiredBy:指定需要該服務的其他服務或單元(必須同時啟動)。
-
Also:指定需要該服務的其他服務或單元(推薦同時啟動)。
以上是systemd服務配置文件的主要部分和屬性介紹,這些屬性根據服務需求而異。使用systemd配置文件來管理服務非常方便,可以有效地提高系統管理的效率和可靠性。
十四、system啟動流程
總結system啟動流程。
systemd 是一個具有啟動管理、服務管理、日志管理和設備管理等功能的系統和服務管理器,其啟動流程主要包括以下幾個步驟:
-
系統引導:當計算機啟動時,BIOS/UEFI會加載GRUB2或者其他引導程序,并從硬盤、光盤或者網絡中讀取內核映像文件。
-
內核初始化:內核映像文件被加載后,內核會對硬件進行初始化操作,并創建第一個用戶空間進程systemd(PID 1)。
-
systemd初始化:systemd會讀取所有的unit文件,并按照啟動順序將它們加入到啟動隊列中,這些unit文件包括target文件、service文件、socket文件等。
-
啟動目標:每個target文件都是一套預定義的unit,在systemd啟動時,會根據指定的default target決定啟動哪一個target文件(比如multi-user.target,表示只啟動多用戶模式,并不啟動圖形界面)。
-
加載依賴項:在啟動target前,systemd會根據unit文件中的Requires和Wants字段,來查找并自動加載必要的依賴文件和服務。
-
啟動服務:在所有依賴關系滿足后,systemd會按照啟動順序執行服務文件,并在執行過程中記錄各種系統日志。
-
啟動完成:一旦所有服務都啟動完畢,systemd會進入idle狀態,并等待下一次事件發生。
總之,systemd啟動流程非常復雜和龐大,但由于其高度集成和可擴展性,已成為眾多Linux發行版的標配啟動管理器。
十五、AWK工作原理
總結awk工作原理,awk命令,選項,示例。
awk是一種文本處理工具,它按行讀取輸入文件并將每行分解為字段。可以使用任意分隔符來指定字段之間的分隔符,默認情況下使用空格和制表符。在每個字段中,awk執行指定的動作,并且可以根據需要打印輸出結果。
awk的基本工作原理如下:
-
將輸入文件讀入內存,一行一行地處理。
-
按照指定的字段分隔符將每行拆分為多個字段。
-
對于每個字段,執行指定的操作,這些操作包括條件判斷、變量設置、數學計算、字符串操作等。
-
根據需要輸出結果。
對于每個輸入行,awk會執行指定的操作,這些操作可以是內置函數、用戶自定義函數、條件語句、循環語句等。awk還支持多種模式和模式匹配方式,以便更容易地處理文本數據。常見的應用包括文本處理、報告生成、數據轉換和格式化等。
awk命令的一般語法格式為:
awk 'pattern {action}' input_file
其中,pattern用于指定需要匹配的模式,action用于指定匹配成功后需要執行的操作,input_file表示要處理的輸入文件。如果沒有指定輸入文件,則awk默認從標準輸入讀取數據。
以下是一些常見的awk命令使用示例:
-
輸出指定列:打印第1列和第3列
awk '{print $1, $3}' input_file
-
根據條件過濾數據:打印第2列等于"hello"的行
awk '$2 == "hello" {print}' input_file
-
基于統計信息生成報告:輸出文件的行數、單詞數和字符數
awk 'BEGIN {lines=words=chars=0} {lines++; words+=NF; chars+=length} END {print lines, words, chars}' input_file
-
對數據進行計算:求第2列的平均值
awk '{sum+=$2} END {print sum/NR}' input_file
awk命令有許多選項可用于指定模式匹配和規則動作的行為。以下是一些常見的awk選項:
-
-F:指定字段分隔符,默認為制表符或空格。例如,-F:將冒號作為字段之間的分隔符。
-
-
-v:定義變量并將其傳遞給awk程序。例如,awk -v var=value 'pattern {action}' input_file中的var變量可在awk程序中使用。
-
-f:從文件中讀取awk程序。例如,awk -f script.awk input_file將從script.awk文件中讀取awk程序。
-
-i inplace:啟用原地編輯模式,并將結果寫回到輸入文件中,而不是打印到標準輸出。該選項只適用于GNU awk(gawk)版本4.1及更高版本。
-
-W:指定gawk擴展功能。例如,-W interactive可以啟用交互式模式,-W compat可以使gawk與舊版awk兼容。
-
-n:禁用默認打印操作,只執行指定的規則操作,不輸出處理的數據。
-
-N:禁用所有輸入記錄的拆分,默認情況下,awk將根據空格和制表符分割輸入記錄。
這只是一小部分常見的awk選項,還有其他許多選項和功能可供選擇,具體取決于你所使用的awk版本。可以通過查看man awk命令來獲取完整的選項列表和說明。
十六、AWK數組/函數
總結awk的數組,函數。
awk中的數組是一種關聯數組,它可以存儲多個值,并使用一個鍵來引用每個值。awk數組中的鍵通常是字符串或數字,數組中的值可以是任何類型的數據,包括字符串、數字、其他數組等。
在awk中,可以通過以下方法聲明和訪問數組:
-
聲明數組:使用下面的語法來聲明數組:
array[index]=value
array["key"]=value
其中,index和key都是索引值,value則是與索引相關聯的值。
-
訪問數組:可以使用以下語法來訪問數組中的元素:
# 通過數字索引訪問數組
array[index]
# 通過字符串索引訪問數組
array["key"]
可以像訪問普通變量一樣使用數組來訪問它們的元素。
以下是一個簡單的例子,演示了如何在awk中創建和使用數組:
# test.txt
apple,fruit,red
banana,fruit,yellow
carrot,vegetable,orange
# awk程序獲取test.txt文件中所有水果的名稱
awk -F, '{ if ($2 == "fruit") { fruits[$1] = $3 } } END { for (f in fruits) print f, fruits[f] }' test.txt
在上面的例子中,我們創建了一個名為fruits的數組,存儲了所有水果的名稱和顏色。在每一行上,如果水果的類型是fruit,則將該水果的名稱和顏色存儲到fruits數組中。最后,使用for循環遍歷fruits數組并輸出所有水果的名稱和顏色。
希望這個例子演示了如何使用awk數組來處理文本數據。
awk是一種強大的文本處理工具,它還提供了許多內置函數來處理文本和數值類型。此外,awk還允許用戶定義自己的函數,以便更好地組織和重復使用代碼。
在awk中,可以通過以下語法來定義和調用函數:
-
定義函數:定義一個函數需要使用function關鍵字,并在函數名稱后面跟一個括號。如果函數有參數,這些參數應該放在括號中,并用逗號分隔。
function name(parameter1, parameter2, ...) {
# 函數體,包括語句和表達式
}
-
調用函數:使用函數名稱和參數列表來調用函數。參數應該用逗號分隔,并放在括號中。
name(argument1, argument2, ...)
以下是一個簡單的例子,演示如何在awk中定義和調用函數:
# awk程序計算兩個數字之和
function add(x, y) {
return x + y
}
# 在main out中調用add函數
BEGIN {
a = 2
b = 3
print "The sum of", a, "and", b, "is", add(a, b)
}
在上面的例子中,我們定義了一個名為add的函數,它接受兩個參數并返回它們的和。然后,在BEGIN塊中,我們聲明了兩個變量a和b,并在print語句中調用了add函數,以顯示它們的和。
除此之外,awk還提供了許多內置函數,例如字符串函數、數學函數、時間函數等。可以在awk的官方文檔中查找完整列表,并在需要時使用它們來處理數據。
十七、CA管理相關工具
總結ca管理相關的工具,根據使用場景總結示例。
要建立私有證書頒發機構(CA),可以參考以下步驟:
-
選擇適合的CA軟件:可以根據自己的需求選擇開源的或商業的CA軟件,如OpenSSL、EJBCA、Microsoft Certificate Services等。這些軟件提供了創建和管理證書的工具和面板,能夠方便地處理數字證書。
-
創建根證書:在選擇好CA軟件后,需要創建一個根證書。根證書是CA的頂級證書,對其進行簽名的證書只有兩種方式,即信任或被撤銷。創建根證書時需要輸入一些組織信息,如組織名稱、國家、州/省、城市以及聯系信息等。
-
創建中間證書(可選):如果需要更復雜的證書結構,可以在根證書下創建其他中間CA。中間CA是通過根CA簽名的證書,用于頒發子證書。中間CA的目的是為了隔離根證書,防止根證書被泄露后全部證書都失效。
-
頒發子證書:在創建完根證書和中間證書(可選)之后,可以開始頒發子證書。頒發子證書時需要指定證書的一些信息,如證書名稱、公鑰、有效期限等。子證書頒發之前必須使用父證書進行簽名,以便證書鏈的完整性驗證。
-
處理證書吊銷:如果某個證書不再被信任或者存在安全風險,需要對其進行吊銷操作。在吊銷證書后,該證書將不再被認為是有效的,并且無法用來進行加密或數字簽名。吊銷證書可以通過CA軟件中提供的工具來完成。
-
公開證書:最后,需要將頒發的證書公開發布到可信賴的目錄中,這樣其他人才能獲得并驗證證書的合法性。
需要注意的是,在建立私有CA時,需要非常小心和謹慎地保護私鑰,確保它們不被泄露。泄露私鑰可能會導致他人偽造證書,進而進行惡意attack。
OpenSSL的openssl.cnf配置文件比較復雜,包括多個節(section)以及各種選項參數,下面是一些比較常見的選項參數:
-
RANDFILE:用于指定隨機數文件的路徑,這個文件存儲了OpenSSL需要生成加密算法中所需的隨機數,例如需要創建自簽名證書時。
-
HOME:用于指定OpenSSL默認的主目錄,默認值為/etc/pki/tls。
-
certificate:用于設置證書文件的名稱,默認值為$dir/cert.pem。
-
private_key:用于設置私鑰文件的名稱,默認值為$dir/private/key.pem。
-
default_md:用于設置默認使用的消息摘要算法,默認值為sha256。
-
req_extensions:用于設置證書請求時添加的擴展信息。
-
x509_extensions:用于設置證書時添加的擴展信息。
此外,根據你的應用場景,還可以設置其它許多參數,比如:
-
[ca] 配置 CA 證書和 CA 目錄信息
-
[req] 配置證書的請求信息
-
[req_distinguished_name] 配置證書請求的 DN
-
[usr_cert] 配置用戶證書信息
-
[v3_ca] 配置 CA 證書的 V3 擴展
-
[v3_req] 配置證書請求的 V3 擴展
需要注意的是,在修改openssl.cnf文件時需要小心操作,確保其符合安全標準,并進行相應的測試和驗證,以保證系統的安全性和穩定性。
創建CA所需要的文件
#生成證書索引數據庫文件
touch /etc/pki/CA/index.txt
#指定第一個頒發證書的序列號
echo 01 > /etc/pki/CA/serial
生成CA私鑰
cd /etc/pki/CA/
(umask 066; openssl genrsa -out private/cakey.pem 2048)
生成CA自簽名證書
openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -day 3650 -out /etc/pki/CA/cacert.pem
-new:生成新證書簽署請求
-x509:專用于CA生成自簽證書
-key:生成請求用到的私鑰文件
-days n:證書的有效期限
-out /PATH/TO/SOMECERTFILE:證書的保存路徑
用戶生成私鑰和證書申請
(umask 066;openssl genrsa -out /data/app1/app1.key 2048)
openssl req -new -key /data/app1/app1.key -out /data/app1/app1.csr
CA 頒發證書
openssl ca -in /data/app1/app1.csr -out /etc/pki/CA/certs/app1.crt -days 1000
十八、加密算法
總結對稱加密和非對稱加密算法和用openssl簽發證書步驟。
對稱加密
對稱加密:加密和解密使用同一個密鑰
特性:
-
加密、解密使用同一個密鑰,效率高;
-
將原始數據分割成固定大小的塊,逐個進行加密
缺陷:
-
密鑰過多
-
密鑰分發
-
數據來源無法確認
常見對稱加密算法:
-
DES:Data Encryption Standard,56bits
-
3DES:
-
AES:Advanced (128, 192, 256bits)
-
Blowfish,Twofish
-
IDEA,RC6,CAST5
非對稱加密
非對稱加密:密鑰是成對出現
-
公鑰:public key,公開給所有人,主要給別人加密使用
-
私鑰:secret key,private key 自己留存,必須保證其私密性,用于自已加密簽名
-
特點:用公鑰加密數據,只能使用與之配對的私鑰解密;反之亦然
功能:
-
數據加密:適合加密較小數據,比如: 加密對稱密鑰
-
數字簽名:主要在于讓接收方確認發送方身份
缺點:
-
密鑰長,算法復雜
-
加密解密效率低下
常見算法:
-
RSA:由 RSA 公司發明,是一個支持變長密鑰的公共密鑰算法,需要加密的文件塊的長度也是可變的,可實現加密和數字簽名
-
DSA(Digital Signature Algorithm):數字簽名算法,是一種標準的 DSS(數字簽名標準)
-
ECC(Elliptic Curves Cryptography):橢圓曲線密碼編碼學,比RSA加密算法使用更小的密鑰,提供相當的或更高等級的安全
OpenSSL簽發證書
建立私有CA:
-
OpenCA:OpenCA開源組織使用Perl對OpenSSL進行二次開發而成的一套完善的PKI免費軟件
-
openssl:相關包 openssl和openssl-libs
證書申請及簽署步驟:
-
生成證書申請請求
-
RA核驗
-
CA簽署
-
獲取證書
[
]
[
]
[
]
[ ]
配置文件部分內容說明
[ CA_default ]
dir = ./demoCA #所有與證書相關的文件目錄,在實際使用時此處
要進行修改
certs = $dir/certs #頒發的證書文件目錄
crl_dir = $dir/crl #吊銷的證書文件
database = $dir/index.txt #證書索引文件
new_certs_dir = $dir/newcerts #新頒發的證書目錄
certificate = $dir/cacert.pem #CA機構自己的證書
serial = $dir/serial #證書編號文件,下一個證書編號,16進制
crlnumber = $dir/crlnumber #存放當前CRL編號的文件
crl = $dir/crl.pem #CA證書吊銷列表文件
private_key = $dir/private/cakey.pem #CA證書的私鑰
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
匹配策略,指用此CA頒發證書時,證書的相關字段與CA的值的匹配規則
匹配規則 |
說明 |
match |
要求申請填寫的信息跟CA設置信息必須一致 |
optional |
可有可無,跟CA設置信息可不一致 |
supplied |
必須填寫這項申請信息 |
創建私有CA
1、創建CA所需要的文件
[
][
]/etc/pki/CA/
├── certs
├── crl
├── newcerts
└── private
4 directories, 0 files
2、 生成CA私鑰
[
][ ]
3、生成CA自簽名證書
[root@ubuntu CA]# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days
3650 -out /etc/pki/CA/cacert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN #國家代碼
State or Province Name (full name) [Some-State]:beijing #省/州
Locality Name (eg, city) []:beijing #城市
Organization Name (eg, company) [Internet Widgits Pty Ltd]:magedu #公司/單位
Organizational Unit Name (eg, section) []:m54 #部門
Common Name (e.g. server FQDN or YOUR name) []:www.magedu.org #域名
Email Address []: #郵箱
-new #生成新證書簽署
請求
-x509 #專用于CA生成自
簽證書
-key #生成請求時用到
的私鑰文件
-days n #證書的有效期限
-out /PATH/TO/SOMECERTFILE #證書的保存路徑
#查看證書
[root@ubuntu CA]# cat /etc/pki/CA/cacert.pem
-----BEGIN CERTIFICATE-----
MIIDszCCApugAwIBAgIURIyd0TW4qqffpbh1NudkH3ZLWQUwDQYJKoZIhvcNAQEL
BQAwaTELMAkGA1UEBhMCQ04xEDAOBgNVBAgMB2JlaWppbmcxEDAOBgNVBAcMB2Jl
aWppbmcxDzANBgNVBAoMBm1hZ2VkdTEMMAoGA1UECwwDbTU0MRcwFQYDVQQDDA53
d3cubWFnZWR1Lm9yZzAeFw0yMzA1MjIxMzMwMzFaFw0zMzA1MTkxMzMwMzFaMGkx
CzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdiZWlqaW5nMRAwDgYDVQQHDAdiZWlqaW5n
MQ8wDQYDVQQKDAZtYWdlZHUxDDAKBgNVBAsMA201NDEXMBUGA1UEAwwOd3d3Lm1h
Z2VkdS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCjAuAX6QgC
o1GBbWefyHTib/Unq7k4l1mgbjvfLv9mccSUFaZcZllIdRb5HPpeGPtjHjgxRfS6
iMNdVrVwON9gkLMv/BDPJKUdK7a3LokweohU+i0o2Xnp2ZZ1AhDgUvE1vHhOQa/a
YZKTgnbucJAeKr0u3/GoHlJvb652t7/g13yUR9XrLaLjIYk+IcDvdBVd2apRO6w3
IvkUrhhLQ3FSNWLi6mOuCdXfTs7TtQDbu1guLMo5ZNZffHXlnUNpjF5rtvsD8L7m
bvjRvEdBAyYp9IwV0vMLntSZ0bdrntAGlBXi18W2nb6LGskQhViC2J0U59gk5bVZ
0LvGbVeXMQm1AgMBAAGjUzBRMB0GA1UdDgQWBBREjMYMzWwjJT1PtwMJ3/CASxIK
EjAfBgNVHSMEGDAWgBREjMYMzWwjJT1PtwMJ3/CASxIKEjAPBgNVHRMBAf8EBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBJz2HTy/UlOUyVlVf+7imbToWyCkDDrB1P
26hrHIPcl+njzP5qFn662po4LczXRK1oqv7OOBjvLOTuj5eVmz3Jzf4dGk54E6jP
Vqp6SjnH0gOFBqJx0bRo5fIzbBZ6yVedXPQM5X11rhS+eJmeU2bU4QcT9PZ08M1Z
Hp+QJmJBpXHxd8ouu+YU4fyFtde24NYQNtKLFfJCyJl4wO210CXYHoTVe8dtWFoS
UvqUR49iFZW1uPXXQtP6eizw4k+sV9afaEii+u4fnGdIs2q3c+GPn276V1MrcQnw
GRdFX/WHvr0asO9wvoQTnB9LM+UEqn61oJ+aGXgkujbaTtaNYOS/
-----END CERTIFICATE-----
#查看證書
[root@ubuntu CA]# openssl x509 -in /etc/pki/CA/cacert.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
44:8c:9d:d1:35:b8:aa:a7:df:a5:b8:75:36:e7:64:1f:76:4b:59:05
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, ST = beijing, L = beijing, O = magedu, OU = m54, CN =
www.magedu.org
Validity
Not Before: May 22 13:30:31 2023 GMT
Not After : May 19 13:30:31 2033 GMT
Subject: C = CN, ST = beijing, L = beijing, O = magedu, OU = m54, CN =
www.magedu.org
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
......
......
#導到WINDOWS中查看
[root@ubuntu CA]# sz /etc/pki/CA/cacert.pem
https://country-code.cl/ #國家代碼
申請證書并頒發證書
1、為需要使用證書的主機生成生成私鑰
[root@ubuntu CA]# openssl genrsa -out /data/test.key 2048
2、為需要使用證書的主機生成證書申請文件
#注意:默認要求國家,省,公司名稱三項必須和CA一致
CA]# openssl req -new -key /data/test.key -out /data/test.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:beijing
Locality Name (eg, city) []:beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:magedu
Organizational Unit Name (eg, section) []:m54-class
Common Name (e.g. server FQDN or YOUR name) []:www.m54.magedu.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
3、用CA簽署證書并將證書頒發給請求者
#創建索引文件
[root@ubuntu CA]# touch /etc/pki/CA/index.txt
#創建序號文件
[root@ubuntu CA]# echo 0F > /etc/pki/CA/serial
#簽發證書
[root@ubuntu CA]# openssl ca -in /data/test.csr -out /etc/pki/CA/certs/test.crt -
days 100
Using configuration from /usr/lib/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 15 (0xf)
Validity
Not Before: May 22 13:56:23 2023 GMT
Not After : Aug 30 13:56:23 2023 GMT
Subject:
countryName = CN
stateOrProvinceName = beijing
organizationName = magedu
organizationalUnitName = m54-class
commonName = www.m54.magedu.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
13:7E:49:68:5E5F:23:68127EB5:90:020C:64
X509v3 Authority Key Identifier:
44:8C0C6C:23:25:3D:4F03:09F0:80:4B:12:0A:12
Certificate is to be certified until Aug 30 13:56:23 2023 GMT (100 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
#查看
[root@ubuntu CA]# tree /etc/pki/CA/
/etc/pki/CA/
├── cacert.pem
├── certs
│ └── test.crt
├── crl
├── index.txt
├── index.txt.attr
├── index.txt.old
├── newcerts
│ └── 0F.pem
├── private
│ └── cakey.pem
├── serial
└── serial.old
4 directories, 9 files
#原來是0F,加1后變成10
[root@ubuntu CA]# cat /etc/pki/CA/serial
10
#V 表示有效,230830 表示2023年8月30日過期,0F 表示證書編號
[root@ubuntu CA]# cat /etc/pki/CA/index.txt
V 230830135623Z 0F unknown /C=CN/ST=beijing/O=magedu/OU=m54-
class/CN=www.m54.magedu.com
4、查看證書中的信息:
#根據編號查看狀態
CA]# openssl ca -status 0F
Using configuration from /usr/lib/ssl/openssl.cnf
0F=Valid (V)
CA]# openssl x509 -in /etc/pki/CA/certs/test.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 15 (0xf)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, ST = beijing, L = beijing, O = magedu, OU = m54, CN =
www.magedu.org
Validity
Not Before: May 22 1323 2023 GMT
Not After : Aug 30 1323 2023 GMT
Subject: C = CN, ST = beijing, O = magedu, OU = m54-class, CN =
www.m54.magedu.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
(2048 bit)
: ......
......
如果證書申請文件中的配置項與CA機構的匹配規則不一致,將無法簽發證書
吊銷證書
在客戶端獲取要吊銷的證書的 serial
[root@ubuntu CA]# openssl x509 -in /etc/pki/CA/certs/test.crt -noout -serial -
subject
serial=0F
subject=C = CN, ST = beijing, O = magedu, OU = m54-class, CN =
www.m54.magedu.com
在CA上,根據客戶提交的 serial 與 subject 信息,對比檢驗是否與 index.txt 文件中的信息一致,吊銷證書:
[root
CA]# openssl ca -revoke /etc/pki/CA/certs/test.crtUsing configuration from /usr/lib/ssl/openssl.cnf
Revoking Certificate 0F.
Data Base Updated
[root
CA]# cat /etc/pki/CA/index.txtR 230830135623Z 230522141008Z 0F unknown
/C=CN/ST=beijing/O=magedu/OU=m54-class/CN=www.m54.magedu.com
指定第一個吊銷證書的編號,注意:第一次更新證書吊銷列表前,才需要執行
[ ]
更新證書吊銷列表
[
]Using configuration from /usr/lib/ssl/openssl.cnf
查看crl文件:
CA]# openssl crl -in /etc/pki/CA/crl.pem -noout -text
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, ST = beijing, L = beijing, O = magedu, OU = m54, CN =
www.magedu.org
Last Update: May 22 1400 2023 GMT
Next Update: Jun 21 1400 2023 GMT
CRL extensions:
X509v3 CRL Number:
......
......
CentOS7 創建自簽名證書
certs]# cd /etc/pki/tls/certs
certs]# make
This makefile allows you to create:
......
......
Examples:
make server.key
make server.csr
make server.crt
make stunnel.pem
make genkey
make certreq
make testcert
make server.crt SERIAL=1
make stunnel.pem EXTRA_FLAGS=-sha384
make testcert DAYS=600
#根據目錄中的 Makefile 來執行不同操作
certs]# ls
ca-bundle.trust.crt make-dummy-cert Makefile renew-dummy-cert
certs]# cat Makefile
UTF8 := $(shell locale -c LC_CTYPE -k | grep -q charmap.*UTF-8 && echo -utf8)
DAYS=365
KEYLEN=2048
......
......
#centos8中沒有該Makefile,可以SCP過去使用
OpenSSH 免密認證是通過使用公鑰、私鑰實現的。在 OpenSSH 中,客戶端和服務器端都會有一對密鑰:私鑰和公鑰。
-
首先在客戶端生成一對密鑰(ssh-keygen)
-
并將客戶端的公鑰ssh-copy-id復制到服務端
-
當客戶端再次發送一個連接請求,包括ip、用戶名
-
服務端得到客戶端的請求后,會到authorized_keys中查找,如果有響應的IP和用戶,就會隨機生成一個字符穿,例如:13579
-
服務端將使用客戶端復制過來的公鑰進行加密,然后發送給客戶端
-
得到服務端發來的消息后,客戶端會使用私鑰進行解密,然后解密后的字符串發送給服務端
-
服務端接受到客戶端發來的字符串后,跟之前的字符串進行對比,如果一致,就允許免密碼登錄
-
Linux
+關注
關注
87文章
11230瀏覽量
208937 -
字符串
+關注
關注
1文章
577瀏覽量
20486 -
變量
+關注
關注
0文章
613瀏覽量
28330
原文標題:Linux進程管理和啟動流程
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論