1. 程式人生 > 實用技巧 >【Mage作業】linux運維實戰練習-2016年1月19日-2月3日課程作業(練習)(第二次)...

【Mage作業】linux運維實戰練習-2016年1月19日-2月3日課程作業(練習)(第二次)...

1、描述centos6系統開機啟動流程;

按下開機按鍵

--> 主機板檢測到開機訊號

--> 硬體自動將BIOS或者可以引導到BIOS的程式複製到記憶體指定地址

--> CPU復位內部暫存器 使得CPU從上面指定的記憶體地址開始執行程式

--> 進入 BIOS 程式(對於UEFI引導的主機 可能略有出入)

--> 系統自檢

--> BIOS自檢完成後 根據引導選項 選擇引導裝置

--> 讀取引導裝置的MBR資訊,載入Bootloader程式(對於UEFI引導的主機 GPT分割槽的磁碟裝置及網路啟動的裝置等 可能略有出入)

--> Bootloader程式(主要是LILO及GRUB)將系統控制權移交至Linux Kernel

--> Kernel 通過RAMFS輔助或者直接執行 完成自身初始化:

探測可識別的所有硬體裝置

載入硬體驅動程式

以只讀方式掛載根檔案系統

執行使用者空間的第一個應用程式 /sbin/init

init 程式主要分為以下三種 Sys-V、Upstart、Systemd

2、描述/etc/rc.d/sysinit指令碼功能;

  1. 設定主機名;

  2. 設定歡迎資訊;

  3. 啟用udev和selinux;

  4. 掛載/etc/fstab檔案中定義的檔案系統;

  5. 檢測根檔案系統,並以讀寫方式重新掛載根檔案系統:

  6. 設定系統時鐘 (讀取硬體時鐘並將其設定為當前系統時鐘);

  7. 啟用swap裝置;

  8. 根據/etc/sysctl.conf 檔案設定核心引數;

  9. 啟用lvm與soft raid裝置;

  10. 載入額外裝置的驅動程式;

  11. 清理操作

3、總結文字處理工具sed及awk的用法;(必須附帶示例)

sed

sed: Stream EDitor, 行編輯器;

用法:

sed [option]... 'script' inputfile...

script: '地址命令'

常用選項:

    • -n:不輸出模式中的內容至螢幕;

    • -e: 多點編輯;

    • -f /PATH/TO/SCRIPT_FILE: 從指定檔案中讀取編輯指令碼;

    • -r: 支援使用擴充套件正則表示式;

    • -i: 原處編輯;

地址定界:

    • (1) 不給地址:對全文進行處理;

    • (2) 單地址:

      • #: 指定的行;

      • /pattern/:被此處模式所能夠匹配到的每一行;

    • (3) 地址範圍:

      • #,#

      • #,+#

      • /pat1/,/pat2/

      • #,/pat1/

    • (4) ~:步進

      • 1~2

      • 2~2

編輯命令:

    • d: 刪除;

    • p: 顯示模式空間中的內容;

    • a \text:在行後面追加文字;支援使用\n實現多行追加;

    • i \text:在行前面插入文字;支援使用\n實現多行插入;

    • c \text:替換行為單行或多行文字;

    • w /path/to/somefile: 儲存模式空間匹配到的行至指定檔案中;

    • r /path/from/somefile:讀取指定檔案的文字流至模式空間中匹配到的行的行後;

    • =: 為模式空間中的行列印行號;

    • !: 取反條件;

    • s///:支援使用其它分隔符,[email protected]@@,s###;

      替換標記:

      • g: 行內全域性替換;

      • p: 顯示替換成功的行;

      • w /PATH/TO/SOMEFILE:將替換成功的結果儲存至指定檔案中;

高階編輯命令:

    • h: 把模式空間中的內容覆蓋至保持空間中;

    • H:把模式空間中的內容追加至保持空間中;

    • g: 從保持空間取出資料覆蓋至模式空間;

    • G:從保持空間取出內容追加至模式空間;

    • x: 把模式空間中的內容與保持空間中的內容進行互換;

    • n: 讀取匹配到的行的下一行至模式空間;

    • N:追加匹配到的行的下一行至模式空間;

    • d: 刪除模式空間中的行;

    • D:刪除多行模式空間中的所有行;

示例:

sed -n 'n;p' FILE          # 顯示偶數行
sed '1!G;h;$!d' FILE       # 逆向顯示檔案內容
sed '$!N;$!D' FILE         # 取出檔案後兩行
sed '$!d' FILE             # 取出檔案最後一行
sed 'G' FILE               # 每行後加一空白行 
sed '/^$/d;G' FILE         # 將多個空白行合併為一個空白行
sed 'n;d' FILE             # 顯示奇數行;
sed -n '1!G;h;$p' FILE     # 逆向顯示檔案中的每一行;
 
#刪除/boot/grub/grub.conf檔案中所有以空白開頭的行行首的空白字元;
sed '[email protected]^[[:space:]]\[email protected]@' /etc/grub2.cfg
 
#刪除/etc/fstab檔案中所有以#開頭,後面至少跟一個空白字元的行的行首的#和空白字元;
sed '[email protected]^#[[:space:]]\[email protected]@' /etc/fstab
 
#echo一個絕對路徑給sed命令,取出其基名;取出其目錄名;
# echo "/etc/sysconfig/" | sed '[email protected][^/]\+/\[email protected]@'


awk

gnu awk: gawk,報告生成工具 格式化文字輸出 內建有指令碼語言直譯器 具有一般程式語言所支援的所有功能。

用法:

基本用法:gawk [options] 'program' FILE ...
program: PATTERN{ACTION STATEMENTS}
語句之間用分號分隔

選項:

    • -F:指明輸入時用到的欄位分隔符;

    • -v var=value: 自定義變數;

變數:

    • 內建變數

      • FS:input field seperator,預設為空白字元;

      • OFS:output field seperator,預設為空白字元;

      • RS:input record seperator,輸入時的換行符;

      • ORS:output record seperator,輸出時的換行符;

      • NF:number of field,欄位數量 {print NF}, {print $NF}

      • NR:number of record, 行數;

      • FNR:各檔案分別計數;行數;

      • FILENAME:當前檔名;

      • ARGC:命令列引數的個數;

      • ARGV:陣列,儲存的是命令列所給定的各引數;

    • 自定義變數

      • -v var=value
        變數名區分字元大小寫;

      • 在program中直接定義

運算子:

    • 算術操作符: x+y, x-y, x*y, x/y, x^y, x%y, -x, +x(轉換為數值);

    • 字串操作符:沒有符號的操作符,字串連線

    • 賦值操作符: =, +=, -=, *=, /=, %=, ^=, ++, --

    • 比較操作符: >, >=, <, <=, !=, ==

    • 模式匹配符: ~ (是否匹配), !~ (是否不匹配)

    • 邏輯操作符: &&, ||, !

    • 函式呼叫: function_name(argu1, argu2, ...)

    • 條件表示式: selector?if-true-expression:if-false-expression

PATTERN:

    1. empty:空模式,匹配每一行;;

    2. /regular expression/:僅處理能夠被此處的模式匹配到的行;

    3. relational expression: 關係表示式;結果有“真”有“假”;結果為“真”才會被處理;(真:結果為非0值,非空字串;)

    4. line ranges:行範圍,
      startline,endline:/pat1/,/pat2/
      注意: 不支援直接給出數字的格式

    5. BEGIN/END模式

      • BEGIN{}: 僅在開始處理檔案中的文字之前執行一次;
      • END{}:僅在文字處理完成之後執行一次;

常用的action:

    1. Expressions

    2. Control statements:if, while等;

    3. Compound statements:組合語句;

    4. input statements

    5. output statements

控制語句:

    • if(condition) {statments}

    • if(condition) {statments} else {statements}

    • while(conditon) {statments}

    • do {statements} while(condition)

    • for(expr1;expr2;expr3) {statements}

    • break

    • continue

    • delete array[index]

    • delete array

    • exit

    • { statements }

array:

    • 關聯陣列:array[index-expression]

      • index-expression:

        1. 可使用任意字串;字串要使用雙引號;
        2. 如果某陣列元素事先不存在,在引用時,awk會自動建立此元素,並將其值初始化為“空串”;
      • 若要判斷陣列中是否存在某元素,要使用"index in array"格式進行;

      • 若要遍歷陣列中的每個元素,要使用for迴圈: for(var in array) {for-body}

函式:

  • 內建函式

    • 數值處理:

      • rand():返回0和1之間一個隨機數;

    • 字串處理:

      • length([s]):返回指定字串的長度;

      • sub(r,s,[t]):以r表示的模式來查詢t所表示的字元中的匹配的內容,並將其第一次出現替換為s所表示的內容;

      • gsub(r,s,[t]):以r表示的模式來查詢t所表示的字元中的匹配的內容,並將其所有出現均替換為s所表示的內容;

      • split(s,a[,r]):以r為分隔符切割字元s,並將切割後的結果儲存至a所表示的陣列中;

示例:

# 顯示/etc/passwd檔案中第二行到第十行對應的使用者名稱
awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd

# 顯示/etc/passwd檔案中 所有的使用者名稱及其對應的使用者型別
awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd

# 顯示所有預設使用Bash的使用者
awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd

# 一個簡單的測試NF用法的程式
awk '{if(NF>5) print $0}' /etc/fstab

# 列印所有以/dev/開頭的磁碟裝置 如果使用空間百分比大於20 則顯示裝置路徑
#(使用%作為分隔符 之後在用正常分隔符 最後一個欄位為已經使用的百分比) 
df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=20) print $1}'

# 顯示所有使用者ID號為偶數的使用者
awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd

# 陣列及迴圈體的練習 列印一週中前兩天的英文
awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'

# 顯示處於不同TCP狀態的網路連線數量
netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}'

# 顯示httpd 服務日誌中同一個IP的訪問次數
awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log

# 統計/etc/fstab檔案中每個檔案系統型別出現的次數;
awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab

# 統計指定檔案中每個單詞出現的次數;
awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab

# 統計每個IP建立的TCP連線數量 
netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'

4、寫一個指令碼,生成10個隨機數,並按從小到大進行排序(要求至少使用2種方法);

#!/bin/bash
# used for sort 

declare -a Random_array

bubble_sort(){
local a=($1)
local i
local j
local temp
for ((j=0;j<$[${#a[@]}-1];j++))do
    for ((i=0;i<$[${#a[@]}-1-$j];i++))do
        if [ ${a[$i]} -gt ${a[$[$i+1]]} ]; then
            temp=${a[$i]}
            a[$i]=${a[$(($i+1))]}
            a[$(($i+1))]=$temp
        fi
    done
done
echo ${a[@]}
}


select_sort(){
local a=($1)
local i
local j
local min
local temp
for ((i=0;i<$[${#a[@]}-1];i++))do
    min=$i
    for ((j=$[$i+1];j<${#a[@]};j++))do
        if [ ${a[$min]} -gt ${a[$j]} ]; then
            min=$j
        fi
    done
    if [ $min -ne $j ]; then
        temp=${a[$min]}
        a[$min]=${a[$i]}
        a[$i]=$temp
    fi    
done
echo ${a[@]}
}

for i in {0..9}; do
    Random_array[$i]=$RANDOM
done

echo "original array:"
echo ${Random_array[@]}
echo "sort with bubble sort algorithm:"
bubble_sort "${Random_array[*]}"
echo "sort with select sort algorithm:"
select_sort "${Random_array[*]}"

排序演算法執行效果示意

5、在每週二的凌晨1點5分執行指令碼/data/get_username.sh,並將指令碼的輸出至/tmp/get_username.log日誌檔案中;

需要修改配置檔案 /etc/crontab 在其中增加一行:

[[email protected] tmp]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
  5  1  *  *  2 root /data/get_username.sh >> /tmp/get_username.log

6、寫一個指令碼:如果某路徑不存在,則將其建立為目錄;否則顯示其存在,並顯示內容型別;

#!/bin/bash
# file type detection 


if [ $# -ne 1 ]; then
    echo "Only can receive one parameter."
    exit 2
fi
if [ -e $1 ]; then
    echo "$1 exists."
    file $1
else
    mkdir -p $1 >>/dev/null
    [ $? -eq 0 ] && echo "Directory $1 Created."
fi

檔案內容型別檢視指令碼

7、寫一個指令碼,列印9X9乘法表;

弄個遞迴的方法試試吧。

#!/bin/bash
# used for print multiplication tables

m_table(){
if [ $1 -eq 1 ]; then
    echo -e "1X1=1\t"
else
    m_table $[$1-1]
    for((i=1;i<=$1;i++))do
        echo -e -n "${i}X${1}=$[$i*$1]\t"
    done
    echo
fi
}

m_table 9

遞迴列印99乘法表執行效果示意

8、描述dns的工作流程,以及完整搭建一套dns主從伺服器,相關域名和ip可自行設定。

DNS工作流程

DNS,Domain Name Service, 基於C/S架構,使用套接字53/udp, 53/tcp來完成資料交換,是一種應用層協議。Linux下常用的伺服器端軟體為bind

DNS是用來完成域名和IP地址之間的轉換的。

DNS的查詢型別主要有兩種:遞迴查詢迭代查詢

一次完整的查詢請求經過的流程:

客戶端需要進行一次IP/域名解析,發請求;

首先檢視本機 hosts檔案 (對於Linux位於/etc/hosts 對於Windows位於%WINDOWS%/system32/drivers/etc/hosts)中是否存在解析記錄,如果沒有執行下一步;

檢視本地的DNS快取中是否存在解析記錄,如果沒有執行下一步;

向DNS配置中指向的第一個DNS伺服器請求獲取解析記錄

通過遞迴查詢是否存在解析記錄,如果沒有執行下一步;

檢視服務端的快取中是否存在解析記錄,如果沒有執行下一步;

訪問根伺服器,開始迭代查詢

搭建一套DNS主從伺服器

環境介紹:

主DNS伺服器: 192.168.11.100 CentOS 7.1 BIND 9.9.4

從DNS伺服器:192.168.11.101 CentOS 6.6 BIND 9.8.2rc1

測試客戶端: 192.168.11.102 CentOS7.1

FQDN為 test-dns.com.

>

主從伺服器安裝軟體環境:

yum install bind bind-libs bind-utils
#(對於生產環境 同時還應該安裝上 bind-chroot 以提高安全性)

主伺服器配置:

1) 修改主配置檔案 /etc/named.conf ,

# 監聽外部地址
    listen-on port 53 { 127.0.0.1; };   
->  listen-on port 53 { 192.168.11.100;127.0.0.1; };

# 允許外部地址訪問
    allow-query     { localhost; };
->  allow-query     { any; };

# 關閉dnssec
    dnssec-enable yes;
    dnssec-validation yes;
->  dnssec-enable no;
    dnssec-validation no;

2)在/etc/named.rfc1912.zones 檔案中定義區域

# 在檔案尾部加入如下的配置項
zone "test-dns.com" IN {
        type master;
        file "test-dns.com.zone";
};

3)建立並定義區域解析庫檔案:

touch /var/named/test-dns.com.zone
#逐項新增如下資源定義到解析庫檔案中
$TTL 86400
$ORIGIN test-dns.com.
@ IN SOA ns1.test-dns.com. admin.test-dns.com. (
        2016020601;
        1H
        5M
        7D
        1D )
        IN NS    ns1.test-dns.com.
        IN NS    ns2.test-dns.com.
        IN MX 10 mx1.test-dns.com.
        IN MX 20 mx2.test-dns.com.
ns1     IN A    192.168.11.100
ns2     IN A    192.168.11.101
mx1     IN A    192.168.11.100
mx2     IN A    192.168.11.100
www     IN A    192.168.11.100
mail    IN A    192.168.11.105
nas     IN A    192.168.11.128
*       IN A    192.168.11.100

#修改解析庫檔案許可權
chmod 640 test-dns.com.zone;
chown :named test-dns.com.zone

4)檢查配置檔案書寫正確與否

named-checkconf
named-checkzone "test-dns.com" test-dns.com.zone
rndc status

5)重讀配置檔案

systemctl reload named.service

wKioL1a2F8OArb10AABTU4_JtlQ284.png

6)本地測試

dig -t A nas.test-dns.com @192.168.11.100
dig -t A www.test-dns.com @192.168.11.100
dig -t A nas.test-dns.com @192.168.11.100

從伺服器配置:

1) 修改主配置檔案 /etc/named.conf ,

# 監聽外部地址
    listen-on port 53 { 127.0.0.1; };   
->  listen-on port 53 { 192.168.11.101;127.0.0.1; };

# 允許外部地址訪問
    allow-query     { localhost; };
->  allow-query     { any; };

# 關閉dnssec
    dnssec-enable yes;
    dnssec-validation yes;
->  dnssec-enable no;
    dnssec-validation no;

2)在/etc/named.rfc1912.zones 檔案中定義區域

# 在檔案尾部加入如下的配置項
zone "test-dns.com" IN {
        type slave;
        masters { 192.168.11.100; };
        file "slaves/test-dns.com.zone";
};

3)分別在主從伺服器上關閉防火牆:

# CentOS 7.1  
service firewalld stop
# CentOS 6.6
/etc/init.d/iptable stop
    

4)檢查並重讀配置檔案

named-checkconf
rndc reload
rndc status

5)本地測試

# 檢視日誌 確認同步是否正常
tail /var/log/messages

# 測試解析
dig -t A nas.test-dns.com @192.168.11.101
dig -t A www.test-dns.com @192.168.11.101
dig -t A nas.test-dns.com @192.168.11.101

6)測試“通知”機制是否執行正常

主伺服器端

# 手動修改主伺服器 區域檔案內容 /var/named/test-dns.com.zone

# 手動修改序列號 使其+1
# 過載配置
 rndc reload
# 檢視日誌 確認同步是否已經完成
 tail /var/log/messages
    
>

從伺服器端

# 檢視日誌 確認同步是否已經完成
 tail /var/log/messages
    

轉載於:https://blog.51cto.com/978543210/1740785