1. 程式人生 > 實用技巧 >《shell程式設計入門》學習總結

《shell程式設計入門》學習總結

以下圖為本章節的知識點結構圖。

wKiom1YskcmCqCv8AANivd3IJ0w288.jpg

【前言】我們在linux上敲過的命令是有記錄的。預設儲存1000條。儲存位置:.bash_history。但是前提是我們得正常退出。

shell是什麼?】shell是一個指令碼,不是一種正式的程式語言。shell也就是一些命令的集合,能夠幫助我們更加方便的管理伺服器。

shell特性】 !! 是執行上一條命令。

[[email protected]~]#ls-l11.txt
-rw-r--r--.1rootroot1536Oct1803:2711.txt
[[email protected]~]#!!
ls-l11.txt
-rw-r--r--.1rootroot1536Oct1803:2711.txt


n:執行第n條歷史命令的意思。

[[email protected]~]#!632
pwd
/root

!字串:執行最近的字串命令。

[[email protected]~]#!ls
ls-l11.txt
-rw-r--r--.1rootroot1536Oct1803:2711.txt

alias 命令別名 =‘具體別名’-----做別名。使用unalias解除別名(unalias 別名)。

[[email protected]~]#aliassenlin='ls'
[[email protected]~]#senlin
1111.txt1.txt2.txtanaconda-ks.cfginstall.loginstall.log.syslog

*:匹配多個或者零個字元。?:匹配一個字元。

[[email protected]~]#ls1*
11.txt1.txt
11:
11
[[email protected]~]#ls1?
11
[[email protected]~]#echo"aaa">11.txt
[[email protected]~]#echo"aaa">>11.txt
[[email protected]~]#cat11.txt
aaa
aaa

| :管道符。把前面的命令結果丟給後面的。

[[email protected]
~]#cat11.txt|wc-l 2

作業控制:當執行一個程序時,你可以使它暫停(按 Ctrl+z),然後使用 fg 命令恢復它,利用 bg 命令使他到後臺執行,你也可以使它終止(按 Ctrl+c)。多個被暫停的任務會有編號,使用 jobs 命令可以看到兩個任務,那麼使用 bg 或者 fg 的時候,就需要在後面加一個編號了,使用 bg 2 把第二個被暫停的任務丟到後臺跑起來了,丟入後臺需要使用在命令後邊加一個&符號,中間有個空格。先使用“fg 編號‘’把任務調到前臺,然後使用 Ctrl + c 結束任務。另外,關閉到當前的 shell,再次開啟另一個 shell時,使用 jobs 命令並不會顯示在後臺執行或者被暫停的任務,要想停掉它的話,則需要先知道其 pid,然後使用 kill 命令殺死那個程序。

shell變數】系統預設命令:PWD,HOME,LOGNAME

[[email protected]~]#echo$PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

env:列出所有系統變數。注:使用者不同,值不同。

[[email protected]~]#env
HOSTNAME=localhost.localdomain
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.200.15750522
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
LANG=en_US.UTF-8
SELINUX_LEVEL_REQUESTED=
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
SSH_CONNECTION=192.168.200.157505192.168.200.13122
LESSOPEN=||/usr/bin/lesspipe.sh%s
G_BROKEN_FILENAMES=1
_=/bin/env


PATH:決定了 shell 將到哪些目錄中尋找命令或程式;
HOME
:當前使用者主目錄
HISTSIZE
:歷史命令記錄數
LOGNAME
:當前使用者的登入名
HOSTNAME
:指主機的名稱
SHELL
:前使用者 Shell 型別
LANG
:語言相關的環境變數,多語言可以修改此環境變數
MAIL
:當前使用者的郵件的存放目錄
PWD
:當前所在目錄;

set:列出所有預設命令,包括自定義的變數。雖然我們自定義變數,但是也只能在當前的shell使用。

設定的變數一直生效:需要在 /etc/profile 檔案最末行加入export myname=senlin 然後執行 source /etc/profile 就可以生效了。

[[email protected]~]#echo"exportmyname=senlin">>/etc/profile
[[email protected]~]#source!$
source/etc/profile
[[email protected]~]#bash
[[email protected]~]#echo$myname
senlin
[[email protected]~]#exit
exit

自定義變數的規則:

a. 設定變數的格式為:a=b ,其中 a 為變數名,b 為變數的內容,等號兩邊不能有空格;
b.
變數名只能由英、數字以及下劃線組成,而且不能以數字開頭;
c.
當變數內容帶有特殊字元(如空格)時,需要加上單引號;

注意事項:

1.變數內容中本身帶有單引號,這就需要用到雙引號了;
2.
變數內容中需要用到其他命令執行結果則可以使用反引號;
3.
變數內容可以累加其他變數的內容,需要加雙引號;
4.
單引號和雙引號的區別。用雙引號時不會取消掉裡面出現的特殊字元的本身作用,而使用單引號則裡面的特殊字元全部失去它本身的作用。

【系統和使用者的環境變數配置檔案】

系統變數的儲存位置:

/etc/profile:這個檔案預設了幾個重要的變數,例如 PATHUSERLOGNAMEMAIL INPUTRC
HOSTNAME
HISTSIZEumask 等等。上節已經列出。

/etc/bashrc:這個檔案主要預設 umask以及 PS1

.bash_profile:定義了使用者的個人化路徑與環境變數的檔名稱。每個使用者都可使用該檔案輸入專用

於自己使用的 shell 資訊,當用戶登入時,該檔案僅僅執行一次。

.bashrc:該檔案包含專用於你的 shell bash 資訊,當登入時以及每次開啟新的 shell ,該該檔案被讀取。例如你可以將使用者自定義的 alias 或者自定義變數寫到這個檔案中。

.bash_history:記錄命令歷史用的。

.bash_logout:當退出 shell時,會執行該檔案。可以把一些清理的工作放到這個檔案中。

shell中的特殊符號】

* :零個或多個任意字元。

[[email protected]~]#ls-d1*
1111.txt1.txt

? :一個任意字元(數字或者字元)。

[[email protected]~]#ls-d1?
11

#:註釋符號。

[[email protected]~]#ls-l#列出訊息資訊
total72
drwxr-xr-x.3rootroot4096Oct901:5211
-rw-r--r--.1rootroot8Oct2418:4811.txt
-rw-r--r--.1rootroot0Oct1212:541.txt
-rw-r--r--.1rootroot1576Oct1212:532.txt
-rw-------.1rootroot3332Oct101:28anaconda-ks.cfg
-rw-r--r--.1rootroot40356Oct101:28install.log
-rw-r--r--.1rootroot9154Oct101:27install.log.syslog

\ :脫意符號(變為普通無意義的字元)。

[[email protected]~]#cat11.txt\*
cat:11.txt*:Nosuchfileordirectory


|:管道符(前面已經總結)。

$: 變數前的識別符號或者和結合用(前面一節已經總結)。

;:執行兩個以上命令的分隔符。

[[email protected]~]#ls11.txt;cat11.txt
11.txt
aaa
aaa

~ :特殊符號。家目錄:/root;普通使用者:/home/usname

[[email protected]~]#cd~#家目錄
[[email protected]~]#pwd
/root
[[email protected]~]#suchensenlin#普通使用者:陳森林
[[email protected]root]$pwd
/root
[[email protected]root]$

$ :如果想把一條命令放到後臺執行的話,則需要加上這個符號。通常用於命令執行時間非常長的情況。

[[email protected]root]$sleep30&
[1]3394
[[email protected]root]$jobs
[1]+Runningsleep30&

[] :中間字元任意一個。

[[email protected]~]#ls-dchen[1-3]
chen1chen2chen3

cut 命令-擷取】

語法:cut -d ’分隔字元‘ dfc 數字

-d:後面指定分隔符,需要加單引號;

-f :指定第幾段;

-c 後面只有一個數字表示擷取第幾個字元,後面跟一個數字區域,表示擷取從幾到幾。

[[email protected]~]#cat11.txt|cut-d';'-f1|head-n3
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

sort命令-排序】

語法: sort -t 分隔符 [-kn1,n2] [-nru]

-t 分隔符:後面指定分隔符,需要加單引號;
-n
:使用純數字排序;
-r
:反向排序;
-u
:去重複。

[[email protected]~]#head-n511.txt#如果sort不加任何選項,則從首字元向後,依次按ASCII碼值進行比較,最後將他們按升序輸出.
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[[email protected]~]#head-n511.txt|sort-t:-k3,5-r
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
root:x:0:0:root:/root:/bin/bash

-k3,5 表示從第 3 到第 5 區域間的字串排序,-r 表示反向排序。

wc命令-統計】

wc :統計指定檔案中的位元組數、字數、行數,並將統計結果顯示輸出。該命令統計指定檔案中的位元組數、字數、行數。如果沒有給出檔名,則從標準輸入讀取。wc同時也給出所指定檔案的總統計數。

-c 統計位元組數;
-l
統計行數;
-m
統計字元數。這個標誌不能與 -c 標誌一起使用;
-w
統計字數。一個字被定義為由空白、跳格或換行字元分隔的字串;
-L
列印最長行的長度。

[[email protected]~]#wc-l11.txt
3111.txt
[[email protected]~]#wc-m11.txt
144511.txt
[[email protected]~]#wc-w11.txt
4611.txt
[[email protected]~]#wc-L11.txt
7911.txt
[[email protected]~]#wc-c11.txt
144511.txt

uniq tee 命令】

[[email protected]~]#sort1.txt|uniq
11
111
1111
11111
2222
333
3333
33333
4444
5
666
777
[[email protected]~]#sort1.txt|uniq-c
1011
10111
101111
111111
12222
20333
103333
133333
14444
105
9666
10777

tee 命令,後跟檔名,類似與重定向’>’,但是比重定向多了一個功能,在把檔案寫入後面所跟的檔案中的同時,還顯示在螢幕上。

[[email protected]~]#echo"qwqwqwqwqw"|tee1.txt
qwqwqwqwqw
[[email protected]~]#cat1.txt
qwqwqwqwqw

tr split 命令】

tr :替換字元(特殊字元);也可大小寫轉換。

-d :刪除字元;

-s:去重複。

[[email protected]~]#head-n3cat1.txt|tra-zA-Z
head:cannotopen`cat'forreading:Nosuchfileordirectory
==>1.TXT<==
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN
DAEMON:X:2:2:DAEMON:/SBIN:/SBIN/NOLOGIN

split 用於切割文件。

-b:依照大小切割。單位為byte

-l:行數切割;

[[email protected]~]#mkdirsplit_dir
[[email protected]~]#cd!$
cdsplit_dir
[[email protected]split_dir]#cp/etc/passwd./
[[email protected]split_dir]#split-b500passwd
[[email protected]split_dir]#ls
passwdxaaxabxac
[[email protected]split_dir]#

shell 中連線符(並且、和、或者)

在上面剛剛提到了分號,用於多條命令間的分隔符。另外還有兩個可以用於多條命令中間的特殊符號,
那就是 &||,下面把這幾種情況全列出:
(1) command1 ; command2
(2) command1 && command2
(3) command1 || command2
使用 ; 時,不管command1 是否執行成功都會執行command2
使用 && 時,只有 command1 執行成功後,command2才會執行,否則 command2 不執行。
使用 || 時,command1執行成功後 command2 不執行,否則去執行command2,總之 command1 command2 總有一條命令會執行。

grep 過濾】

-c :列印符合要求的行數;
-n
:在輸出符合要求的行的同時連同行號一起輸出;
-v
:列印不符合要求的行
-A
:後跟一個數字(有無空格都可以),例如 –A2 則表示列印符合要求的行以及下面兩行;
-B
:後跟一個數字,例如 –B2 則表示列印符合要求的行以及上面兩行
-C
:後跟一個數字,例如 –C2 則表示列印符合要求的行以及上下各兩行;
-r :
會把目錄下面所有的檔案全部遍歷;
--color:
把匹配到的關鍵詞用紅色標識;

[[email protected]~]##grep-n'root'1.txt過濾出帶有某個關鍵字的行並輸出行號。
[[email protected]~]##grep-n-v'root'1.txt過濾出不帶有某個關鍵字的行並輸出行號。
[[email protected]~]##grep'[0-9]'1.txt過濾包含數字的行
[[email protected]~]##grep-n-v'[0-9]'1.txt過濾出所有包含數字的行並輸出行號
[[email protected]~]##grep-n-v'^#'1.txt去除所有以'#'開頭的行
[[email protected]~]##grep-v'^#'1.txt|grep-v'^$'去除所有以'#'開頭的行和空行
[[email protected]~]##grep'^[a-zA-Z]'1.txt過濾出以英文字母開頭的行
[[email protected]~]##grep'^[0-9]'1.txt過濾出以非數字開頭的行
[[email protected]~]##grep'r.o'1.txt;grep'r*t'1.txt;grep'r.*t'1.txt過濾任意一個或多個字元
[[email protected]~]##grep-A1'root'1.txt過濾出包含root的行以及下面一行
[[email protected]~]##grep-B1'root'1.txt過濾出包含root的行以及上面一行
[[email protected]~]##grep'o\{2\}'1.txt指定過濾字元次數

. 表示任意一個字元;
*
表示零個或多個前面的字元;
.*
表示零個或多個任意字元,空行也包含在內。

egrep 命令】

egrep 工具是 grep 工具的擴充套件,它可以實現所有 grep 的功能,grep -E == egrep

[[email protected]~]#aliasegrep='egrep--color'#做別名
[[email protected]~]##egrep'o+'1.txt匹配1個或1個以上+前面的字元
[[email protected]~]##egrep'o?'1.txt匹配0個或者1個?前面字元
[[email protected]~]##egrep'roo|passwd'1.txt匹配roo或者匹配passwd
[[email protected]~]##egrep'(oo)+'1.txt匹配1個或者多個'oo';括號表示一個整體

. 表示任意一個字元(包括特殊字元);
*
表示零個或多個*前面的字元;
.*
表示任意個任意字元(包含空行);
+
表示 1 個或多個+前面的字元;
?表示 0 個或 1 ?前面的字元;
其中,+? grep 不支援,egrep 才支援。

sed 命令】
sed
可以實現 grep 的大部分功能,而且還可以查詢替換。

列印指定行

[[email protected]~]#sed'10'p-n1.txt
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
[[email protected]~]#sed'1,4'p-n1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin


[[email protected]~]#sed'15,$'p-n1.txt
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTPUser:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:Systemmessagebus:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxduser:/:/sbin/nologin
vcsa:x:69:69:virtualconsolememoryowner:/dev:/sbin/nologin
rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
avahi-autoipd:x:170:170:AvahiIPv4LLStack:/var/lib/avahi-autoipd:/sbin/nologin
pulse:x:498:496:PulseAudioSystemDaemon:/var/run/pulse:/sbin/nologin
haldaemon:x:68:68:HALdaemon:/:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
saslauth:x:497:76:Saslauthduser:/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
sshd:x:74:74:Privilege-separatedSSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
chensenlin:x:500:500:CentOS6.7:/home/chensenlin:/bin/bash

列印包含”root“(某個字串)的行;

[[email protected]~]#sed-n'/root/'p1.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

特殊符號;

[[email protected]~]#sed-n'/ro.t/'p1.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[[email protected]~]#sed-n'/^roo/'p1.txt
root:x:0:0:root:/root:/bin/bash

sed 不識別+|{}()等符號,需要藉助脫義符號\或者使用選項-r

-e 實現多工;

[[email protected]~]#sed-e'root/p'-e'/body/p'-n1.txt
nobody:x:99:99:Nobody:/:/sbin/nologin

刪除指定的行;

[[email protected]~]#sed'/root/d'1.txt
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

替換的使用:s是替換;g是全域性替換;

[[email protected]~]#sed'1.2s/ot/to/g'1.txt

刪除所有數字和刪除所有非數字;

[[email protected]~]##sed's/[0-9]//g'1.txt
[[email protected]~]##sed's/[^0-9]//g'1.txt

調換兩個字串位置;

[[email protected]~]#head-n21.txt|sed-r's/(root)(.*)(bash)/\3\2\1/'–

i :直接修改檔案內容;

[[email protected]~]#sed-i's/ot/to/g'1.txt

awk 命令】

擷取文件中的某段

[[email protected]~]#awk-F':''{print$1}'1.txt

說明: -F 指定分隔符號為 :

也可以使用自定義字元連線每個段

[[email protected]~]#awk-F':''{print$1"#"$2"#"$3"#"$4}'1.txt

或者使用 awk 內部變數 OFS,格式如下:

#awk-F':''{OFS="#"}{print$1,$2,$3,$4}'1.txt

匹配字元或字串

[[email protected]~]#awk'/oo/'1.txt

針對某個段匹配

[[email protected]~]#awk-F':''$1~/oo/'1.txt

多次匹配

[[email protected]~]#awk-F':''/root/{print$1,$3};$1~/test/;$3~/20/'1.txt

條件操作符==, >,<,!=,>=;<=

第三段為 0

[[email protected]~]#awk-F':''$3=="0"'1.txt;

第三段大於等於 500

[[email protected]~]#awk-F':''$3>=500'1.txt;

說明:當比較數字時,不能加雙引號,如果寫成$3>="500"就不符合我們的需求了。

第七段不是'/sbin/nologin'

[[email protected]~]#awk-F':''$7!="/sbin/nologin"'1.txt;

第三段小於第四段

[[email protected]~]#awk-F':''$3<$4'1.txt;

第三段大於 5,並且第三段小於 7

[[email protected]~]#awk-F':''$3>5&&$3<7'1.txt

第三段大於 5 或者第七段為'/bin/bash'

[[email protected]~]#awk-F':''$3>"5"||$7=="/bin/bash"'1.txt

awk 內建變數 NF(段數) NR(行數)

[[email protected]~]#head-n31.txt|awk-F':''{printNF}'
[[email protected]~]#head-n31.txt|awk-F':''{print$NF}'
[[email protected]~]#head-n31.txt|awk-F':''{printNR}'

列印 20 行以後的行

[[email protected]~]#awk'NR>20'1.txt

列印 20 行以後並且第一段包含'ssh'的行

[[email protected]~]#awk-F':''NR>20&&$1~/ssh/'1.txt

更改某個段的值

[[email protected]~]#awk-F':''$1="root"'1.txt

數學計算, 把第三段和第四段值相加,並賦予第七段

[[email protected]~]#awk-F':''{$7=$3+$4;print$0}'1.txt

但是這樣的話,相當於改變了原來文字的結構,所以 print $0 的時候就不再有分隔符顯示。如果想顯

示分隔符需要藉助 OFS

[[email protected]~]#awk-F':''{OFS=":"}{$7=$3+$4;print$0}'1.txt

計算第三段的總和

[[email protected]~]#awk-F':''{(tot=tot+$3)};END{printtot}'1.txt

awk 中也可以使用 if 關鍵詞

[[email protected]~]#awk-F':''{if($1=="root")print$0}'1.txt

!!總結完畢。


轉載於:https://blog.51cto.com/chensenlin/1706057