首頁 > 運維 > linux運維 > Linux系統基礎篇(二)

Linux系統基礎篇(二)

PHP中文网
發布: 2017-06-20 11:19:38
原創
2405 人瀏覽過
Linux磁碟管理
I/O Ports: I/O裝置位址;
一切皆檔案:
open(), read(), write(), close()
##區塊裝置:block,存取單位“區塊”,磁碟
字元裝置:char,存取單位“字元”,鍵盤
#裝置檔案:關聯至一個裝置驅動程序,進而能夠跟隨硬體裝置進行通訊;
##裝置號碼:
主設備號:major number, 識別設備類型
#次設備號:minor number, 標識同一類型下的不同設備
硬碟介面類型:
#並行:
IDE:133MB/ s
SCSI:640MB/s
#字串埠:
##SATA:6Gbps
SAS:6Gbps
USB: 480MB/s
rpm: rotations per minute
/dev/DEV_FILE
磁碟裝置的裝置檔案命名:
IDE: /dev/hd
#SCSI, SATA, SAS, USB: /dev/sd
不同裝置:a-z
/dev/sda, /dev/sdb, ...
##同一裝置上的不同分割區:1,2, ...
/dev/sda1, /dev/sda5
##機械式硬碟:
track:磁軌
#cylinder: 柱面
secotr: 區號
512bytes
如何分割區:
按柱面
0磁軌0磁區:512bytes
MBR: Master Boot Record
#446bytes: boot loader
64bytes:分割表
16bytes: 識別一個分割區
2bytes: 55AA
4個主分割區;
3主分割區+1擴充(N個邏輯分割區)
邏輯分割區
#分割區管理工具:fdisk, parted, sfdisk
fdisk:對於一塊硬碟來講,最多只能管理15分割區;
# fdisk -l [-u] [device...]
# fdisk device
子指令:管理功能
p: print, 顯示已有分割區;
n: new, 建立
d: delete, 刪除
w: write, 寫入磁碟並退出
q: quit, 放棄更新並退出
m: 取得幫助
l: 清單所分割 id
t: 調整分割區 id
#查看核心是否已經識別新的分割區:
# cat /proc/partations
通知核心重新讀取硬碟分割表:
partx -a /dev/DEVICE
-n M:N
kpartx -a /dev/DEVICE
-f: force
CentOS 5: 使用partprobe
#partprobe [/dev/DEVICE]
##################################################################################################### #
Linux檔案系統管理:
Linux檔案系統: ext2, ext3, ext4, xfs, btrfs, reiserfs, jfs, swap
#swap: 交換分割區
光碟:iso9660
#Windows:fat32, ntfs
#Unix : FFS, UFS, JFS2
網路檔案系統:NFS, CIFS
叢集檔案系統:GFS2, OCFS2
分散式檔案系統:ceph, 
moosefs, mogilefs, GlusterFS, Lustre
#根據是否支援"journal"功能:
日誌型檔系統: ext3, ext4, xfs, ...
非日誌型檔案系統: ext2, vfat
檔案系統的組成部分:
核心中的模組:ext4, xfs , vfat
使用者空間的管理工具:mkfs.ext4, mkfs.xfs, mkfs.vfat
Linux的虛擬檔案系統:VFS
建立檔案系統:
mkfs指令:
#(1) # mkfs.FS_TYPE /dev/DEVICE
#ext4
##xfs
##btrfs
vfat
#(2) # mkfs -t FS_TYPE /dev/DEVICE
#-L 'LABEL': 設定卷標
#mke2fs:ext系列檔案系統專用管理工具
-t {ext2|ext3|ext4}
#-b {1024|2048|4096}
#-L 'LABEL'
-j: 相當於-t ext3
mkfs.ext3 = mkfs -t ext3 = mke2fs -j = mke2fs -t ext3
-i #: 為資料空間中每多少個位元組建立一個inode;此大小不應該小於block的大小;
#-N #:為資料空間建立一個多少個inode;
-m #: 為管理人員預留的空間佔據的百分比;
-O FEATURE[,...]:啟用指定特性
#-O ^FEATURE:關閉指定特性
mkswap:建立交換分割區
mkswap [options] device
-L 'LABEL'
#前提:調整其分割區的ID為82;
其它常用工具:
blkid:塊裝置屬性資訊檢視
##blkid [OPTION]... [DEVICE]
-U UUID: 根據指定的UUID來尋找對應的設備
-L LABEL:根據指定的LABEL來尋找對應的設備
e2label:管理ext系列檔案系統的LABEL
# e2label DEVICE [LABEL]
tune2fs:重新設定ext系列檔案系統可調整參數的值
-l:檢視指定檔案系統超級區塊資訊; super block
-L 'LABEL':修改卷標
-m #:修預留給管理員的空間百分比
###-j: 將ext2升級為ext3#############-O: 檔案系統屬性啟用或停用########### #-o: 調整檔案系統的預設掛載選項############-U UUID:修改UUID號碼;################## dumpe2fs:############-h:查看超級區塊資訊##################檔案系統偵測:###
fsck: File System CheCk
#fsck.FS_TYPE
fsck -t FS_TYPE
-a: 自動修正錯誤
-r: 互動式修復錯誤
Note: FS_TYPE一定要與分割區上已經檔案型別相同;
#e2fsck:ext系列檔案專用的偵測修復工具
#-y:自動回答為yes; 
##-f:強制修復;
檔案系統管理:
將額外檔案系統與根檔案系統某現存的目錄建立起關聯關係,進而使得此目錄做為其它檔案存取入口的行為稱之為掛載;
解除此關聯關係的過程稱為卸載;
#把裝置關聯掛載點:Mount Point
mount
卸載時:可使用設備,也可以使用掛載點
umount
注意:掛載點下原有檔案在掛載完成後會被暫時隱藏;
#掛載方法:mount DEVICE MOUNT_POINT
#mount:透過檢視/etc/mtab檔案顯示目前系統已掛載的所有裝置
mount [-fnrsvw] [-t vfstype] [-o options] device dir
device:指明要掛載的裝置;
(1) 裝置檔案:例如/dev/sda5
#(2) 磁碟區號:-L 'LABEL', 例如-L 'MYDATA'
(3) UUID, -U 'UUID':例如-U '0c50523c-43f1-45e7-85c0-a126711d406e'
#( 4) 偽檔案系統名稱:proc, sysfs, devtmpfs, configfs
#dir:掛載點
##事先存在;建議使用空目錄;
進程正在使用中的裝置無法被卸載;
常用指令選項:
-t vsftype:指定要掛載的裝置上的檔案系統型別;
#-r: readonly,只讀掛載;
-w: read and write, 讀寫掛載;
-n: 不更新/etc/mtab; 
-a:自動掛載所有支援自動掛載的裝置;(定義在了/etc/fstab檔案中,且掛載選項中有「自動掛載」功能)
-L 'LABEL': 以卷標指定掛載設備;
-U 'UUID': 以UUID指定要掛載的設備;
#-U 'UUID': 以UUID指定要掛載的設備;
#-B, --bind: 綁定目錄到另一個目錄上;
#注意:查看核心追蹤到的已掛載的所有設備:cat /proc/mounts
-o options:(掛載檔案系統的選項)
async:非同步模式;
sync:同步模式;
atime/noatime:包含目錄和檔案;
#diratime/nodiratime:目錄的存取時間戳
#auto/noauto:是否支援自動掛載
exec/ noexec:是否支援將檔案系統上應用程式執行為進程
dev/nodev:是否支援在此檔案系統上使用裝置檔案;
######## ##suid/nosuid:############remount:重新掛載#############ro:############rw :############user/nouser:是否允許一般使用者掛載此裝置############acl:啟用此檔案系統上的acl功能### ###############注意:上述選項可多同時使用,彼此使用逗號分隔;###
 預設掛載選項:defaults
#  rw, suid, dev, exec, auto, nouser, and async
卸載指令:
## umount DEVICE
# umount MOUNT_POINT
查看正在存取指定檔案系統的進程:
## fuser -v MOUNT_POINT
終止所有在正存取指定的檔案系統的進程:
## fuser -km MOUNT_POINT
掛載交換分割區:
##:swapon
swapon [OPTION]... [DEVICE]
-a:啟動所有的交換分割區;
-p PRIORITY:指定優先權;
停用:swapoff [OPTION]... [DEVICE]
#記憶體空間使用狀態:
##free [OPTION]
-m: 以MB為單位
#-g: 以GB為單位
檔案系統空間佔用等資訊的檢視工具:
#df: 
-h: human- readable
-i:inodes instead of blocks
-P: 以Posix相容的格式輸出; 
#檢視某目錄總體空間佔用狀態:
du:
du [OPTION].. . DIR
-h: human-readable
#-s: summary
已講述指令:mount, umount, free, df, du, swapon, swapoff, fuser
檔案掛載的設定檔:/etc/fstab
每行定義一個要掛載的檔案系統;
要掛載的裝置或偽檔案系統掛載點檔案系統類型 掛載選項轉儲頻率 自我檢測順序
要掛載的裝置或偽檔案系統:
#裝置檔案、LABEL(LABEL="")、UUID( UUID="")、偽檔案系統名稱(proc, sysfs)
#掛載選項:
defaults
轉儲頻率:
#0:不做備份
#1:每天轉儲
2:每隔一天轉儲
#自檢順序:
0:不自我檢查
1:先自檢;一般只有rootfs才用1;
...
檔案系統上的其它概念:
Inode: Index Node, 索引節點
位址指標:
#直接指標:
間接指標:
三級指標:
#inode bitmap:對位元標識每個inode空閒與否的狀態資訊;
連結檔:
#硬連結:
不能夠對目錄進行;
不能跨分割區進行;
#指向同一個inode的多個不同路徑;建立檔案的硬連結即為inode建立新的引用路徑,因此會增加其引用計數;
#
符號連結:
可以對目錄進行;
可以跨分割區;
#指向的是另一個檔案的路徑;其大小為指向的路徑字串的長度;不增加或減少目標檔案inode的引用計數;
ln [-sv] SRC DEST

-s:symbolic link

-v: verbose
檔案管理操作對檔案的影響:
#檔案刪除:
##文件複製:
檔案移動:
 #1、建立一個20G的檔案系統,區塊大小為2048,文件系統ext4,磁碟區標為TEST,要求此分割區開機後自動掛載至/testing目錄,預設有acl掛載選項;(1) 建立20G分割區;
(2) 格式化:
mke2fs -t ext4 -b 2048 -L 'TEST' /dev/DEVICE
(3) 編輯/etc/fstab檔案
LABEL='TEST'
/testing
ext4
defaults,acl
0 0
#3、寫一個腳本,完成以下功能:
(1) 列出目前系統識別到的所有磁碟設備;
(2) 如磁碟數量為1,則顯示其空間使用資訊;
否則,則顯示最後一個磁碟上的空間使用資訊;
if [ $disks -eq 1 ]; then 
#fdisk -l /dev/[hs]da
else 
fdisk -l $(fdisk -l /dev /[sh]d[a-z] | grep -o "^Disk /dev/[sh]d[a-]" | tail -1 | cut -d' ' -f2)
#fi
bash腳本程式設計使用者互動:
read [option]... [name . ..]
-p 'PROMPT'
-t TIMEOUT
##bash -n /path/to/some_script
偵測腳本中的語法錯誤
bash - x /path/to/some_script
偵錯執行
範例:
#!/bin/bash
# Version: 0.0.1
# Author: MaEdu
## Description: read testing
#read -p "Enter a disk special file: " diskfile
#[ -z "$diskfile" ] && echo "Fool" && exit 1
if fdisk -l | grep "^Disk $diskfile" &> /dev/null; then
   fdisk -l $diskfile
else
#    echo " Wrong disk special file."
   exit 2
fi
RAID: 
#Redundant Arrays of Inexpensive Disks
                   Independent
Berkeley: A case for Redundent Arrays of Inexpensive Disks RAID
##########提升IO能力:###########磁碟並行讀寫;##### #######提高耐用性;############磁碟冗餘來實現##################等級:多區塊磁碟組織在一起的工作方式有所不同;###
RAID實作的方式:
外接式磁碟陣列:透過擴充卡提供適配能力
內接式RAID:主機板整合RAID控制器
Software RAID:
RAID-0:0, 條帶卷,strip; 
#RAID-1: 1, 鏡像卷,mirror;
#RAID-2
..
#RAID-5:
RAID-6
RAID10
#RAID01
RAID-0 : 
讀取、寫入效能提升;
#可用空間:N*min(S1,S2,...)
無容錯能力
最少磁碟數:2, 2+
RAID -1:
讀取效能提升、寫入效能略有下降;
#可用空間:1*min(S1,S2,.. .)
有冗餘能力
最少磁碟數:2, 2+
RAID-4:
1101, 0110, 1011
RAID-5:
讀取、寫入效能提升
可用空間:(N-1)*min(S1,S2,...)
#有容錯能力:1區塊磁碟
最少磁碟數:3, 3+
RAID-6:
讀、寫入效能提升
#可用空間:(N-2)*min(S1, S2,...)
有容錯能力:2區塊磁碟
#最少磁碟數:4, 4+
#RAID-10:
讀取、寫入效能提升
可用空間:N*min(S1,S2,...)/2
有容錯能力:每組鏡像最多只能壞一塊;
最少磁碟數:4, 4+
RAID-01:
RAID-50、RAID7
JBOD:Just a Bunch Of Disks
功能:將多區塊磁碟的空間合併一個大的連續空間使用;
可用空間:sum(S1,S2,... )
常用層級:RAID-0, RAID-1, RAID-5, RAID-10, RAID-50, JBOD
#實作方式:
硬體實作方式
軟體實作方式 
#CentOS 6上的軟體RAID的實作:
#結合核心中的md(multi devices)
#mdadm:模式化的工具
指令的語法格式:mdadm [mode] [options]
支援的RAID等級:LINEAR, RAID0, RAID1, RAID4, RAID5, RAID6, RAID10; 
#模式:
建立:-C
組裝: -A
監控: -F
管理:-f, -r, -a
#: /dev/md
## #######: 任意區塊裝置########################-C: 建立模式###
-n #: 使用#個區塊裝置來建立此RAID;
#-l #:指明要建立的RAID的等級;
-a {yes|no}:自動建立目標RAID裝置的裝置檔案;
-c CHUNK_SIZE: 指明區塊大小;
-x #: 指明空閒碟的數量;
例如:建立一個10G可用空間的RAID5;
-D:顯示raid的詳細資訊;
#mdadm -D /dev/md
#管理模式:
-f: 標記指定磁碟為損壞;
-a : 新增磁碟
-r: 移除磁碟
觀察md的狀態:
cat /proc/mdstat
# 停止md裝置:
mdadm -S /dev /md
#watch指令:
-n #: 刷新間隔,單位是秒;
watch -n# 'COMMAND'
#LVM2:
LVM: Logical Volume Manager, Version: 2
dm: device mapper,將一個或多個底層區塊設備組織成一個邏輯設備的模組;
/dev/dm-
#/dev/mapper/VG_NAME -LV_NAME
/dev/mapper/vol0-root
/dev/VG_NAME/LV_NAME
#/dev/vol0/root
pv管理工具:
pvs:簡要pv資訊顯示
pvdisplay:顯示pv的詳細資訊
#pvcreate /dev/DEVICE: 建立pv
#vg管理工具:
vgs
vgdisplay
vgcreate  [-s #[kKmMgGtTpPeE]] VolumeGroupName  PhysicalDevicePath [PhysicalDevicePath...]
vgextend  VolumeGPhysro...]
vgextend Pathup PathconroperoPhysroPhysow;
vgreduce  VolumeGroupName  PhysicalDevicePath [PhysicalDevicePath...]
先做pvmove
先做pvmove
##先做pvmove
#vgremove
lv管理工具:
lvs
##lvdisplay
lvcreate -L #[mMgGtT] -n NAME VolumeGroup
lvremove /dev /VG_NAME/LV_NAME
擴充邏輯磁碟區:
# lvextend -L [+]#[mMgGtT] / dev/VG_NAME/LV_NAME
# resize2fs /dev/VG_NAME/LV_NAME
#縮減邏輯磁碟區:
# umount /dev/VG_NAME/LV_NAME
## e2fsck -f /dev/VG_NAME/LV_NAME
## resize2fs /dev/VG_NAME/LV_NAME #[mMgGtT]
# lvreduce -L [-]#[mMgGtT] /dev/VG_NAME/LV_NAME
## mount
############快照:snapshot############lvcreate -L #[mMgGtT] -p r -s -n snapshot_lv_name original_lv_name############檔案系統掛載使用:############掛載光碟裝置:############ #光碟裝置檔案:############IDE: /dev/hdc#############SATA: /dev/sr0#################################################################################################################################################### #########符號連結檔:############/dev/cdrom###
/dev/cdrw
/dev/dvd
/dev/dvdrw
#mount -r /dev/cdrom /media/cdrom
umount /dev/cdrom
dd指令:convert and copy a file
#用法:
dd if=/PATH/FROM /SRC of=/PATH/TO/DEST 
bs=#:block size, 複製單元大小;
count=#:複製多少個bs;
磁碟拷貝:
dd if=/dev/sda of=/dev/sdb
備份MBR
dd if=/dev/sda of=/tmp/mbr.bak bs=512 count=1
破壞MBR中的bootloader:
dd if=/dev/zero of=/dev /sda bs=256 count=1
#兩個特殊裝置:
/dev/null: 資料黑洞;
/dev/zero:吐零機;
btrfs檔案系統:
技術預覽版
#Btrfs (B-tree, Butter FS, Better FS ), GPL, Oracle, 2007, CoW; 
#ext3/ext4, xfs
核心特性:
多實體磁碟區支援:btrfs可由多個底層實體磁碟區組成;支援RAID,以連線「新增」、「移除」,「修改」;
寫時複製更新機制(CoW):複製、更新及替換指針,而非「就地」更新;
資料及元資料校驗碼:checksum
子磁碟區:sub_volume
快照:支援快照的快照;
透明壓縮:
檔案系統建立:
mkfs.btrfs
##-L 'LABEL'
-d : raid0, raid1, raid5, raid6, raid10, single
#-m
-O
#-O list-all : 列出支援的所有feature;
屬性檢視:
##btrfs filesystem show 
##掛載檔案系統:
mount -t btrfs /dev/sdb MOUNT_POINT
透明壓縮機制:
mount -o compress={lzo|zlib} DEVICE MOUNT_POINT
子指令:filesystem, device, balance, subvolume
#壓縮、解壓縮及歸檔工具
compress/uncompress: .Z
gzip/gunzip: .gz
bzip2/bunzip2: .bz2
xz/unxz: .xz
#zip/unzip
tar, cpio
#1、gzip/gunzip
gzip [OPTION]... FILE ...
-d: 解壓縮,相當於gunzip
-c: 將結果輸出至標準輸出;
-#:1-9,指定壓縮比;
zcat:不明確展開的前提下查看文字檔案內容;
2、bzip2/bunzip2/bzcat
bzip2 [OPTION]... FILE ...
-k: keep, 保留原始檔案;
#######-d:解壓縮###
-#:1-9,壓縮比,預設為6;
bzcat:不明確展開的前提下檢視文字檔案內容;
3、xz/unxz/xzcat
bzip2 [ OPTION]... FILE ...
-k: keep, 保留原始檔案;
##-d:解壓縮
-#:1-9,壓縮比,預設為6;
xzcat: 不明確展開的前提下查看文字檔內容;
4、tar
##tar [OPTION].. . 
(1) 建立檔案
tar -c -f /PATH/TO/SOMEFILE.tar FILE ...
tar -cf /PATH/TO/SOMEFILE.tar FILE...
##(2) 查看歸檔檔案中的檔案清單
tar -t -f /PATH/TO/SOMEFILE.tar
#(3) 展開歸檔
tar -x -f /PATH/TO/SOMEFILE.tar
tar -x -f /PATH/TO/SOMEFILE.tar -C /PATH/TO/DIR
結合壓縮工具實作:歸檔並壓縮
-j: bzip2, -z: gzip, -J: xz
bash腳本程式設計:
if語句、bash -n、bash -x
CONDITION:
bash指令:
用指令的執行狀態結果;
##成功:true
失敗:flase
#成功或失敗的意義:取決於用到的指令;
單一分支:
#if CONDITION; then
##if-true
fi
雙分支:
if CONDITION; then
if-true
else
if-false
fi
多分支:
if CONDITION1; then
##if-true
elif CONDITION2; then
if-ture 
#elif CONDITION3; then
if-ture 
#...
##esle
all-false
fi
#逐條件判斷,第一次遇為「真」條件時,執行其分支,而後結束;
範例:使用者鍵入檔案路徑,腳本來判斷檔案類型;
#!/bin/bash
##read -p "Enter a file path: " filename
if [ -z "$filename" ]; then
   echo "Usage: Enter a file path."
   exit 2
fi
if [ ! -e $filename ]; then
   echo "No such file."
   exit 3
fi
if [ -f $filename ]; then
   echo "A common file."
elif [ -d $filename ]; then
   echo "A directory."
elif [ -L $filename ]; then
   echo "A symbolic file."
##else
#    echo "Other type."
fi
#注意:if語句可嵌套;
迴圈:for, while, until
循環體:要執行的程式碼;可能要執行n遍;
進入條件:
退出條件:
for迴圈:
for 變數名稱 in 列表; do
迴圈體
done
執行機制:
依序將清單中的元素賦值給「變數名”; 每次賦值後即執行一次循環體; 直到列表中的元素耗盡,循環結束; 
#範例:新增10個使用者, user1- user10;密碼同用戶名;
#!/bin/bash
#if [ ! $UID -eq 0 ]; then
   echo "Only root."
   exit 1
fi
for i in {1..10}; do
#    if id user$i &> /dev/null; then
 echo "user$i exists."
#    else
   
useradd user$i
if [ $? -eq 0 ]; then
   echo "user$i" | passwd --stdin user$i &> /dev/null
           echo "Adduser$i finished ."
       fi
   fi
done
##done
列表產生方式:
(1) 直接給出列表;
(2) 整數列表:
(a) {start..end}
#(b) $(seq [start [step]] end) 
(3) 傳回清單的指令;
#$(COMMAND)
(4) glob
(b) 變數引用;
#$@, $*
### #########範例:判斷某路徑下所有檔案的型別#############!/bin/bash############# ##################for file in $(ls /var); do############    if [ -f /var/$file ]; then############echo "Common file."#############    elif [ -L /var/$file ]; then##### #######echo "Symbolic file."############    elif [ -d /var/$file ]; then#############echo "Directory."############    else############echo "Other type."############    fi## ##########done#########################範例:###
#!/bin/bash
##declare -i estab=0
declare -i listen=0
#declare -i other=0
for state in $( netstat -tan | grep "^tcp\>" | awk '{print $NF}'); do
##    if [ "$state" == ' ESTABLISHED' ]; then
let estab++
   elif [ "$state" == 'LISTEN' ]; then
#let listen++
   else
let other++
   fi
done
echo "ESTABLISHED: $estab"
#echo "LISTEN: $listen"
echo "Unkown: $other"
##/ etc/rc.d/rc3.d目錄下分別有多個以K開頭和以S開頭的文件;
分別讀取每個文件,以K開頭的文件輸出為檔案加stop,以S開頭的檔案輸出為檔案名稱加start;
「K34filename stop」
「S66filename start」
Linux套件管理:
##API:Application Programming Interface
POSIX:Portable OS
程式原始碼--> 預處理--> 編譯--> 彙編--> 連結 
# 靜態編譯:
共享編譯:.so
ABI:Application 臉層級的虛擬化:
Linux: WINE
#Windows: Cywin
##系統級開發
C
C++
應用程式級開發
java
Python
#php
perl
ruby
二進位應用程式的組成部分:
二進位文件、庫檔案、設定檔、幫助文件
套件管理器:
debian:deb, dpt
redhat: rpm, rpm
#rpm: Redhat Package Manager
##RPM is Package Manager
Gentoo
#Archlinux
原始碼:name-VERSION.tar.gz
#VERSION: major.minor.release
#rpm套件命名方式:
name-VERSION-release.arch.rpm
VERSION: major.minor.release
release.arch:
release:release.OS
##zlib- 1.2.7-13.el7.i686.rpm
#常見的arch:
x86: i386, i486 , i586, i686
x86_64: x64, x86_64, amd64
#######powerpc: ppc#############跟平台無關:noarch##########
testapp: 拆包
testapp-VERSION-ARCH.rpm: 主套件
testapp-devel -VERSION-ARCH.rpm:支包
testapp-testing-VERSION-ARHC.rpm
# 包之間:存在依賴關係
X, Y, Z
yum:rpm套件管理器的前端工具;
apt-get:deb套件管理器前端工具;
#zypper: suse上的rpm前端管理工具;
dnf: Fedora 22+ rpm套件管理器前端管理工具;
#檢視二進位程式所依賴的程式庫檔案:
ldd /PATH/TO/BINARY_FILE
管理並檢視本機裝載的程式庫檔案:
#ldconfig 
/sbin/ldconfig -p: 顯示本機已快取的所有可用程式庫檔案名稱及檔案路徑對應關係;
#設定檔為:/etc/ld.so.conf, /etc/ld.so.conf.d/*.conf
##快取檔案:/etc/ld.so.cache
#套件管理:
功能:將編譯好的應用程式的各組成文件打包一個或幾個程序包文件,從而方便快捷地實現程序包的安裝、卸載、查詢、升級和校驗等管理操作;
1、程式的組成組成清單(每個套件獨有)
檔案清單
安裝或解除安裝時執行的腳本
2、資料庫(公共)
#套件名稱及版本
##依賴關係;
功能說明;
安裝產生的各檔案的檔案路徑及校驗碼資訊;
安裝產生的各檔案的檔案路徑及校驗碼資訊;
#管理套件的方式:
使用套件管理器:rpm
##使用前端工具:yum, dnf
取得套件的路徑:
(1) 系統發版的光碟或官方的伺服器;
CentOS映像:
(2) 專案官方網站
##(3) 第三方組織:
Fedora-EPEL
搜尋引擎:
##(4) 自己製作
建議:檢查其合法性
來源合法性;
#程式包的完整性;
#CentOS系統上rpm指令管理套件:
安裝、解除安裝、升級、查詢、校驗、資料庫維護
安裝:
rpm {-i|--install} [install-options] PACKAGE_FILE ...
-v: verbose
-vv: 
#-h: 以#顯示套件管理執行進度;每個#表示2%的進度
###rpm -ivh PACKAGE_FILE ...#################[install- options]############--test: 測試安裝,但不真正執行安裝程序;dry run模式;############--nodeps:忽略依賴關係;############--replacepkgs: 重新安裝;##################--nosignature: 不檢查來源合法性;# ##
--nodigest:不檢查套件完整性;
#--noscipts:不執行套件腳本片段;
%pre: 安裝前腳本; --nopre
#%post: 安裝後腳本; --nopost
%preun: 卸載前腳本; --nopreun
%postun: 卸載後腳本;  --nopostun
#升級:
rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...
rpm { -F|--freshen} [install-options] PACKAGE_FILE ...
#upgrage:安裝有舊版程式包,則「升級」;如果不存在舊版程式包,則「安裝」;
freeshen:安裝有舊版程式包,則「升級」;如果不存在舊版程式包,則不執行升級操作;
rpm -Uvh PACKAGE_FILE ...
rpm -Fvh PACKAGE_FILE ...
#--oldpackage:降級;
--force: 強制升級;
注意:(1) 不要對核心做升級操作;Linux支援多核心版本並存,因此,對直接安裝新版本核心;
 (2) 如果原程式包的配置檔案安裝後曾被修改,長級時,新版本的提供的同一個設定檔並不會直接覆寫舊版的設定文件,而把新版本的檔案重新命名(FILENAME.rpmnew)後保留;
#查詢:
rpm {-q|--query} [select-options] [query-options]
[select-options]
#-a: 所有套件
-f: 查看指定的檔案由哪個套件安裝產生
#-p /PATH/TO/PACKAGE_FILE:針對尚未安裝的套件檔案做查詢操作;
--whatprovides CAPABILITY:查詢指定的CAPABILITY由哪個套件提供;
--whatrequires CAPABILITY:查詢指定的CAPABILITY被哪個套件所依賴;
[query-options]
--changelog :查詢rpm套件的changlog
-c: 查詢程式的設定檔
-d: 查詢程式的文件
-i: information
-l: 查看指定的套件安裝後產生的所有檔案;
## --scripts:套件自帶的腳本片段
-R: 查詢指定的套件所依賴的CAPABILITY;
##-- provides: 列出指定程式包所提供的CAPABILITY;
#用法:
-qi PACKAGE, -qf FILE, -qc PACKAGE, -ql PACKAGE, -qd PACKAGE
-qpi PACKAGE_FILE, -qpl PACKAGE_FILE, ...
-qa
卸載:
##########rpm {-e|--erase} [--allmatches] [--nodeps ] [--noscripts]######           [--notriggers] [--test] PACKAGE_NAME ...#################    校驗:### ###    ######rpm {-V|--verify} [select-options] [verify-options]#################       S file Size differs ############       M Mode differs (includes permissions and file type)############       5 digest (formerly MD5 sum) differs######## ####       D Device major/minor number mismatch############       L readLink(2) path mismatch############  ########       G Group ownership differs###
      T mTime differs
#       P caPabilities differ
套件來源合法性驗正及完整性驗正:
完整性驗正:SHA256
來源合法性驗正:RSA
#公鑰加密:
#對稱加密:加密、解密使用相同金鑰;
#非對稱加密:金鑰是成對兒的,
public key: 公鑰,公開所有人
#secret key: 私密金鑰, 不能公開
# 匯入所需公鑰:
rpm --import /PATH/FROM/GPG-PUBKEY-FILE
#CentOS 7發行版光碟提供的金鑰檔案:RPM-GPG-KEY -CentOS-7
#資料庫重建:
rpm {--initdb|--rebuilddb}
initdb: 初始化
如果事先不存在資料庫,則新建之;否則,不執行任何操作;
rebuilddb:重建
無論目前存在與否,直接重新建立資料庫;
回顧:Linux套件管理的實作、rpm包管理器
rpm指令實作程式管理:
##安裝:-ivh , --nodeps, --replacepkgs
卸載:-e, --nodeps
##升級:-Uvh, -Fvh, -- nodeps, --oldpackage
查詢:-q, -qa, -qf, -qi, -qd, -qc, -q --scripts, -q --changlog, - q --provides, -q --requires
#校驗:-V
##匯入GPG金鑰: --import, -K, --nodigest, --nosignature
資料庫重建:--initdb, --rebuilddb
Linux程序套件管理(2)
CentOS: yum, dnf
URL: ftp: //172.16.0.1/pub/
#YUM: yellow dog, Yellowdog Update Modifier
#yum repository: yum repo
#儲存了眾多rpm包,以及套件的相關的元資料檔案(放置於特定目錄下:repodata);
檔案伺服器:
#ftp://
http: //
nfs://
file:///
##yum用戶端:
設定檔:
#/etc/yum.conf:為所有倉庫提供公共設定
/etc/yum.repos.d/*.repo:為倉庫的指向提供配置
倉庫指向的定義:
[repositoryID]
#name=Some name for this repository
baseurl=url ://path/to/repository/
enabled={1|0}
gpgcheck={1|0}
gpgkey=URL
enablegroups={1|0}
failovermethod={roundrobin|priority}
預設為:roundrobin,意為隨機挑選;
#cost=
##預設為1000
教室裡的yum來源:http://172.16.0.1/cobbler/ks_mirror/CentOS-6.6-x86_64/
CentOS 6.6 X84_64 epel: http://172.16.0.1/fedora-epel/6/x86_64/
# yum指令的用法:
yum [選項] [指令] [套件...]
       指令是下列之一:
        * install package1 [ package2 ] [...]
        * 更新 [package1] [package2] [...]
        * 更新至 [package1] [package2] [...]
          * 檢查更新
        * 升級[package1] [package2] [...]
        * 升級至[package1] [package2
        * 升級至[package1] [package2] [
# * 分發同步[package1] [package2] [...]
##        * 刪除 |擦除 package1 [package2] [...]
##        * 清單 [...]
        * 資訊 [...]
       * 提供 |提供功能 1 [功能 2] [...]
        * 乾淨 [ 包 | ]元數據 |過期緩存 | rpmdb |插件 |完整]
        * makecache
        * groupinstall group1 [group2] [...]
        * groupupdate 1 [
##        * groupupdate 1 [
##        * groupupdate 1 [112] [#group> * 群組清單[隱藏] [群組簡單] [...]
##        * groupremove group1 [group2] [...]
##        * groupinfo group1 [...]
#        * groupinfo group1 [...]
* 搜尋string1 [string2] [...]
##        * shell [檔案名稱]
        *resolvedep dep1 [dep2] [...]# ##    *resolvedep   rpmfile1 [rpmfile2 ] [...]
           (僅因遺留原因維護- 使用安裝)
        * localupdate rpmfile1 [rpmfile2] [基於遺留原因維護僅- 使用更新)
        * 重新安裝package1 [package2] [...]
        * 降級package1 [package2] [...]
        * 刪除package1 [package2 ] [...]
        * 重新處理 [全部|啟用|停用]
        * 版本 [ 全部|啟用|停用]
#        * 版本 [ 全部 | 停用]已安裝 |可用 |組-* |沒有組* |群組列表 | groupinfo ]
        * 歷史記錄[info|list|packages-list|packages-info|summary|addon-info|redo|undo|rollback|new|sync|stats]
##     |rollback|new|sync|stats]
##         
        * help [command]
   顯示倉庫清單:
   
repolist [all|enabled|disabled]
#disabled
  顯示套件:   
list
   
# yum list [all | glob_exp1] [glob_exp2] [...]##   
# yum list {可用|已安裝|更新} [glob_exp1] [...]
#   安裝程式套件:
   
安裝package1 [package2] [...]
     
#重新安裝package1 [package2] ] [...] (重新安裝)
## 升級套件:
update [package1] [package2] [. ..]
     
downgrade package1 [package2] [...] (降級)
    檢查是否可以升級:
    check-update
    卸載套件:
    #remove |擦除package1 [package2] [...]
##   查看程式包資訊:
   
info [...]
    查看指定的功能(可以是某個檔案)是由哪個程式包所提供的:
   
#提供 | Whatprovides feature1 [feature2] [...]
##    清理本機伺服器:
   
clean [packages |元數據 |過期緩存 | rpmdb |插件 | all ]
    建置快取:
   
makecache
##    搜尋:
search string1 [string2] [...]
   
以指定的關鍵字搜尋程式包名及摘要資訊;
    查看指定套件所依賴的capabilities:
    deplist package1 [package2] [...]
    查看yum事務歷史:
    history [info|list|packages-list|packages-info|summary|addon-info|redo|undo|rollback|new|sync|stats]
#    安裝與升級本地套件:
* localinstall rpmfile1 [rpmfile2] [...]
           (maintained for legacy reasons only -      (maintained for legacy reasons only - ” install)
        * localupdate rpmfile1 [rpmfile2] [...]
           (maintained for legacy reasons only - 套件相關指令:
        * groupinstall group1 [group2] [...]
        * groupupdate group1 [group2] [...]
# groupwildcard] [...]
        * groupremove group1 [group2] [...]
        * groupinfo group1 [...]
如何使用光碟當作本地yum倉庫:
   
(1) 掛載光碟至某目錄,例如/media/cdrom
   
# mount -r -t iso9660 /dev/cdrom /media/cdrom
   
(2) 建立設定檔
   
[CentOS7]
#   
name=##   
#baseurl=   
gpgcheck=   
# enabled=
    yum的命令列選項:   
--nogpgcheck:禁止進行gpg check;
   
#-y: 自動回答為「yes」;##   
#-q:靜默模式;
   
--disablerepo=repoidglob:暫時停用此處指定的repo;
   
--enablerepo=repoidglob:暫時啟用此處指定的repo;
   
--noplugins:停用所有外掛程式;
    yum的repo設定檔中可用的變數:
   
$releasever: 目前OS的發行版的主版本號;
   
$arch: 平台;
   
$basearch:基礎平台;
   
$YUM0- $YUM9
   
$releasever/$basearch/os
    建立yum倉庫:
   
createrepo [options]
    套件編譯安裝:
   
testapp-VERSION-release.src. rpm --> 安裝後,使用rpmbuild指令製作成二進位格式的rpm包,而後再安裝;
   
原始碼--> 預處理- -> 編譯(gcc) --> 彙編--> 連結--> 執行
   
原始程式碼組織格式:
   
多重檔案:檔案中的程式碼之間,很可能存在跨檔案依賴關係;
   
C、C++: make (configure --> Makefile.in --> makefile)
   
#java: maven
##    C程式碼編譯安裝三步驟:
   
./configure:
    (1) 透過選項傳遞參數,指定啟用功能、安裝路徑等;執行時會參考使用者的指定以及Makefile.in檔案產生makefile;
    (2) 檢查所依賴的外在環境;
    #make:
    根據makefile文件,建立應用程式;
    make install
    開發工具:
    autoconf: 產生configure腳本
    automake:產生Makefile.in
    #建議:安裝前檢視INSTALL,README
#    開源程式原始碼的取得:
    開放原始程式網站:
    apache.org (ASF)
    mariadb.org
#    ...
    程式碼託管:
    SourceForge
    Github.com
    #code.google.com
#   
#code.google.com
#   
c/c++: gcc (GNU C Complier)
   
編譯C原始碼:
#前提:提供開發工具及開發環境
   
#開發工具:make, gcc等
   
# 開發環境:開發函式庫,頭檔
   
glibc:標準函式庫
   
透過「套件組」提供開發元件
   
CentOS 6: "Development Tools", "Server Platform Development",
   
#第一步:configure腳本
   
選項:指定安裝位置、指定啟用的功能
#   
--help: 取得其支援使用的選項
   
選項分類:
##    #安裝路徑設定:
    --prefix=/PATH/TO/SOMEWHERE:指定預設安裝位置;預設為/usr/local/
   
--sysconfdir=/PATH/TO/SOMEWHERE:設定檔安裝位置;
#   
System types:
#    Optional Features: 可選功能
#    --disable -FEATURE
   
##--enable-FEATURE[=ARG]
   
Optional Packages: 選用套件
   
--with-PACKAGE[=ARG]
   
--without-PACKAGE
#   
第二步:make
   
第三個步驟:make install
##   
安裝後的設定:   
(1) 匯出二進位程式目錄至PATH環境變數;   
#編輯檔案/etc/profile.d /NAME.sh   
export PATH=/PATH/TO/BIN:$PATH
##   
(2) 匯出庫檔案路徑
    ##編輯/etc/ld.so.conf.d/NAME.conf
    新增新的庫檔案所在目錄至此文件中;
    讓系統重新產生快取:
    ldconfig [-v]
    (3) 匯出頭檔
    #以連結為基礎的方式實作:
##   
ln - sv 
   
(4) 匯出說明手冊
   
編輯/etc/man.config檔案
#   
新增一個MANPATH
#
 Linux網路屬性管理
 「區域網路:乙太網路,令牌環網
 Ethernet: CSMA/CD
 衝突域
  #廣播域 
 MAC:Media Access Control
 48bits: 
#24bits:
 24bits:
##IP: Internet Protocol
Routing protocol
 
Routed protocol
 
OSI, TCP/IP
#tcp/ip分層:
 
application layer
 
transport layer
 
#internet layer
 
datalink layer
 
pysical layer
## 
傳輸層協議: 
tcp, udp, sctp
 
##網路層協定:
 
ip
 
ip協定:
IPv4 位址分類:
 
點分十進位:0-255
 
0000 0000 - 1111 1111
 
# 0.0.0.0-255.255.255.255
 A類別:
 #0 000 0000 - 0 111 1111: 1 127
 網路數:126, 127
 每個網路中的主機數:2^24-2
預設子網路遮罩:255.0.0.0 
私人網路位址:10.0.0.0/8
 
B類別: 
10 00 0000 - 10 11 1111:128-191 
網路數:2^14
 每個網路中的主機數:2^16-2
 預設子網路遮罩:255.255.0.0
#私人網路位址:172.16.0.0/16-172.31.0.0/16
 #C類別:
 110 0 0000 - 110 1 1111: 192-223
 網路數:2^21
 
每個網路中的主機數:2^8-2 
預設子網路遮罩:255.255.255.0 
私人網路位址:192.168.0.0/24 -192.168.255.0/24
 D類別:群播
 1110 0000 - 1110 1111: 224-239
 
E類別: 
240-255
 
子網路遮罩: 
###172.16.100.100/255.255.0.0, 172.17.1.1############ ######跨網路通訊:路由###### ######主機路由###### ######網路路由###### ######預設路由#### ###############將Linux主機連結到網路:############IP/mask########## #路由:預設閘道############DNS伺服器#############主DNS伺服器############次DNS伺服器# ###########第三DNS伺服器###################設定方式:############靜態指定:###
ifcfg: ifconfig, route, netstat
ip: object {link, addr, route}, ss, tc
#設定檔
system-config-network-tui (setup)
CentOS 7:
nmcli, nmtui
動態分配:
#DHCP: Dynamic Host Configuration Protocol
設定網路介面:
介面命名方式:
CentOS 6: 
乙太網路:eth[0,1,2,...]
ppp:ppp[0,1,2,...]
ifconfig指令
ifconfig [interface]
## ifconfig -a
# ifconfig IFACE [up|down]
       
ifconfig interface [aftype] options | address ...
#   
# ifconfig IFACE IP/mask [up]
       # ifconfig IFACE IP netmask MASK
      
      
      
      
 立即生效;
       
#啟用混雜模式:[-]promisc
##       
route指令指令
##       路由管理指令
       檢視:route -n
       ##       
route add  [-net|-host]  target [netmask Nm] [gw Gw] [[dev] If]
    #  
 # #目標:192.168.1.3  閘道:172.16.0.1
       
~]# route add -host 192.168.1.3 gw##172.16.0.1 192.168.1.3 gw
2.16.0.1 dev #       目標:192.168.0.0 閘道:172.16.0.1
       
~]# route add -net 192.168.0.##~]# route add -net 192.168.0.##~20515. eth0
       ~]# route add -net 192.168.0.0/24 gw 1​​72.16.0.1 dev eth0
#    閘道:172.16.0.1       
~]# route add -net 0.0.0.0 netmask 0.0.0.0 gw 1​​72.16.0.1# > route add default gw 1​​72.16.0.1
       
#刪除:route del
       
route del
       
route del##-net|-host] target [gw Gw] [netmask Nm] [[dev] If]
       
目標:192.168.1.3  閘道:172.16.0.192.168.1.3  閘道:172.16.0.1
#~]# route del -host 192.168.1.3
       目標:192.168.0.0 閘道:172.16.0.#目標:192.168.0.0 閘道:172.16.0.11
#   
##~]# route del -net 192.168.0.0 netmask 255.255.255.0
##       
##/etc/resolv.conf
       
nameserver DNS_SERVER_IP1
       
nameserver DNS_SERVER_IP2
##   #1 
       
正解:FQDN-->IP######       ####### dig -t A FQDN#############################################################################################################################################################################################################' ####### host -t A FQDN######       ######反解:IP-->FQDN###
       # dig -x IP
       # host -t PTR IP
       
#'
FQDN: www.madu.com.
       
netstat指令:
       ##netstat指令:
##       
##netstat - Print##netstat - Print##netstatd network connections, routing tables, interface statistics, masquerade connections, and multicast memberships
        [--tcp|-t] [--udp|-u] [--raw|-w] [--listening|-l] [--all|-a] [--numeric|-n] [- -extend|-e[--extend|-e]]  [--program|-p]
       
-t: tcp協定相關       
##-u: udp協定相關        
#-w: raw socket相關
       -l: 處於監聽狀態
#'
-a: 所有狀態
       
-n: 以數字顯示IP與連接埠;
       
-e:擴充格式格式
       
-p: 相關行程及PID
       
常用組合:
       
常用組合:##    #   
#-tan, -uan, -tnl, -unl
##       顯示路由表:
       netstat {##netstat --route|-r} [--numeric|-n]
##       
-r: 顯示核心路由表
       
-n: 數字
#       -n: 數字格式
       
#顯示介面統計資料:
       #netstat  {--interfaces|-I|-i} [iface ] [--all|-a] [--extend|-e] [--program|-p] [--numeric|-n] 
       # netstat -i
       # netstat -I IFACE  
       
總結:ifcfg家庭命令配置       
ifconfig/route/netstat#       
ifup/ifdown
####Linux網路設定(2)#### ####################設定Linux網路屬性:ip指令##################ip指令:## ##########ip - show / manipulate routing, devices, policy routing and tunnels###################ip [ OPTIONS ] OBJECT { COMMAND | help }##################OBJECT := { link | addr | route }##################link OBJECT: ############ip link - network device configuration##################set############dev IFACE############可設定屬性:############up and down:啟動或停用指定介面;########### #######show############[dev IFACE]:指定介面#############[up]:僅顯示處於啟動狀態的接口##################ip address - protocol address management#################ip addr { add | del } IFADDR dev STRING############[label LABEL]:在新增位址時指明網路卡別名############[scope {global|link|host}]:指明作用網域############global: 全域可用;############link: 僅連結可用;###########host:本機可用;###
[broadcast ADDRESS]:指明廣播位址
#ip address show - look at protocol addresses
[dev DEVICE]
[label PATTERN]
[primary and secondary]
#ip address flush - flush protocol addresses
使用格式同show
ip route - routing table management
#ip route add
新增路由:ip route add TARGET via GW dev IFACE src SOURCE_IP
TARGET:
主機路由:IP
##網路路由:NETWORK/ MASK
新增網關:ip route add defalt via GW dev IFACE
ip route delete
刪除路由:ip route del TARGET 
##ip route show
#ip route flush
[dev IFACE]
[via PREFIX]
ss指令:
格式:ss [OPTION]... [FILTER]
選項:
-t: tcp協定相關
-u: udp協定相關
-w: 裸套接字相關
-x:unix sock相關
-l: listen狀態的連線
-a: 所有
-n: 數字格式
-p: 相關的程式及PID
-e: 擴充的資訊
-m:記憶體用量
-o:計時器資訊
FILTER := [ state TCP-STATE ] [ EXPRESSION ]
TCP的共同狀態:
tcp finite state machine:
LISTEN: 監聽
ESTABLISHED:已建立的連線
FIN_WAIT_1
FIN_WAIT_2
SYN_SENT
## SYN_RECV
CLOSED
EXPRESSION:
dport = 
sport = 
範例:'( dport = :ssh or sport = :ssh )'
#常用組合:
-tan, -tanl, -tanlp, -uan
Linux網路屬性設定(3): 修改設定檔
#IP、MASK、GW、DNS相關設定檔:/etc/sysconfig/network-scripts/ ifcfg-IFACE
路由相關的設定檔:/etc/sysconfig/network-scripts/route-IFACE
## #/etc/sysconfig/network-scripts/ifcfg-IFACE:############DEVICE:此設定檔套用到的裝置;############HWADDR:對應的設備的MAC位址;############BOOTPROTO:啟動此裝置時使用的位址設定協議,常用的dhcp, static, none, bootp;########## ###NM_CONTROLLED:NM是NetworkManager的簡寫;此網卡是否接受NM控制;CentOS6建議為「no」;############ONBOOT:在系統引導時是否啟動此設備;## ##########TYPE:介面類型;常見有的Ethernet, Bridge;#############UUID:裝置的惟一識別;######################################################################## #########IPADDR:指明IP位址;###
NETMASK:子網路遮罩;
GATEWAY: 預設閘道;
DNS1:第一個DNS伺服器指向;
DNS2:第二個DNS伺服器指向;
USERCTL:一般使用者是否可控制此設備;
PEERDNS:如果BOOTPROTO的值為“dhcp”,是否允許dhcp server分配的dns伺服器指向資訊直接覆蓋至/etc/resolv.conf檔案中;
/etc/sysconfig/network-scripts/route-IFACE
兩種風格:
(1) TARGET via GW
#(2) 每三行定義一條路由
ADDRESS#=TARGET
NETMASK#=mask
GATEWAY#=GW
##設定多位址由網路卡位址:
ifconfig:
#ifconfig IFACE_ALIAS 
#ip
ip addr add 
#設定檔:
##ifcfg-IFACE_ALIAS
DEVICE=IFACE_ALIAS
#注意:網關別名不能使用dhcp協定引導;
#Linux網路屬性配置的tui(text user interface):
system-config-network-tui
也可以使用setup找到;
#注意:記得重新啟動網路服務方能生效;
#設定目前主機的主機名稱:
hostname [HOSTNAME]
/etc/sysconfig/network
HOSTNAME=
#網路介面辨識並命名相關的udev設定檔:
/etc/udev/rules.d/70-persistent-net.rules
卸載網路卡驅動程式:
modprobe -r e1000
#裝載網卡驅動:
modprobe e1000
CentOS 7網路屬性設定
## 傳統命名:乙太網路eth[0,1,2,...], wlan[0,1,2,...]
可預測函數
udev支援多種不同的命名方案:
#Firmware, 拓樸結構
##(1) 網路卡命名機制
systemd對網路設備的命名方式:
(a ) 如果Firmware或BIOS為主板上整合的設備提供的索引資訊可用,且可預測則根據此索引進行命名,例如eno1;
(b) 如果Firmware或BIOS為PCI-E擴充槽所提供的索引資訊可用,且可預測,則根據此索引進行命名,例如ens1; 
(c) 如果硬體介面的實體位置資訊可用,則根據此資訊命名,例如enp2s0;
(d) 若使用者明確啟動,也可依MAC位址命名,enx2387a1dc56; 
#(e) 上述皆不可用時,則使用傳統命名機制;
#上述命名機制中,有的需要biosdevname程式的參與;
############(2) 名稱組成格式#############en: ethernet###########wl : wlan############ww: wwan###################名稱類型:############ o: 整合設備的設備索引號碼;###
s: 擴充槽的索引號碼;
x: 基於MAC位址的命名;
#ps: enp2s1
網卡設備的命名過程:
#第一步:
udev, 輔助工具程式/lib/udev/rename_device, /usr/lib/udev/rules.d/60-net.rules
第二步:
biosdevname 會根據/usr/lib/udev/rules.d/71-biosdevname.rules
第三個步驟:
透過偵測網路介面設備,根據/usr/lib/udev/rules.d/ 75-net-description
ID_NET_NAME_ONBOARD, ID_NET_NAME_SLOT, ID_NET_NAME_PATH
# 傳統命名方式:
#回歸傳統命名方式:
(1) 編輯/etc/default/grub設定檔
GRUB_CMDLINE_LINUX="net.ifnames=0 rhgb quiet"
#(2) 為grub2產生其設定檔
#grub2-mkconfig -o /etc/grub2.cfg
#(3) 重新啟動系統
#位址設定工具:nmcli
## nmcli  [ OPTIONS ] OBJECT { COMMAND | help }
device - show and manage network interfaces
connection - start, stop, and manage network connections
#如何修改IP位址等屬性:
# #nmcli connection modify IFACE [+|-]setting.property value
setting.property:
ipv4. addresses
ipv4.gateway
ipv4.dns1
#ipv4.method
manual
# #網路介面設定tui工具:nmtui
主機名稱設定工具:hostnamectl
##status
#set-hostname
#參考資料:
網路用戶端工具:
lftp, ftp, lftpget, wget
# lftp [ -p port] [-u user[,password]] SERVER
子指令:
get
mget
ls
#help
## lftpget URL
# ftp
# wget
wget [option]... [URL]...
-q: 靜默模式
-c: 續傳
-O: 儲存位置
#--limit-rates=: 指定傳輸速率
回顧:ip指令,ss指令;設定檔;CentOS 7
ifcfg、ip、netstat 、ss############設定檔:############/etc/sysconfig/network-scripts/############ ifcfg-IFNAME############route-IFNAME############CentOS 7: nmcli, nmtui#############Linux進程及作業管理##################核心的功用:行程管理、檔案系統、網路功能、記憶體管理、驅動程式、安全功能######## #
Process: 執行中的程式的副本;
#存在生命週期
Linux核心儲存進程資訊的固定格式:task struct
多個任務的的task struct元件的鍊錶:task list
#進程建立:
init
#父子關係
程式:都由其父進程創建
fork(), clone()
##進程優先權:
0-139:
1-99:即時優先權;
100-139:靜態優先權;
數字越小,優先權越高;
Nice值:
-20,19
#Big O
O(1), O( logn), O(n), O(n^2), O(2^n)
#進程記憶體:
Page Frame: 頁框,用儲存頁面資料
儲存Page
MMU:Memory Management Unit
IPC: Inter Process Communication
在同一主機上:
signal
shm: shared memory
#semerphor
不同主機上:
rpc: remote procecure call
socket: 
Linux核心:搶佔式多任務
#程式類型:
守護程式: 在系統引導過程中啟動的進程,跟終端機無關的進程;
#前台進程:跟終端機相關,透過終端機啟動的進程
:也可把在前台啟動的程序送到後台,以守護模式運作;
#程式狀態:
執行狀態:running
就緒狀態:ready
#睡眠狀態:
可中斷:interruptable
不可中斷:uninterruptable
停止態:暫停於記憶體中,但不會被調度,除非手動啟動之;stopped
死態:zombie
#程式的分類:
##CPU- Bound
IO-Bound
#《Linux核心設計與實作》,《深入理解Linux核心》
Linux程序檢視及管理的工具:pstree, ps, pidof, pgrep, top, htop, glance, pmap, vmstat, dstat, kill, pkill, job, bg, fg, nohup
pstree指令:
pstree - display a tree of processes
ps: process state
ps - report a snapshot of the current processes
Linux系統各行程的相關資訊皆保存在/proc/PID目錄下的各檔案中;
ps [OPTION]...
選項:支援兩種風格
#常用組合:aux
u: 以使用者為中心組織進程狀態資訊顯示
a: 與終端機相關的進程;
x: 與終端機無關的程序;
~]# ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY   #  STAT START
#VSZ: Virtual memory SiZe,虛擬記憶體集
RSS: ReSident Size, 常駐記憶體集
#STAT:行程狀態
R:running
#S: interruptable sleeping
D: uninterruptable sleeping
T: stopped
Z: zombie
+: 前台進程
l: 多執行緒進程
N:低優先權進程
<: 高優先權進程
##s: session leader
常用組合:- ef
-e: 顯示所有進程
-f: 顯示完整格式程式資訊
常用組合:-eFH
-F: 顯示完整格式的進程資訊
-H: 以進程層級格式顯示進程相關資訊
常用組合:-eo, axo
-eo pid,tid,class ,rtprio,ni,pri,psr,pcpu,stat,comm
axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
ni: nice值
#pri: priority,優先權
psr: processor, CPU
rtprio: 即時優先權
pgrep, pkill:
#pgrep [options] pattern
       
pkill [options] pattern
       
##-
       
-u uid: effective user
       
-U uid: real user
       
-t terminal: 與指定終端機相關的進程
## 
##-t terminal: 與指定終端機相關的進程
##  ## #-l: 顯示流程名稱
       -a: 顯示完整格式的行程名稱
       -P pid: 顯示其父行程為此處指定的程序的行程清單
       
pidof:       
依行程名稱取得其PID;
       
top:       
有許多內建指令:##       ## 排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序:排序。
       P:以佔據的CPU百分比;
       M:佔據內存百分比;
        T:累積佔據CPU時長;
       首部資訊顯示:
        ##       
tasks及cpu資訊:t指令       
cpu分別顯示:1 (數字)
     m指令
###       #######退出指令:q######       #######修改刷新時間間隔:s######      ####修改刷新時間間隔:s######   ####終止指定程序:k​​############       ######選項:###
       ##-d #: 指定刷新時間間隔,預設為3秒;
       
-b: 以批次方式;##  # 
#-b: 以批次方式;
##  -n #: 顯示多少批次;
##       
htop指令:
       
選項:
       
-d #: 指定延遲時間;
       
-u UserName: 只顯示指定使用者的進程;##   #   ##    ##    ##    ##  
#-s COLOMN: 以指定欄位排序;
       
指令:
##      
s: 追蹤選定行程的系統呼叫;      
l: 顯示選定行程開啟的檔案清單;##      
a:將選定的程序綁定至某指定CPU核心;
     
t: 顯示進程樹
#      
注意:Fedora-EPEL來源
回顧:
Linux基礎:
CPU: timeslice
Memory:線性位址空間
I/O:
分時重複使用
程式檢視工具:pstree, ps, pgrep, pidof, top, htop
#Linux進程查看及管理(2)
Linux進程檢視及管理的工具:pstree, ps, pidof, pgrep , top, htop, glances, pmap, vmstat, dstat, kill, pkill, job, bg, fg, nohup
vmstat指令:
#vmstat [options] [delay [count]]
procs:
r :等待運行的程序的數量;
b:處於不可中斷睡眠狀態的程序個數;(被阻塞的佇列的長度);
memory:
swpd: 交換記憶體的使用總量; 
free:空閒實體記憶體總量;
buffer:用於buffer的記憶體總量;
cache:用於cache的記憶體總量;
swap:
si:資料進入swap中的資料速率(kb/s)
so:資料離開swap中的資料速率(kb/s)
io:
#bi:從區塊裝置讀入資料到系統的速率;(kb/s )
bo: 將資料儲存至區塊裝置的速率;
system:
##in : interrupts, 中斷速率;
cs: context switch, 進程切換速率;
cpu:
##us
sy
id
wa
st
#選項:
#-s: 顯示記憶體的統計資料
pmap指令:
pmap - report memory map of a process
## #####pmap [options] pid [...]############-x: 顯示詳細格式的資訊;############# ####另外一種實作:############# cat /proc/PID/maps##########
##glances指令:
glances [-bdehmnrsvyz1] [-B bind] [-c server] [-C conffile] [ -p 連接埠] [-P 密碼] [--密碼] [-t 刷新] [-f 檔案] [-o 輸出]
內建指令:
a 自動對行程排序l 顯示/隱藏日誌
c 對進程排序依CPU%           b  網路I/O 的位元組或位元
 m  按MEM% 對進程進行排序         # p  對進程進行排序name           x  刪除警告和關鍵日誌
 i  按I/O 速率對進程進行排序      1  全局統計資料
#12CPU 統計資料
 d  顯示/隱藏磁碟I/O 統計資料        h  顯示/隱藏此說明畫面
 f  顯示/隱藏檔案系統統計資料O
n 顯示/隱藏網路統計數據u 查看累計網路I/O
s 顯示/隱藏感測器統計資料退出(Esc 和Ctrl-C 也可以)
 y  顯示/隱藏hddtemp stats
# 常用選項:
-b: 以Byte為單位顯示頻寬資料速率;
-d: 關閉磁碟I/O模組;
-f /path/to/somefile:設定輸入檔案位置;
#-o {HTML|CSV}:輸出格式;
-m:取消掛載模組
-n: 取消網路模組
-t #: 延遲時間間隔
-1:每個CPU的相關資料單獨顯示;
C/S模式下執行檢視指令:
服務模式:
glances -s -B IPADDR
IPADDR : 指示監聽於本機哪個位址
##客戶端模式:
glances -c IPADDR
IPADDR:要連入的伺服器端位址
dstat指令:
dstat [-afv] [選項..] [delay [count]]
#-c: 顯示cpu相關資訊;
-C# ,#,...,total
-d:顯示磁碟相關資訊;
-Dtotal,sda,sdb,.. .
##-g:顯示頁面相關統計;
-m:顯示記憶體相關統計資料;
-n:顯示網路相關統計資料;
-p:顯示進程相關統計;
-r:顯示io請求相關的統計資料;
-s: 顯示交換的相關統計資料;
-- tcp
--udp
#--unix
--raw
--插座
#--ipc
--top-cpu:顯示最佔用CPU的進程;
#--top-io:顯示最佔用io的進程;
--top-mem: 顯示最佔用記憶體的進程;
#--top-lantency: 顯示延遲最大的進程;
##kill指令:
向進程發送控制訊號,以實現對進程管理
#顯示目前系統可用訊號:
## kill -l
# man 7 signal
常用訊號:
1) SIGHUP: 無須關閉進程而讓其重讀設定檔;
2) SIGINT: 中止正在執行的進程;相當於Ctrl+c ;
9) SIGKILL: 殺死正在執行的進程;
15) SIGTERM:終止正在執行的進程;
18) SIGCONT:
19) SIGSTOP:
指定訊號的方法:
(1) 訊號的數字識別;1, 2, 9
(2) 訊號完整名稱;SIGHUP
#(3) 訊號的簡寫名稱;HUP
#向進程發送訊號:
kill [-SIGNAL] PID...
終止「名稱」之下的所有行程:
killall [-SIGNAL] Program
Linux的作業控制
前台作業:透過終端啟動,且啟動後一直佔據終端;
#後台作業:可透過終端機啟動,但啟動後即轉入後台運作(釋放終端);
如何讓作業運行於後台?
(1) 執行中的作業
#Ctrl+z
(2) 尚未啟動的作業
# COMMAND &
#此類作業雖然被送到後台運行,但其依然與終端相關;如果希望送到背景後,剝離與終端的關係:
## nohup COMMAND &
檢視所有作業:
# jobs
作業控制:
## fg [[%]JOB_NUM]:把指定的後台作業調回前台;
## bg [[%]JOB_NUM]:讓送到後台的作業在後台繼續執行;
# kill [%JOB_NUM]:終止指定的作業;
##程式優先調整:
靜態優先權:100-139
#進程預設啟動時的nice值為0,優先權為120;
nice指令:
#nice [OPTION] [COMMAND [ARG]...]
renice指令:
renice [-n] priority pid...
檢視:
ps axo pid,comm,ni
未涉及的指令:sar, tsar, iostat, iftop
#Linux任務計劃、週期性任務執行
##未來的某一時間點執行一次任務:at, batch
#週期性執行某項任務: cron
# ########電子郵件服務:############smtp: simple mail transmission protocol, 用於傳送郵件;############pop3: Post Office Protocol############imap4:Internet Mail Access Protocol##################mailx - send and receive Internet mail#### ##############MUA:Mail User Agent##################mailx [-s 'SUBJECT'] username[@hostname] ############郵件正文的產生:############(1) 直接給出,Ctrl+d; ###
(2) 輸入重定向;
(3) 透過管道;
echo -e " How are you?\nHow old are you?" | mail
#mailx
# at指令:
at [option] TIME
TIME:
HH:MM [YYYY-mm-dd]
noon, midnight, teatime
tomorrow
now+#{minutes,hours,days, OR weeks}
##常用選項:
#-q QUEUE: 
-l: 列出指定佇列中等待執行的作業;相當於atq
##- d: 刪除指定的作業;相當於atrm
-c: 檢視特定作業任務;
##-f /path/from/somefile :從指定的檔案中讀取任務;
注意:作業的執行結果以郵件通知相關使用者;
#batch指令:
讓系統自行選擇空閒時間去執行此處指定的任務;
週期性任務計畫:cron
相關的套件:
cronie: 主程式包,提供了crond守護程序及相關輔助工具;
cronie-anacron:cronie的補充程序;用於監控cronie任務執行狀況;如cronie中的任務在過去該運行的時間點未能正常運行,則anacron會隨後啟動此任務;
crontabs:包含CentOS提供系統維護任務;
#確保crond守護處於運作狀態:
CentOS 7:
systemctl status crond
...running...
CentOS 6:
#service crond status
##計畫要週期性執行的任務提交給crond,由其來實現到點運行。
系統cron任務:系統維護作業
#/etc/crontab
使用者cron任務:
crontab指令
#系統cron任務
# 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
# |
##例如:晚上9點10分執行echo指令;
10 21 * * *
gentoo /bin/echo "Howdy!"
#時間表示法:
##(1) 特定值;
給定時間點有效取值範圍內的值;
#(2) *
#在給定時間點上有效取值範圍內的所有值;
表示「每...」;
(3 ) 離散取值:,
#,#,
#####(4) 連續取值:-####### ######-####
(5) 在指定時間範圍上,定義步長:
#/#: #即為步長
#例如:每3小時echo指令;
#0 */3 * * * gentoo /bin/echo "howdy!"
#使用者cron:
crontab指令定義,每個使用者都有專用的cron任務檔案:/var/spool/cron /USERNAME
crontab指令:
crontab [-u user] [-l | -r | -e ] [-i] 
-l: 列出所有任務;
-e: 編輯任務;
-r: 移除所有任務;
-i:同-r一同使用,以互動模式讓使用者選擇性地移除指定任務;
-u user: 僅root可運行,代為指定使用者管理cron任務;
注意:運行結果以郵件通知相關使用者;
(1) COMMAND > /dev/null 
(2) COMMAND &> /dev/null
對於cron任務來講,%有特殊用途;如果在命令中要使用%,則需要轉義;不過,如果把%放在單引號中,也可以不用轉義;
#思考:
(1)如何在秒級別運行任務?
* * * * * for min in 0 1 2; do echo "hi"; sleep 20; done
(2) 如何實作每7分鐘運行一次任務?
sleep指令:
sleep NUMBER[SUFFIX]...
SUFFIX: 
#s: 秒, 預設
##m:分
h: 小時
d: 天
;
##CentOS 5與6的啟動流程
Linux: kernel+rootfs
#kernel: 程式管理、記憶體管理、網路管理、驅動程式、檔案系統、安全功能
rootfs:
glibc
#函式集合, function, 呼叫介面
過程呼叫:procedure
函數呼叫:function
程式
##核心設計流派:
單一核心設計:Linux
把所有功能整合於同一個程式;
微核心設計:Windows, Solaris
#每個功能都使用一個單獨子系統實作;
#Linux核心特性:
支援模組化:.ko
支援模組的動態載入和卸載;
組成部分:
#核心檔案:/boot/vmlinuz-VERSION-release
ramdisk:
CentOS 5: /boot/initrd-VERSION-release.img
CentOS 6: / boot/initramfs-VERSION-release.img############模組檔案:/lib/modules/VERSION-release################### CentOS 系統啟動流程:##################POST:加電自我檢查;###########ROM:CMOS##### #######BIOS:Basic Input and Output System###################ROM+RAM######################################################################################### ###BOOT Sequence: ###
依序找出各引導設備,第一個有引導程式的設備即為本次啟動用到設備;
#bootloader: 開機載入器,程式
windows: ntloader
Linux:
LILO :LInux LOader
GRUB: GRand Uniform Bootloader
GRUB 0.X: GRUB Legacy
#GRUB 1.x: GRUB2
功能:提供一個選單,讓使用者可以選擇要啟動系統或不同的核心版本;把使用者選定的核心裝載到記憶體中的特定空間中,解壓縮、展開,並把系統控制權移交給核心;
MBR:
446: bootloader
64: fat
2: 55AA
#GRUB: 
bootloader: 1st stage
disk: 2nd stage
##kernel:
自身初始化:
探測可辨識到的所有硬體設備;
載入硬體驅動程式;(有可能會藉助ramdisk載入驅動程式)
以唯讀方式掛載根檔案系統;
執行使用者空間的第一個應用程式:/sbin/init
#init程式的類型:
#SysV: init, CentOS 5
設定檔:/etc/inittab
##Upstart: init , CentOS 6
設定檔:/etc/inittab, /etc/init/*.conf
##Systemd :systemd, CentOS 7
設定檔:/usr/lib/systemd/system, /etc/systemd/system
ramdisk:
核心中的功能之一:使用緩衝和快取來回事對磁碟上的檔案存取;
#ramdisk --> ramfs
#CentOS 5: initrd,  工具程式:mkinitrd
#CentOS 6: initramfs, 工具程式:mkinitrd, dracut
系統初始化:
# POST --> BootSequence (BIOS) --> Bootloader(MBR) --> kernel(ramdisk) --> rootfs(唯讀) --> init
#/sbin/init
#CentOS 5:
#運行等級:為了系統的運作或維護等應用目的而設定;
0-6: 7級
0:關機
1:單一使用者模式(root, 無須登入), single, 維護模式;
2: 多重使用者模式,會啟動網路功能,但不會啟動NFS;維護模式;
3:多重使用者模式,正常模式;文字介面;
###4:預留等級;可同3等級;############5:多重使用者模式,正常模式;圖形介面; ############6:重啟###################預設等級:############3, 5##################切換等級:#############init ############## ####查看層級:############runlevel#############who -r############## ###設定檔:/etc/inittab################## 每一行定義一個action以及與之對應的process###
id:runlevel:action:process
#action:
wait: 切換到這個層級執行一次;
respawn:此process終止,就重新啟動之;
initdefault:設定預設運行等級;process省略;
#sysinit:設定係統初始化方式,此處一般為指定/etc/rc.d/rc.sysinit;
##......
id:3:initdefault:
#si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/ etc/rc.d/rc 1
...
#l6:6:wait:/etc/rc.d/rc 6
說明:rc 0 --> 意味著讀取/etc/rc.d/rc0.d/
K*: K##*:##運行次序;數字越小,越先運行;數字越小的服務,通常為依賴到別的服務;
S*: S##*:##運行次序;數字越小,越先運行;數字越小的服務,通常為被依賴到的服務;
for srv in /etc/rc.d/rc0.d/K*; do
$srv stop
done
for srv in /etc/rc.d/rc0.d/S*; do
$srv start
done
chkconfig命令
查看服務在所有級別的啟動或關閉設定情形:
chkconfig [--list] [name]
## 新增:
SysV的服務腳本放置於/etc/rc.d/init.d (/etc/init.d)
chkconfig --add name
#!/bin/bash
## chkconfig: LLLL nn nn
#刪除:
##chkconfig --del name
修改指定的連結類型
#chkconfig [--level levels] name
--level LLLL: 指定要設定的等級;省略時表示2345;
注意:正常等級下,最後啟動一個服務S99local沒有連結至/etc/rc.d/init.d一個服務腳本,而是指向了/etc/rc.d/rc.local腳本;因此,不便或不需要寫為服務腳本放置於/etc/rc.d/init.d/目錄,且想開機時自動執行的命令,可直接放置於/etc/rc.d/rc.local檔案中;
#tty1:2345:respawn:/usr/sbin/mingetty tty1
tty2:2345:respawn:/usr/sbin/mingetty tty2
...
tty6:2345:respawn:/usr/sbin/mingetty tty6
mingetty會呼叫login程式
/etc/rc.d/rc.sysinit: 系統初始化腳本
#(1) 設定主機名稱;
(2) 設定歡迎訊息;
(3) 啟動udev和selinux; 
(4) 掛載/etc/fstab檔案中定義的檔案系統;
##(5) 偵測根檔案系統,並以讀寫方式重新掛載根檔案系統;
(6) 設定係統時脈;
(7) 啟動swap裝置;
(8) 依據/etc/sysctl.conf檔案設定核心參數;
##(9) 啟動lvm及software raid裝置;
(10) 載入額外裝置的驅動程式;
(11) 清理作業;
總結:/sbin/init --> (/etc/inittab) --> 設定預設運行等級--> 執行系統初始腳本、完成系統初始化--> 關閉對應下需要關閉的服務,啟動需要啟動服務--> 設定登入終端機 
CentOS 6:
##init程式為: upstart, 其設定檔:
/etc/inittab, /etc/init/*.conf
注意:/etc/init/*.conf檔案語法遵循upstart設定檔語法格式;
##CentOS 6啟動流程:
POST --> Boot Sequence(BIOS) -- > Boot Loader (MBR) --> Kernel(ramdisk) --> rootfs --> switchroot --> /sbin/init -->(/etc/inittab, /etc/init/*. conf) --> 設定預設運行等級--> 系統初始化腳本--> 關閉或啟動對應等級下的服務--> 啟動終端
##GRUB( Boot Loader):
grub: GRand Unified Bootloader
grub 0.x: grub legacy
grub 1.x: grub2
#grub legacy:
stage1: mbr
stage1_5: mbr之後的磁區,讓stage1中的bootloader能辨識stage2所在的分割區上的檔案系統;
stage2:磁碟分割區(/boot/grub/)
設定檔:/boot/grub/grub.conf <-- /etc/grub.conf
stage2及核心等通常放置於一個基本磁碟分割區;
##功用:
(1) 提供選單、並提供互動式介面
e: 編輯模式,用於編輯選單;
c : 指令模式,互動式介面;
(2) 載入使用者選擇的核心或作業系統
允許傳遞參數給核心
可隱藏此選單
(3) 為選單提供了保護機制
為編輯選單進行認證
為啟用核心或作業系統進行認證
#如何辨識裝置:
#(hd#,#)
hd#: 磁碟編號,用數字表示;從0開始編號
#: 分割區編號,用數字表示; 從0開始編號
#(hd0,0)
grub的命令列介面
help: 取得幫助清單
help KEYWORD: 詳細協助資訊
#find (hd#,#)/PATH/TO/SOMEFILE:
#root (hd#,#)
kernel /PATH/TO/KERNEL_FILE: 設定本次啟動時所使用的核心檔案;額外也可以加入許多核心支援使用的cmdline參數;
例如:init=/ path/to/init, selinux=0
initrd /PATH/TO/INITRAMFS_FILE: 設定為選定的核心提供額外檔案的ramdisk;
#boot: 引導啟動選定的核心;
# 手動在grub命令列介面啟動系統:
#grub> root (hd#,#)
grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE 
####################### #grub> initrd /initramfs-VERSION-RELEASE.img############grub> boot###################設定檔:/boot /grub/grub.conf############設定項:#############default=#: 設定預設啟動的選單項目;落單項目(title)編號從0開始;###
timeout=#:指定選單項目等待選項選擇的時間長度;
splashima=(hd#,#)/PATH/TO/XPM_PIC_FILE:指明選單背景圖片檔案路徑;
hiddenmenu:隱藏選單;
password [--md5] STRING: 選單編輯認證;
title TITLE:定義選單項目「標題」, 可出現多次;
root (hd#,#):grub查找stage2及kernel文件所在設備分區;為grub的「根」; 
kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:啟動的核心
initrd /PATH/TO/INITRAMFS_FILE: 核心匹配的ramfs檔案;
#password [--md5] STRING: 啟動選定的核心或作業系統時進行認證;
grub-md5-crypt指令
進入單一使用者模式:
(1) 編輯grub選單(選取要編輯的title,而後使用e指令); 
(2) 在選取的kernel後附加
1, s, S或single都可以;
(3) 在kernel所在行,鍵入「b」指令;
安裝grub:
#(1) grub-install
# #grub-install --root-directory=ROOT /dev/DISK
(2) grub
#grub> root (hd#,#)
grub> setup (hd#)
#Linux Kernel:
單核心體系設計、但充分借鑒了微核心設計體系的優點,為核心引入模組化機制。
核心組成部分:
kernel: 核心核心,一般為bzIma,通常在/boot目錄下,名稱為vmlinuz-VERSION- RELEASE;
kernel object: 核心對象,一般放置於/lib/modules/VERSION-RELEASE/
[ ]: N
[M]: M
[*]: Y
輔助檔案:ramdisk
initrd
#initramfs
##在運行中的核心:
uname指令:
uname - print system information
#uname [OPTION]...
-n: 顯示節點名稱;
-r: 顯示VERSION-RELEASE; 
模組:
lsmod指令:
顯示由核心已經載入的核心模組
顯示的內容來自: /proc/modules檔案
# #modinfo指令:
顯示模組的詳細描述資訊
modinfo [ -k kernel ]  [ modulename|filename ... ]
-n: 只顯示模組檔案路徑
#-p: 顯示模組參數
-a: author
-d: description
-l: license
modprobe指令:
載入或卸載核心模組
modprobe [ -C config-file ]  [ modulename ]  [ module parame-ters... ]
設定檔:/etc/modprobe.conf, /etc/modprobe.d/*.conf
     
modprobe [ -r ] modulename...
     
depmod指令:
      核心模組依賴關聯式檔案及系統資訊對映檔案的產生工具;
      # 載入或卸載核心模組:
      insmod指令:
      insmod [ filename ]  [ module options... ]
## 
#rmmod     
rmmod [ modulename ]
    /proc目錄:
   
核心把自己內部狀態資訊及統計訊息,以及可設定參數透過proc偽檔案系統加以輸出;
   
參數:   
唯讀:輸出訊息   
#可寫入:可接受使用者指定「新值」來實現核心某功能或特性的設定   
/proc/sys
   
(1) sysctl指令用於檢視或設定此目錄中許多參數;   
sysctl -w path.to.parameter=VALUE
#   
~]# sysctl -w kernel.hostname=mail.madu.com
#   
(2) echo指令透過重定向的方式也可以修改大多數參數的值;   
echo "VALUE" > ; /proc/sys/path/to/parameter
   
~]# echo "www.madu.com" > /proc/sys/kernel/hostname
   
sysctl指令:   
預設設定檔:/etc/sysctl.conf   
(1) 設定某參數   
sysctl -w parameter=VALUE   
#(2) 透過讀取設定檔設定參數   
sysctl -p [/path/to/conf_file]
   
#核心中的路由轉送:   
/proc/sys/net/ipv4/ip_forward
   
##常用的幾個參數:
#net.ipv4.ip_forward
   
vm.drop_caches
   
kernel.hostname
#    /sys目錄:
   
sysfs:輸出核心辨識出的各硬體設備的相關屬性訊息,也有核心對硬體特性的設定訊息;有些參數是可以修改的,用來調整硬體工作特性。
   
udev透過此路徑下輸出的資訊動態為各裝置建立所需裝置檔案;udev為執行使用者空間程式;專用工具:udevadmin, hotplug;
   
udev為裝置建立裝置檔案時,會讀取事先定義好的規則文件,一般在/etc/udev/rules.d及/usr /lib/udev/rules.d目錄下;
##    ramdisk檔案的製作:
   
(1) mkinitrd指令
    為目前正在使用的核心重新製作ramdisk檔案
    ~] # mkinitrd /boot/initramfs-$(uname -r) .img $(uname -r)
   
(2) dracut指令 
    #為目前正在使用的核心重新製作ramdisk檔案
    ~] # dracut /boot/initramfs-$(uname -r).img $(uname -r) 
##編譯核心:
   
前提:   
(1) 準備開發環境;   
#( 2) 取得目標主機上硬體設備的相關資訊;
    (3) 取得到目標主機系統功能的相關訊息,例如要啟用的檔案系統;
    (4) 取得核心原始碼套件;
    www.kernel.org
    準備開發環境:
    #套件組(CentOS 6):
    Server Platform Development
    Development Tools
#目標主機硬體裝置相關資訊:   
CPU:   
~]# cat /proc/cpuinfo#   
~]# x86info -a   
~]# lscpu
   
PCI裝置裝置:   
~]# lspci#   
-v   
-vv
   
~]# lsusb   
-v   
-vv
   
~]# lsblk
   
了解全部硬體裝置資訊#   
~]# hal-device
   
#簡單依據範本檔案的製作過程:   
#~]# tar xf linux-3.10.67.tar.xz -C /usr/src#   
~]# cd /usr/src   
~] # ln -sv linux-3.10.67 linux   
~]# cd linux   
~]# cp /boot/config-$( uname -r) ./.config
   
~]# make menuconfig   
#~]# screen    
~]# make -j
#   
~]# make modules_install   
~]# make install
   
#重啟系統,並測試使用新核心;
Linux核心編譯(2 )
編譯核心的步驟:
#(1) 設定核心選項
支援「更新」模式進行設定:
(a) make config:基於命令列以遍歷的方式去設定核心中可設定的每個選項;
(b) make menuconfig:基於curses的文字視窗介面;
(c) make gconfig:基於GTK開發環境的視窗介面;
(d) make xconfig:基於Qt開發環境的視窗介面;
支援「全新配置」模式進行設定:
(a) make defconfig:基於核心為目標平台提供的「預設」設定進行設定;
(b) make allnoconfig: 所有選項都回答為"no";
(2) 編譯
make [-j #]
如何只編譯核心中的一部分功能:
(a) 只編譯某子目錄中的相關程式碼:
# cd /usr/src/linux
## make dir/
(b) 只編譯一個特定的模組:
# cd /usr/src/linux
# make dir/file.ko
例如:只為e1000編譯驅動程式:
# make drivers/net/ethernet/intel/e1000/ e1000.ko
#######
如何交叉編譯核心:
編譯的目標平台與目前平台不相同;
make ARCH=arch_name
要取得特定目標平台的使用說明
# make ARCH =arch_name help
如何在已經執行過編譯作業的核心原始碼樹做重新編譯:
事先清理操作:
# make clean:清理大多數編譯產生的文件,但會保留config檔等;
# make mrproper: 清理所有編譯產生的檔案、config及某些備份檔;
# make distclean:mrproper、patches以及編輯器備份檔;
screen指令:
開啟新的screen:
screen
退出並關閉screen:
# exit
#剝離目前screen:
Ctrl +a,d
顯示所有已經開啟的screen:
#screen -ls
#恢復某screen
screen -r [SESSION]
CentOS系統安裝
bootloader-->kernel(initramfs)-->rootfs-->/sbin/init
anaconda: 安裝程式
tui: 基於curses的文字視窗;
#gui: 圖形視窗;
##CentOS的安裝程式啟動過程:
MBR:boot.cat
stage2: isolinux/isolinux.bin
設定檔:isolinux/isolinux.cfg
#每個對應的選單選項:
載入核心:isolinuz/vmlinuz
#向核心傳遞參數:append initrd=initrd.img ...
裝載根檔案系統,並啟動anaconda
預設啟動GUI介面
若是明確指定使用TUI介面:
向核心傳遞「text」參數即可;
#boot: linux text
注意:上述內容一般應位於引導裝置;而後續的anaconda及其安裝用到的套件等有幾種方式可用:
本地光碟
本機硬碟
ftp server: yum repository
http server: yum repostory
nfs server
#如果想要手動指定安裝來源:
boot: linux method
anaconda應用程式的工作過程:
##安裝前設定階段
#安裝程序使用的語言
鍵盤類型
#安裝目標儲存裝置
####安裝目標儲存裝置######### ###Basic Storage:本機磁碟############特種裝置:iSCSI#############設定主機名稱######### ##設定網路介面############時區#############管理員密碼############設定分割區方式及MBR的安裝位置##################建立一個普通使用者##################選定要安裝的程式套件############安裝階段###
在目標磁碟建立分割區,執行格式化操作等
#將選定的套件安裝至目標位置
安裝bootloader
首次啟動
#iptables
##selinux
#。
##core dump
anaconda的設定方式:
(1) 互動式配置方式;
(2) 透過讀取事先給定的設定檔自動完成設定;
##按特定語法給予的設定選項;
kickstart檔;
安裝引導選項:
# #boot: 
text: 文字安裝方式
#method: 手動指定使用的安裝方法
與網路相關的開機選項:
ip=IPADDR
#netmask=MASK
gateway=GW
dns=DNS_SERVER_IP
ifname=NAME:MAC_ADDR
#與遠端存取功能相關的引導選項:
vnc
#vncpassword='PASSWORD'
#指明kickstart檔案的位置
ks=
#DVD drive: ks=cdrom:/PATH/TO/KICKSTART_FILE
Hard drive: ks=hd:/device/drectory/KICKSTART_FILE
HTTP server: ks=http://host:port/path/to/KICKSTART_FILE
FTP server: ks=ftp://host:port/path/to/KICKSTART_FILE
HTTPS server: ks=https://host :port/path/to/KICKSTART_FILE
啟動緊急救援模式:
rescue
官方文件:《Installation Guide》
#kickstart檔案的格式:
命令段:指明各種安裝前配置,如鍵盤類型等;
套件段:指明要安裝的套件組或套件,不安裝的套件等;
%packages
@group_name
package
######################## # -package############%end###################################腳本段:############%pre: 安裝前腳本# ###########執行環境:執行於安裝媒體上的微型Linux環境##################%post: 安裝後腳本### #########執行環境:安裝完成的系統;#########################指令段中的指令:### #########必備指令############authconfig: 認證方式設定############authconfig --useshadow  --passalgo=sha512 ############bootloader:bootloader的安裝位置及相關設定############bootloader --location=mbr --driveorder=sda --append="crashkernel =auto crashkernel=auto rhgb rhgb quiet quiet"#############keyboard: 設定鍵盤類型############lang: 語言類型####### ######part: 建立分割區############rootpw: 指明root的密碼############timezone: 時區######## #######################可選指令#############install OR upgrade###########################install OR upgrade######### ###text: 文字安裝介面############network###
firewall
selinux
halt
##poweroff
reboot
repo
#user:安裝完成後為系統建立新使用者
url: 指明安裝來源
#建立kickstart檔案的方式:
(1) 直接手動編輯;
依據某範本修改;
(2) 可使用建立工具:system-config-kickstart ( CentOS 6)
依據某範本修改並產生新設定;
http://172.16.0.1/ centos6.x86_64.cfg
#檢查ks檔的語法錯誤:ksvalidator
# ksvalidator /PATH/TO/ KICKSTART_FILE
建立引導光碟:
# mkisofs -R -J -T -v --no-emul -boot --boot-load-size 4 --boot-info-table -V "CentOS 6.6 x86_64 boot" -b isolinux/isolinux.bin -c isolinux/boot.cat -o /root/boot.iso myiso/
回顧:CentOS系統安裝
#kickstart檔:
指令段
必備:authconfig, bootloader, ...
可選:firewall, selinux, reboot, ...
套件段
%packages
#@group_name
##package
-package
%end
腳本段
%pre
...
#%end
%post
...
#%end
建立工具:system-config-kickstart
語法檢查:ksvalidator
##安裝過程如何取得kickstart檔:
DVD: ks=cdrom:/PATH/TO/KS_FILE
##HTTP: ks=http://HOST: PORT/PATH/TO/KS_FILE
SELinux:
##SELinux: Secure Enhanced Linux ,工作於Linux核心中
DAC:自主存取控制;
MAC:強制存取控制;
SELinux有兩種工作等級:
#strict: 每個行程都受到selinux的控制;
targeted: 僅有限個程序受到selinux控制;
#只監控容易被入侵的進程;
##sandbox:
subject operation object
subject: 進程
object: 進程,文件,
」檔:open, read, write, close, chown, chmod
#subject: domain
object: type
SELinux為每個檔案提供了安全標籤,也為進程提供了安全標籤;
user:role:type
user: SELinux的user;
role: 角色;
type: 類型;
############### SELinux規則庫:############規則:哪個域能存取哪種或哪些類型內檔案;##################配置SELinux:###
SELinux是否啟用;
給檔案重新打標;
設定某些布型特性;
SELinux的狀態:
enforcing: 強制,每個受限的程序都必然受限;
permissive: 啟用,每個受限的程序違規操作不會被禁止,但會被記錄於審計日誌;
disabled : 關閉;
相關指令:
getenforce: 取得selinux目前狀態;
#setenforce 0|1
0: 設定為permissive
1: 設定為enforcing
#此設定:重新啟動系統後無效;
#設定檔:/etc/sysconfig/selinux, /etc /selinux/config
SELINUX={disabled|enforcing|permissive}
##給檔案重新打標:
chcon
      chcon [OPTION]... CONTEXT FILE...
      chcon [ OPTION]... [-u USER] [-r ROLE] [-t TYPE] FILE...
      chcon [OPTION]... --reference=RFILE FILE. ..
   -R:遞迴打標;
# #還原檔案的預設標籤:
restorecon [-R] /path/to/somewhere
布林型規則:
getsebool
#setsebool
getsebool指令:
getsebool [-a] [boolean]
setsebool指令:
setsebool [ -P] boolean value | bool1=val1 bool2=val2 ...
##bash腳本程式設計:
#程式語言:
#資料結構
順序執行
選擇執行
條件測試
#執行指令或[[ EXPRESSION ]]
執行狀態傳回值;
if
#case
循環執行
將某程式碼段重複執行多次;
#重複運行多少次?
循環次數事先已知:
循環次數事先未知;
##必須有進入條件和退出條件:
for, while, until
函數:結構化程式設計及程式碼重複使用;
function
for迴圈語法:
for NAME in LIST; do
迴圈體
##done
清單產生方式:
#########(1) 整數清單############{start..end}## ##########$(seq start [[step]end])#############(2) glob###########/ etc/rc.d/rc3.d/K*############(3) 指令##################透過ping指令探測172.16.250.1-254範圍內的所有主機的線上狀態;#############!/bin/bash#####################################################################################################
net='172.16.250'
#uphosts=0
##downhosts=0
for i in {1..20}; do
#    ping -c 1 -w 1 ${net}.$ {i} &> /dev/null
   if [ $? -eq 0 ]; then
echo "${net}. ${i} is up."
       let uphosts++
   else
   else
echo "$ {net}.${i} is down."
       let downhosts++
   fi
#    fi
#done
   
#echo "Up hosts: $uphosts."
echo "Down hosts: $downhosts."
while循環:
##while CONDITION; do
迴圈體
done
#CONDITION:迴圈控制條件;進入循環之前,先做一次判斷;每次循環之後會再次做判斷;
#條件為“true”,則執行一次循環;直到條件測試狀態為“false”終止迴圈;
因此:CONDTION一般應該有迴圈控制變數;而此變數的值會在迴圈體不斷地修正;
範例:求100以內所有正整數總和;
#!/bin/bash
declare -i sum=0
#declare -i i=1
##while [ $i -le 100 ]; do
   let sum+=$i
   let i++
done
echo "$i"
echo "Summary: $sum."
新增10位使用者
user1-user10
#!/bin/bash
##declare -i i=1
declare -i users=0
#while [ $i -le 10 ]; do
#    if ! id user$i &> /dev/null; then
useradd user$i
 
#echo "Add user: user$i."
       let users++
##    fi
#    fi
## let i++
done
#echo "Add $users users."
###透過ping指令偵測172.16.250.1-254範圍內的所有主機的線上狀態;(用while循環)############# #!/bin/bash##########################declare -i i=1##################declare -i i=1###########declare - i uphosts=0############declare -i downhosts=0############net='172.16.250'########## #########while [ $i -le 20 ]; do############    if ping -c 1 -w 1 $net.$i &> /dev/null ; then############echo "$net.$i is up."############let uphosts++########### #    else###
echo "$net.$i is down."
let downhosts++
##    fi
   let i++
#done
echo "Up hosts: $uphosts. "
echo "Down hosts: $downhosts."
列印九九乘法表;(分別使用for和while循環實作)
#!/bin/bash
for j in {1..9}; do
   for i in $(seq 1 $j); do
echo -e -n "${i}X${j}=$[$i*$j]\t"
   done
#    echo
done
#!/bin/bash
#declare -i i=1
declare -i j=1
while [ $j -le 9 ]; do
   while [ $i -le $j ]; do
echo -e -n "${i}X${j}=$[$i*$j]\t"
let i++
   done
   echo
   let i=1
   let j++
#done
使用RANDOM產生10個隨機數字,輸出這個10數字,並顯示其中的最大者和最小者;
##!/bin/bash
#declare -i max=0
#declare -i min=0
declare -i i=1
while [ $i -le 9 ]; do
rand=$RANDOM
   echo $rand
   if [ $i -eq 1 ]; then
max=$rand
min=$rand
   fi
   if [ $rand -gt $max ]; then
max=$rand
##    fi
   if [ $rand -lt $min ]; then
min=$rand
   fi
   let i++
done
echo "MAX : $max."
echo "MIN: $min."
回顧:selinux, while
##selinux: 內核,安全加強;
# 開啟:
/etc/sysconfig/selinux, /etc/selinux/config############# setenforce############## getenforce######################################################################## ##打標:############chcon [-t TYPE]############-R############ #####布林型:############getsebool [-a]############setsebool [-P]######## ##########while迴圈:############while CONDITION; do############迴圈體######## #####done############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/// :支援使用其它分隔符,s@@@,s
;
取代標記:
g: 行內全域替換;
p: 顯示已取代成功的行;
#w /PATH/TO/SOMEFILE:將取代成功的結果儲存至指定檔案中;
1:刪除/boot/grub/grub.conf檔案中所有以空白開頭的行行首的空白字元;
~]# sed 's@^[[:space:]]\+@@' /etc/grub2.cfg
2:刪除/etc/fstab檔案中所有以#開頭,後面至少跟一個空白字元的行的行首的#和空白字元;
~]# sed 's@ ^#[[:space:]]\+@@' /etc/fstab
#3:echo一個絕對路徑給sed指令,取出其基底名;取出其目錄名稱;
~]# echo "/etc/sysconfig/" | sed 's@[^/]\+/\?$@@'
高階編輯指令:
#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:反向顯示檔案中的每一行;
bash腳本程式設計
while CONDITION; do
迴圈體
done
# 進入條件:CONDITION為true;
退出條件:false
until CONDITION; do
循環體
done
#進入條件:false
#退出條件:true
範例:求100以內所正整數總和;
#!/bin/bash
#declare -i i=1
declare -i sum=0
until [ $i -gt 100 ]; do
   let sum+=$i
#    let i++
done
#echo "Sum: $sum"
#範例:列印九九乘法表
##!/bin/bash
##declare -i j=1
#declare -i i=1
until [ $j -gt 9 ]; do
   until [ $i -gt $j ]; do
#echo -n -e "${i}X${j}=$[$i*$j]\t"
       let i++
#    done
   echo
   let i=1
#    let j++
done
迴圈控制語句(用於迴圈體中):
#continue [N]:提前結束第N層的本輪循環,而直接進入下一輪判斷;
while CONDTIITON1; do
#CMD1
...
if CONDITION2; then
continue
#。
#fi
CMDn
...
done
break [N]:提前結束循環;
##while CONDTIITON1; do
CMD1
###...###########if CONDITION2; then##### #######break############fi#############CMDn###########...# ###########done###################範例1:求100以內所有偶數總和;要求循環遍歷100以內的所正整數;#############!/bin/bash#########################declare -i i=0# ##
declare -i sum=0
#until [ $i -gt 100 ]; do
#    let i++
   if [ $[$i%2] -eq 1 ]; then
#continue
   fi
   let sum+=$i
done
#echo "Even sum: $sum"
#建立死迴圈:
while true; do
循環體
done
until false; do
循環體
#done
done
範例2 :每隔3秒鐘到系統上取得已經登入的使用者的資訊;如果docker登入了,則記錄於日誌中,並登出;
!/bin/bash
#read -p "Enter a user name: " username
##while true; do
   if who | grep "^$username" &> /dev/null; then
#break
   fi
   sleep 3##done
#echo "$username logged on." >> /tmp/user.log
第二種實作:
#!/bin/bash
#read -p "Enter a user name: " username
until who | grep "^$username" &> /dev/null; do
#    sleep 3
done
echo "$username logged on." >> /tmp/user.log
while迴圈的特殊用法(遍歷檔案的每一行):
while read line; do
迴圈體
done < /PATH/FROM/SOMEFILE
依序讀取/PATH/FROM/SOMEFILE檔案中的每一行,並且將行賦值給變數line: 
#範例:找出其ID號碼為偶數的所有用戶,顯示其用戶名稱及ID號碼;
#!/bin/bash
while read line;do
       if [ $[`echo $line | cut -d: -f3` % 2] -eq 0 ];then
               echo -e -n "username: `echo $line | cut -d: -f1`\t"
# echo "uid: `echo $line | cut -d: -f3 `"
       fi
done < /etc/passwd
for迴圈的特殊格式:
for ((控制變數初始化;條件判斷表達式;控制變數的修正表達式)); do
循環體############done###################################################################### ########控制變數初始化:僅在運行到循環程式碼段時執行一次;############控制變數的修正表達式:每輪迴圈結束會先控制變數修正運算,而後再做條件判斷;##################範例:求100以內所正整數之和;######################################################################## ##!/bin/bash###
#declare -i sum=0
##for ((i =1;i<=100;i++)); do
   let sum+=$i
#done
echo "Sum: $sum."
#範例2:列印九九乘法表;
#!/bin/bash
##for((j= 1;j<=9;j++));do
       for((i=1;i<=j;i++))do
#            echo -e -n "${i}X${j}=$[$i*$j]\t"
       done
  我#        echo
done
(1) 顯示一個下列選單:
##(1) 顯示一個下列選單:
cpu) show cpu information;
mem) show memory information;
disk) show disk information;
quit) quit
(2) 提示用戶選擇選項;
(3) 顯示用戶選擇的內容;
#!/bin/bash
##cat << EOF
cpu) show cpu information;
mem) show memory information;
disk) show disk information;
#quit) quit
========== ===================
EOF
read -p "Enter a option: " option
while [ "$option" != 'cpu' -a "$option" != 'mem' -a "$option" ! = 'disk' -a "$option" != 'quit' ]; do
   read -p "Wrong option, Enter again: " option
#done
if [ "$option" == 'cpu' ]; then
   lscpu
elif [ "$option" == 'mem' ]; then
   cat /proc/meminfo
elif [ "$option" == 'disk' ]; then
#    fdisk -l
else
   echo "Quit"
   exit 0
fi
#進一步:
使用者選擇,並顯示完成後不退出腳本;而是提示使用者繼續選擇顯示其它內容;直到使用quit方始退出;
條件判斷:case語句
#case 變數引用in
PAT1)
分支1
;;
##PAT2)
分支2
;;
#...
# *)
預設分支
;;
##esac
#範例:
#!/bin/bash
#cat << EOF#############cpu) show cpu information;###
mem) show memory information;
disk) show disk information;
quit) quit
============================
# EOF
read -p "Enter a option: " option
while [ "$option" != ' cpu' -a "$option" != 'mem' -a "$option" != 'disk' -a "$option" != 'quit' ]; do
read -p "Wrong option, Enter again: " option
done
case "$option" in
cpu)
lscpu 
;;
mem)
cat /proc/meminfo
;;
disk)
fdisk -l
;;
##*)
echo "Quit..."
exit 0
;;
#esac
#(1) 腳本可接受參數:start, stop, restart, status; 
(2) 如果參數非此四者之一,提示使用格式後錯誤退出;
(3) 如果是start:則建立/var/lock/subsys/SCRIPT_NAME, 並顯示「啟動成功」;
考慮:如果事先已經啟動過一次,該如何處理?
(4) 如果是stop:則刪除/var/lock/subsys/SCRIPT_NAME, 並顯示「停止完成」;
考慮:如果事先已然停止過了,該如何處理?
(5) 如果是restart,則先stop, 再start;
考慮:如果本來沒有start,如何處理?
(6) 如果是status, 則
如果/var/lock/subsys/SCRIPT_NAME檔案存在,則顯示「SCRIPT_NAME is running ....」;
如果/var/lock/subsys/SCRIPT_NAME檔案不存在,則顯示「SCRIPT_NAME is stopped...」;
##其中:SCRIPT_NAME為目前腳本名稱;
#總結:until, while, for, case
##bash腳本程式設計:
#case語句:
##case變數引用in
PAT1)
#分支1
##;;
PAT2)
分支2
#;;
##. ..
*)
分支n
;;
#esac
case支援glob風格的通配符:
########*: 任意長度任意字符;############?: 任意單一字元;#############[]:指定範圍內的任意單一字元;######## ####a|b: a或b##################function:函數############過程式設計:程式碼重複使用# ###########模組化程式設計############結構化程式設計##################語法一: ############function f_name {############...函數體...############} ## #######
語法二:
f_name() {
##...函數體...
}
呼叫:函數只有被呼叫才會執行;
# #呼叫:給定函數名稱
函數名稱出現的地方,會被自動替換為函數代碼;
函數的生命週期:被呼叫時創建,返回時終止;
return命令返回自訂狀態結果;
0:成功
1-255:失敗
#!/bin/bash
function adduser {
#   if id $username &> /dev/null; then
#        echo "$username exists."
       return 1
#。
#}
for i in {1..10}; do
   username=myuser$i
   adduser
done
#範例:服務腳本
#!/bin/bash
chkconfig : - 88 12
# description: test service script
#prog=$ (basename $0)
lockfile=/var/lock/subsys/$prog
start() {
   if [ -e $lockfile ]; then
echo "$prog is aleady running."
#return 0
   else
touch $lockfile
##[ $? -eq 0 ] && echo "Starting $prog finished."
   fi
##}
#stop() {
   if [ -e $lockfile ]; then
rm -f $lockfile && echo " Stop $prog ok."
   else
echo "$prog is stopped yet."
#    fi
}
status() {
if [ -e $lockfile ]; then
echo "$prog is running."
   else
echo "$prog is stopped."
   fi
}
usage() {
   echo "Usage: $prog {start|stop|restart|status}"
# }
if [ $# -lt 1 ]; then
   usage
#    exit 1
##fi    
case $1 in
###################################################################################### ##start)############start###
;;
stop)
#stop
## ;;
restart)
stop
;;
status)
status
##;;
*)
usage
#esac
##函數傳回值:
函數的執行結果傳回值:
(1) 使用echo或print指令進行輸出;
(2) 函數體中呼叫指令的執行結果;
函數的退出狀態碼:
(1) 預設取決於函數體中執行的最後一條指令的退出狀態碼;
(2) 自訂退出狀態碼:
return
函數可以接受參數:
傳遞參數給函數:呼叫函數時,在函數名後面以空白分隔給定參數列表即可;例如「testfunc arg1 arg2 ...」
在函數體中當中,可使用$1, $2, ...呼叫這些參數;也可以使用$@, $*, $#等特殊變量;
範例:新增10個使用者
#!/bin/bash
#function adduser {
##   if [ $# -lt 1 ]; then
return 2
# 2: no arguments
  fi
#   if id $1 &> /dev/null; then
echo "$1 exists."
#return 1
  else
useradd $1
[ $? -eq 0 ] && echo "Add $1 finished." && return 0
  fi
}
for i in {1..10}; do
#    adduser myuser$i
done
印出NN乘法表,使用函數實作;
##變數作用域:
本機變數:目前shell程序;為了執行腳本會啟動專用的shell程序;因此,本機變數的作用範圍是目前shell腳本程式檔;
局部變數:函數的生命週期;函數結束時變數被自動銷毀;
如果函數中有局部變量,其名稱同本地變數;
在函數中定義局部變數的方法:
#local NAME=VALUE
##函數遞迴:
函數直接或間接呼叫自己;
##N!= N(n-1)(n-2)...1
n(n-1)! = n(n-1)(n-2)!
#!/bin/bash
#fact() {
   if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1
   else
echo $[$1*$(fact $[$1-1])]
   fi
}
fact 5
#求n階斐波那契數列;
#!/bin/bash
#fab() {
#    if [ $1 -eq 1 ]; then
#echo 1
   elif [ $1 -eq 2 ]; then
echo 1
   else
echo $[$(fab $[$1-1])+$(fab $[$1-2])]
   fi
}
fab 7
#Systemd:
POST --> Boot Sequence --> Bootloader --> kernel + initramfs(initrd) --> rootfs --> /sbin/init
init:
#CentOS 5: SysV init
CentOS 6: Upstart
CentOS 7: Systemd
Systemd新功能:
系統引導時實現服務並行啟動;
##按需激活進程;
系統狀態快照;
基於依賴關係定義服務控制邏輯;
核心概念:unit
設定檔進行識別與設定;檔案中主要包含了系統服務、監聽socket、儲存的系統快照以及其它與init相關的訊息;
儲存至:
/usr/lib/systemd/system
##/ run/systemd/system
/etc/systemd/system
Unit的類型:
Service unit: 檔案副檔名為.service, 用於定義系統服務;
Target unit: 檔案副檔名為.target,用於模擬實作“運行等級」;
Device unit: .device, 用於定義核心識別的裝置;
Mount unit: .mount, 定義文件系統掛載點;
Socket unit: .socket, 用來識別進程間通訊用的socket檔;
Snapshot unit: . snapshot, 管理系統快照;
Swap unit: .swap, 用於標識swap設備;
Automount unit: .automount,檔案系統的自動掛載點;
Path unit: .path,用於定義檔案系統中的一個檔案或目錄;
##關鍵特性:
基於socket的啟動機制:socket與服務程式分離;
基於bus的啟動機制:
基於device的激活機制:############基於path的激活機制:###########系統快照:保存各unit的目前狀態資訊於持久性儲存設備中;############向後相容sysv init腳本;################################################################不相容:############systemctl指令固定不變#############非由systemd啟動的服務,systemctl無法與之通訊###### ############管理系統服務:############CentOS 7: service unit############注意:能相容於早期的服務腳本##################指令:systemctl COMMAND name.service#########
啟動:service name start ==> systemctl start name.service
停止:service name stop ==> systemctl stop name.service
重啟:service name restart ==> systemctl restart name.service
狀態:service name status ==> systemctl status name. service
條件式重新啟動:service name condrestart ==> systemctl try-restart name.service
##重載或重新啟動服務:systemctl reload-or-restart name.service
重載或條件式重新啟動服務:systemctl reload-or-try-restart name.service
禁止設定為開機自啟動:systemctl mask name.service
取消禁止設定為開機自啟動:systemctl unmask name.service
查看某服務目前啟動與否的狀態:systemctl is-active name.service
查看所有已經啟動的服務:
systemctl list-units --type service 
查看所有服務:
systemctl list -units --type service --all
chkconfig指令的對應關係:
設定某服務開機自啟動:chkconfig name on ==> systemctl enable name.service
禁止:chkconfig name off ==> systemctl disable name.service
##查看所有服務的開機自啟動狀態:
chkconfig --list ==> systemctl list-unit-files --type service 
#查看服務是否開機自啟動:systemctl is-enabled name.service
其它指令:
# #查看服務的依賴關係:systemctl list-dependencies name.service
target units:
#unit設定檔:.target
運行等級:
0  ==> runlevel0.target , poweroff.target
1  ==> runlevel1.target, rescue.target
2  ==> runlevel2.target, multi -user.target
3  ==> runlevel3.target, multi-user.target
4  ==> runlevel4.target , multi-user.target
5  ==> runlevel5.target, graphical.target
6  ==> runlevel6.target , reboot.target
等級切換:
init N ==> systemctl isolate name.target
查看等級:
runlevel ==> systemctl list-units --type target
#取得預設運行等級:
/etc/inittab ==> systemctl get-default
##修改預設等級:
/etc/inittab ==> systemctl set-default name.target
#切換至緊急救援模式:
systemctl rescue
切換至emergency模式:
systemctl emergency
其它常用指令:
##關機:systemctl halt、systemctl poweroff
重啟:systemctl reboot
掛起:systemctl suspend########### #快照:systemctl hibernate############快照並掛起:systemctl hybrid-sleep#################回顧: bash腳本程式設計、 systemd#########
函數:模組化程式設計
function f_name {
...函數本體...
}
f_name() {
...函數體...
}
#return指令;
參數:
函數體中呼叫參數:$1, $2, ...
$*, $@, $
#向函數傳遞參數:
函數名稱參數清單
systemd:系統及服務
unit: 
#類型:service, target
.service, . target
systemctl 
#bash腳本程式設計:
##陣列:
變數:儲存單一元素的記憶體空間;
陣列:儲存多個元素的連續的記憶體空間;
#陣列名稱
索引:編號從0開始,屬於數值索引;
注意:索引也可支援使用自訂的格式,而不僅僅是數值格式;
 bash的陣列支援稀疏格式;
引用數組中的元素:${ARRAY_NAME[INDEX]}
聲明數組:
declare -a ARRAY_NAME
declare -A ARRAY_NAME: 關聯陣列;
陣列元素的賦值:
##(1) 一次只賦值一個元素;
ARRAY_NAME[INDEX]=VALUE
weekdays[0]=" Sunday"
weekdays[4]="Thursday"
(2) 一次賦值全部元素:
#ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
(3) 只賦值特定元素:
ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)
(4) read -a ARRAY
引用陣列元素:${ARRAY_NAME[INDEX]}
#注意:省略[INDEX]表示引用下標示為0的元素;
陣列的長度(陣列中元素的數量):${#ARRAY_NAME[*]}, ${#ARRAY_NAME[@]}
範例:產生10個隨機數儲存於陣列中,並找出其最大值和最小值;
#!/ bin/bash
##declare -a rand
declare -i max=0
for i in {0..9}; do
   rand[$i]=$RANDOM
   echo ${rand[$i]}
   [ ${rand[$i]} -gt $max ] && max=$ {rand[$i]}
done
#echo "Max: $max"
定義一個數組,數組中的元素是/var/log目錄下所有以.log結尾的檔案;要統計其下標為偶數的檔案中的行數總和;
##!/bin/bash
#declare -a files
###files=(/var/log/*.log)######### ###declare -i lines=0##################for i in $(seq 0 $[${#files[*]}-1]); do ###
   if [ $[$i%2] -eq 0 ];then
let lines+=$(wc -l ${files[$i ]} | cut -d' ' -f1) 
   fi
done
echo "Lines: $lines."
#引用陣列中的元素:
所有元素:${ARRAY[@]}, ${ARRAY[*]}
#陣列切片:${ARRAY[@] :offset:number}
offset: 要跳過的元素個數
number: 要取出的元素個數,取偏移量之後的所有元素:${ARRAY[@]:offset};
#向陣列中追加元素:
ARRAY[${#ARRAY[*]}]
#刪除陣列中的某元素:
unset ARRAY[INDEX]
關聯數組:
declare -A ARRAY_NAME
#ARRAY_NAME=([index_name1]='val1' [index_name2]='val2' ...)
bash的字串處理工具:
字串切片:
${var: offset:number}
取字串的最右邊幾個字元:${var: -lengh}
注意:冒號後必須有一空白字元;
基於模式取子字串:
##${var#*word}:其中word可以是指定的任意字元;功能:自左而右,尋找var變數所儲存的字串中,第一次出現的word, 刪除字串開頭至第一次出現word字元之間的所有字元;
${var##*word}:同上,不過,刪除的是字串開頭至最後一次由word指定的字元之間的所有內容;
#file="/var/log/messages"
${file##*/}: messages
##${var%word*}:其中word可以是指定的任意字元;功能:自右而左,查找var變數所儲存的字串中,第一次出現的word, 刪除字串最後一個字元向左至第一次出現word字元之間的所有字元;
file="/var/log/messages"
${file%/*}: /var/log
#${var%%word*}:同上,只不過刪除字串最右側的字元向左至最後一次出現word字元之間的所有字元;
#範例:url=:80
${url##*:}
${url%%:*}
找替換:
${var/pattern/substi}:查找var所表示的字串中,第一次被pattern所匹配到的字串,以substi替換之;
${var//pattern/substi}: 查找var所表示的字串中,所有能被pattern所匹配到的字串,以substi替換之;
${var/#pattern/substi}:在尋找var所表示的字串中,行首被pattern所匹配到的字串,以substi替換之;
${var/%pattern/substi}:查找var所表示的字串中,行尾被pattern所匹配到的字串,以substi替換之;
找出並刪除:
${var/pattern}:找出var所表示的字串中,刪除第一次被pattern配對到的字串
${var//pattern}:
${var/#pattern}:
${var/%pattern}:
#字元大小寫轉換:
#${var^^}:把var中的所有小寫字母都轉換成大寫;###
${var,,}:把var中的所有大寫字母轉換成小寫;
變數賦值:
${var:-value}:如果var為空或未設置,那麼傳回value;否則,則傳回var的值;
## ${var:=value}:如果var為空或未設置,那麼返回value,並將value賦值給var;否則,則返回var的值;
##${var:+value}:如果var不空,則返回value;
#${var:?error_info}:如果var為空或未設置,那麼返回error_info;否則,則傳回var的值;
#為腳本程式使用設定檔:
##(1)定義文字文件,每行定義「name=value」
(2) 在腳本中source此文件即可
指令:
mktemp指令:
#mktemp [OPTION]... [TEMPLATE]
TEMPLATE: filename.XXX
XXX至少要出現三個;
##OPTION:
##-d: 建立臨時目錄;
--tmpdir=/PATH/TO/SOMEDIR:指明臨時檔案目錄位置;
install指令:
      install [OPTION]... [-T] SOURCE DEST
      install [ OPTION]... SOURCE... DIRECTORY
      install [OPTION]... -t DIRECTORY SOURCE...
      install [ OPTION]... -d DIRECTORY...
     
選項:
     
#- m MODE
     
-o OWNER
     
-g GROUP
GNU awk:
#文字處理三工具:grep, sed, awk
grep, egrep, fgrep:文字過濾工具;pattern
sed: 行編輯器
模式空間、保持空間
awk:報告產生器,格式化文字輸出;
AWK: Aho , Weinberger, Kernighan --> New AWK, NAWK
#GNU awk, gawk
#gawk - pattern scanning and processing language
基本用法:gawk [options] 'program' FILE ...
#program: PATTERN{ACTION STATEMENTS}
#語句之間用分號分隔
print, printf
選項:
-F:指明輸入時所用到的欄位分隔符號;
#-v var=value: 自訂變數;
1、print
##1、print
print item1, item2, ...
#要點:
##(1) 逗號分隔符號;
(2) 輸出的各item可以字串,也可以是數值;目前記錄的欄位、變數或awk的表達式;
(3) 如省略item,相當於print $0; 
#2、變數
## 2.1 內建變數
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 :數組,保存的是命令列所給定的各參數;
#2.2 自訂變數
( 1) -v var=value
變數名區分字元大小寫;
(2) 在program中直接定義
3、printf指令
格式化輸出:printf FORMAT, item1, item2, ...
#(1) FORMAT必須給出; 
# (2) 不會自動換行,需要明確給出換行控制符,\n
(3) FORMAT中需要分別為後面的每個item指定一個格式化符號;
格式符號:
%c: 顯示字元的ASCII碼;
%d, %i: 顯示十進位整數;
#%e, %E: 科學計數法數值顯示;
# %f:顯示為浮點數;
%g, %G:以科學計數法或浮點數顯示數值;
##% s:顯示字串;
%u:無符號整數;
%%: 顯示%本身;
修飾符:
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點後的精確度;
%3.1f
#-: 左對齊
+:顯示數值的符號
4、運算子
算術運算子:
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
# awk -F: '{$3> =1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
#5、PATTERN
(1) empty:空模式,符合每一行;
(2) /regular expression/:僅處理能夠被此處的模式匹配到的行;
(3) relational expression: 關係式;結果有「真」有「假」;結果為「真」才會被處理;
真:結果為非0值,非空字串;
(4) line ranges:行範圍,
startline,endline :/pat1/,/pat2/
注意: 不支援直接給出數字的格式
~] # awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
(5) BEGIN/END模式
#BEGIN{}: 僅在開始處理文件中的文字之前執行一次;
#END{}:僅在文字處理完成之後執行一次;
6、常用的action
#(1) Expressions
(2) Control statements:if, while等;
(3) Compound statements:組合語句;
(4) input statements
(5) output statements
7、控制語句
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 }
7.1 if-else
語法:if(condition) statement [else statement]
~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n", $1}}' /etc/passwd
~]# awk -F: '{if($NF=="/bin/bash") print $1 }' /etc/passwd
~]# awk '{if(NF>5) print $0}' /etc/fstab
~]# df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=20) print $1}'
使用場景:對awk所取得的整行或某個欄位做條件判斷;
7.2 while循環
語法:while(condition) statement
條件“真”,進入循環;條件“假”,退出循環;
使用場景:對一行內的多個字段逐一類似處理時使用;對數組中的各元素逐一處理時使用;
~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg
#~]# awk '/^[[:space:] ]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /etc/grub2. cfg
7.3 do-while迴圈
語法:do statement while(condition)
意義:至少執行一次迴圈體
#7.4 for迴圈
語法:for( expr1;expr2;expr3) statement
for(variable assignment;condition;iteration process) {for-body}
#~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)} }' /etc/grub2.cfg
特殊用法:
能夠遍歷數組中的元素;
語法:for(var in array) {for-body}
#
7.5 switch語句
語法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; . ..; default: statement}
7.6 break和continue
break [n]
#continue
7.7 next
提前結束對本行的處理而直接進入下一行;
~]# awk -F: '{if($3%2!=0) next; print $1,$3 }' /etc/passwd
8、array
關聯陣列:array[ index-expression]
index-expression:
(1) 可使用任意字串;字串要使用雙引號;
(2) 如果某數組元素事先不存在,在引用時,awk會自動建立此元素,並將其值初始化為「空串」;
若要判斷數組中是否存在某元素,要使用"index in array"格式進行;
weekdays[mon]="Monday"
#若要遍歷陣列中的每個元素,要使用for迴圈;
for(var in array) {for-body}
#~]# awk 'BEGIN{weekdays["mon"] ="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'
#注意:var會遍歷array的每個索引;
state["LISTEN"]++
state["ESTABLISHED"]++
~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state ) { print i,state[i]}}'
~]# awk '{ip[$1]++}END{for(i in ip ) {print i,ip[i]}}' /var/log/httpd/access_log
#1:統計/etc/fstab檔案中每個文件系統類型出現的次數;
~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i ]}}' /etc/fstab
2:統計指定檔案中每個單字出現的次數;
~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' / etc/fstab
9、函數
9.1 內建函數
數值處理:
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所表示的陣列中;
~]# netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1] ]++}END{for (i in count) {print i,count[i]}}'
#9.2 自訂函數
《sed與awk》
########## ########################################################### ################
#   
####### #### ####################################################### ####DNF新一代的RPM 套件管理器。 ###DNF套件管理器克服了YUM套件管理器的一些瓶頸,提升了包括使用者體驗、記憶體佔用、依賴分析、運行速度等多方面的內容。使用RPM、libsolv和hawkey 函式庫進行套件管理操作。發行版版本號是 1.0,發行日期是 2015 年 5 月 11 日。 #############YUM 的依賴解析是一場噩夢,在DNF 中使用SUSE 庫“libsolv”和Python 包裝器以及C Hawkey 進行了解決。文檔化的API。一個耗時的過程.############################################ ##### ############################################## ####### ############################################ ######### ########################################## #######

以上是Linux系統基礎篇(二)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板