Shell編程(week4_day1)--技術流ken

 

本節內容

 

1.shell簡介html

2. shell分類前端

3. 查看shellpython

4. 第一個shell腳本正則表達式

5. shell編程經常使用命令shell

  5.1 grep數據庫

  5.2 cut編程

  5.3 sortvim

  5.4 uniq後端

  5.5 seqcentos

  5.6 tr

6. 課後做業

 

前言

 

什麼是腳本?

腳本簡單地說就是一條條的文字命令(一些指令的堆積),這些文字命令是能夠看到的(如能夠用記事本打開查看、編輯)。

常見的腳本: JavaScript(JS,前端),VBScript, ASP,JSP,PHP(後端),SQL(數據庫操做語言),Perl,Shell,python,Ruby,JavaFX, Lua等。

 

爲何要學習和使用shell?

Shell屬於內置的腳本

程序開發的效率很是高,依賴於功能強大的命令能夠迅速地完成開發任務(批處理)

語法簡單,代碼寫起來比較輕鬆,簡單易學

 

1.1  Shell 簡介

 

Shell 是一個 C 語言編寫的腳本語言,它是用戶與 Linux 的橋樑,用戶輸入命令交給 Shell 處理, Shell 將相應的操做傳遞給內核(Kernel),內核把處理的結果輸出給用戶。

 下面是流程示意圖:

 

 

Shell 既然是工做在 Linux 內核之上,那咱們也有必要了解下 Linux 相關知識。 Linux 是一套免費試用和自由傳播的類 Unix 操做系統,是一個基於 POSIX 和 UNIX 的多用戶、多任 務、支持多線程和多 CPU 的操做系統。

1983 年 9 月 27 日,Richard Stallman(理查德-馬修-斯托曼)發起 GNU 計劃,它的目標是建立一 套徹底自由的操做系統。爲保證 GNU 軟件能夠自由的使用、複製、修改和發佈,全部的 GNU 軟件都 有一份在禁止其餘人添加任何限制的狀況下受權全部權利給任何人的協議條款,GNU 通用公共許可 證(GNU General Plubic License,GPL),說白了就是不能作商業用途。

GNU 是"GNU is Not Unix"的遞歸縮寫。UNIX 是一種普遍使用的商業操做系統的名稱。

1985 年,Richard Stallman 又創立了自由軟件基金會(Free Software Foundation,FSF)來爲 GNU 計劃提供技術、法律以及財政支持。

1990 年,GNU 計劃開發主要項目有 Emacs(文本編輯器)、GCC(GNU Compiler Collection,GNU 編 譯器集合)、Bash 等,GCC 是一套 GNU 開發的編程語言編譯器。還有開發一些 UNIX 系統的程序庫和 工具。

1991 年,Linuxs Torvalds(林納斯- 託瓦茲)開發出了與 UNIX 兼容的 Linux 操做系統內核並在 GPL 條款下發布。

1992 年,Linux 與其餘 GUN 軟件結合,徹底自由的 GUN/Linux 操做系統正式誕生,簡稱 Linux。

1995 年 1 月,Bob Young 創辦 ACC 公司,以 GNU/Linux 爲核心,開發出了 RedHat Linux 商業版。

Linux 基本思想有兩點:第一,一切都是文件;第二,每一個軟件都有肯定的用途。

與 Unix 思想十分 相近。 Kernel Shell 命令 用戶 解析命令 並傳遞給內核 執行動做

 

1.2  Shell 分類

 

1.2.1  圖形界面 Shell(GUI Shell)

 GUI 爲 Unix 或者類 Unix 操做系統構造一個功能完善、操做簡單以及界面友好的桌面環境。主流桌 面環境有 KDE,Gnome 等。

 

1.2.2  命令行界面 Shell(CLI Shell)

CLI 是在用戶提示符下鍵入可執行指令的界面,用戶經過鍵盤輸入指令,完成一系列操做。 在 Linux 系統上主流的 CLI 實現是 Bash,是許多 Linux 發行版默認的 Shell。還有許多 Unix 上 Shell,例如 tcsh、csh、ash、bsh、ksh 等。

 

1.3  查看shell

 

Shell 是一個程序,通常都是放在/bin或者/user/bin目錄下,當前 Linux 系統可用的 Shell 都記錄在/etc/shells文件中。/etc/shells是一個純文本文件,你能夠在圖形界面下打開它,也可使用 cat 命令查看它。

經過 cat 命令來查看當前 Linux 系統的可用 Shell:

$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh

 

在現代的 Linux 上,sh 已經被 bash 代替,/bin/sh每每是指向/bin/bash的符號連接。 

若是你但願查看當前 Linux 的默認 Shell,那麼能夠輸出 SHELL 環境變量:

$ echo $SHELL
/bin/bash

 

輸出結果代表默認的 Shell 是 bash。 

SHELL Linux 系統中的環境變量,它指明瞭當前使用的 Shell 程序的位置,也就是使用的哪一個 Shell。

 

1.4 第一個 Shell 腳本

 

主要講解在大多 Linux 發行版下默認 Bash Shell。Linux 系統是 RedHat 下的 CentOS 操做系 統,徹底免費。與其商業版 RHEL(Red Hat Enterprise Linux)出自一樣的源代碼,不一樣的是 CentOS 並不包含封閉源代碼軟件和售後支持。

  vim 打開 test.sh,編寫:

 # vim test.sh
 #!/bin/bash
echo "Hello world!"

 

第一行指定解釋器,第二行打印 Hello world!

 寫好後,開始執行,執行 Shell 腳本有三種方法:

 

方法 1:直接用 bash 解釋器執行

# bash test.sh
Hello world!

當前終端會新生成一個子 bash 去執行腳本。

 

方法 2:添加可執行權限

 # ll
test.sh -rw-r--r--. 1 root root 32 Aug 18 01:07 test.sh
 # chmod +x test.sh
 # ./test.sh
-bash: ./test.sh: Permission denied
# chmod +x test.sh
# ./test.sh
Hello world!

這種方式默認根據腳本第一行指定的解釋器處理,若是沒寫以當前默認 Shell 解釋器執行。 

注意,這裏在運行時必定要寫成 ./test.sh(絕對路徑亦可),而不是 test.sh,運行其它二進制的程序也同樣,直接寫 test.sh,Linux 系統會去 PATH(環境變量 裏尋找有沒有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 裏,你的當前目錄一般不在 PATH 裏,因此寫成 test.sh 是會找不到命令的,要用 ./test.sh 告訴系統說,就在當前目錄找。

 

方法 3:source 命令執行,以當前默認 Shell 解釋器執行

# source test.sh
Hello world!

 

source filename 與 bash filename 及./filename執行腳本的區別

 

  • 當shell腳本具備可執行權限時,用bash filename與./filename執行腳本是沒有區別得。./filename是由於當前目錄沒有在PATH中,因此」.」是用來表示當前目錄的。
  • source filename:這個命令其實只是簡單地讀取腳本里面的語句依次在當前shell裏面執行,沒有創建新的子shell。那麼腳本里面全部新建、改變變量的語句都會保存在當前shell裏面。
  • bash filename 從新創建一個子shell,在子shell中執行腳本里面的語句,該子shell繼承父shell的環境變量,但子shell新建的、改變的變量不會被帶回父shell。


最後一句話什麼意思那?

子shell新建變量,在父shell中不會生效:

 

咱們可使用命令pstree查看咱們當前所處的位置

須要下載

[root@ken ~]# yum search pstree
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
==================================================== Matched: pstree ====================================================
psmisc.x86_64 : Utilities for managing processes on your system
texlive-pst-tree.noarch : Trees, using pstricks
[root@ken ~]# yum install psmisc -y

 

使用pstree

 

咱們再次執行bash,就會進入到另一個子shell中

這個時候咱們在這個子shell中定義一個變量,發現能夠正確打印出來

[root@ken ~]# age=25
[root@ken ~]# echo $age
25

 

如今咱們退出當前的shell,即進入了當前子shell中的父shell中,再次打印咱們剛纔定義的變量

能夠發現如今已經沒法獲取到咱們剛纔定義的變量值了。

 

子shell繼承父shell的環境變量:

 

咱們把環境變量定義到profile的一個子文件中,並使用source執行該文件並生效

打開一個子shell,定義在父shell中的環境變量依然有效

反之,這種操做在子shell中操做,父shell也不能繼承

[root@ken ~]# cat /etc/profile.d/ken.sh
export name=ken
[root@ken ~]# source /etc/profile.d/ken.sh
[root@ken ~]# echo $name
ken
[root@ken ~]# bash
[root@ken ~]# echo $name
ken

 

shell編程練習:

 練習1:使用root用戶賬號建立並執行test2.sh,實現建立一個shelltest用戶,並在其家目錄中新建文件try.html。

 練習2:統計當前系統總共有多少用戶

 練習3:統計當前已經安裝的軟件數量

 

1.5   shell編程幾個經常使用命令

 

grep命令詳解

 

過濾來自一個文件或標準輸入匹配模式內容。

除了 grep 外,還有 egrep。egrep 是 grep 的擴展,至關於 grep -E。

Usage: grep [OPTION]... PATTERN [FILE]...

 

grep經常使用選項詳解

 

                 選項             

                  描述                                     

-E,--extended-regexp                                

模式是擴展正則表達式(ERE)                                

 -i,--ignore-case

忽略大小寫

 -n,--line-number

打印行號

 -o,--only-matching

只打印匹配的內容

 -c,--count

只打印每一個文件匹配的行數

 -B,--before-context=NUM

打印匹配的前幾行

 -A,--after-context=NUM

打印匹配的後幾行

-C,--context=NUM

打印匹配的先後幾行

--color[=WHEN],

 匹配的字體顏色

-v,--invert-match

 打印不匹配的行

 

 grep案例演示

 

1. -i, 忽略大小寫

[root@ken ~]# echo "this is ken THIS IS KEN" | grep -i 'ken'
this is ken THIS IS KEN
[root@ken ~]# echo "this is ken THIS IS KEN" | grep  'ken'
this is ken THIS IS KEN

 

2. -n,打印行號

[root@ken ~]# grep -n 'root' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

 

 3. -o,只打印匹配的內容

[root@ken ~]# echo "this is ken THIS IS KEN" | grep -o 'ken'
ken
[root@ken ~]# echo "this is ken THIS IS KEN" | grep  'ken'
this is ken THIS IS KEN

 

4. -c,打印文件匹配的行數

[root@ken ~]# grep  -c 'root' /etc/passwd
2
[root@ken ~]# grep  'root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

 

5. -B,打印匹配的前幾行

[root@ken ~]# grep -B 3 'root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
--
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

 

6.-A,打印匹配的後幾行

[root@ken ~]# grep -A 3 'root' /etc/passwd
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
--
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

 

7.-C,打印匹配的先後幾行

[root@ken ~]# grep -C 3 'root' /etc/passwd
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
--
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

 

8. --color,在centos7中已經默認爲 grep --color,在centos6中須要加上--color纔會顯示顏色

[root@ken ~]# alias grep 
alias grep='grep --color=auto'

 

9. -v, 打印不匹配的行

[root@ken ~]# echo -e "hi\nthis is ken\nncie to meet you\nbye " | grep -v 'ken'
hi
ncie to meet you
bye 

 

 

1、cut命令

 

語法

cut  [-bn] [file]
cut [-c] [file]
cut [-df] [file]
 

使用說明:

cut 命令從文件的每一行剪切字節、字符和字段並將這些字節、字符和字段寫至標準輸出。

若是不指定 File 參數,cut 命令將讀取標準輸入。必須指定 -b-c -f 標誌之一。

 

經常使用參數:

  • -c :以字符爲單位進行分割。

  • -d :自定義分隔符。

  • -f :與-d一塊兒使用,指定顯示哪一個區域。

 

經常使用實例演示1: -c:以字符爲單位進行分隔

[root@ken ~]# echo "this is ken" | cut -c  4
s
[root@ken ~]# echo "this is ken" | cut -c 5
 
[root@ken ~]# echo "this is ken" | cut -c 2
h

  [root@ken ~]# echo "this is ken" | cut -c 1-5
  this

 

經常使用實例演示2:-d,-f:自定義分隔符並進行指定顯示

1.從標準輸入讀取

[root@ken ~]# echo 'this is ken' | cut -d' ' -f3
ken

  [root@ken ~]# echo "name:ken age:25 gender:male" | cut -d ' ' -f2
  age:25

 

2.從文件中讀取

[root@ken ~]# echo "this is ken">test
[root@ken ~]#  cut -d' ' -f3 test
ken

 

2、sort命令

 

Linux sort命令用於將文本文件內容加以排序。

sort可針對文本文件的內容,以行爲單位來排序。

語法:

sort [-bcdfimMnr][-o<輸出文件>][-t<分隔字符>][+<起始欄位>-<結束欄位>][--help][--verison][文件]
 

經常使用參數說明

  • -k:根據切割後的那一段進行排序
  • -n 依照數值的大小排序(默認是根據字符進行排序)。
  • -r 以相反的順序來排序。
  • -t<分隔字符> 指定排序時所用的欄位分隔字符。
  • -u:去除重複的行(只要那個指定的字段重複,就認定是重複的行)

 

實例一:默認排序

在使用sort命令以默認的式對文件的行進行排序,使用的命令以下:

[root@ken ~]# cat test
6 this is ken
2 this is ken
5 this is ken
6 this is ken
1 this is ken
8 this is ken
[root@ken ~]# sort test
1 this is ken
2 this is ken
5 this is ken
6 this is ken
6 this is ken
8 this is ken

sort 命令將以默認的方式將文本文件的第一列以ASCII 碼的次序排列,並將結果輸出到標準輸出。

 

實例二:取出排名前三

[root@ken ~]# sort -r test | head -3
8 this is ken
6 this is ken
6 this is ken

 

實例三:對文件中的內容按照e分割第二部分進行排序

[root@ken ~]# sort -t 'e' -k 2 test
6 this:is:ke1
5 this:is:ke2
6 this:is:ke3
2 this:is:ke4
1 this:is:ke6
8 this:is:ke7
[root@ken ~]# sort -t 'e' -k 2  -r test
8 this:is:ke7
1 this:is:ke6
2 this:is:ke4
6 this:is:ke3
5 this:is:ke2
6 this:is:ke1

 

實例四:去除重複的行

[root@ken ~]# sort test
1 this:is:ke6
2 this:is:ke4
2 this:is:ke4
2 this:is:ke4
2 this:is:ke4
5 this:is:ke2
6 this:is:ke1
6 this:is:ke3
8 this:is:ke7
[root@ken ~]# sort -u test
1 this:is:ke6
2 this:is:ke4
5 this:is:ke2
6 this:is:ke1
6 this:is:ke3
8 this:is:ke7

 

 3、uniq命令

做用:

去除重複的行(相鄰且相同,認定爲重複)

選項:

-c:在行首用數字表示該行出現了多少次

-u:僅僅顯示那些沒有出現重複過的行

 

實例一:統計行數

[root@ken ~]# uniq -c test
      1 6 this:is:ke3
      4 2 this:is:ke4
      1 5 this:is:ke2
      1 6 this:is:ke1
      1 1 this:is:ke6
      1 8 this:is:ke7

 

實例二:將文件中相同的行去重

[root@ken ~]# sort test | uniq
1 this:is:ke6
2 this:is:ke4
5 this:is:ke2
6 this:is:ke1
6 this:is:ke3
8 this:is:ke7

 

 4、seq命令

做用:

生成一個數組序列

格式:

seq [start  [step]] stop

 

實例:

[root@ken ~]# seq 5       #終止位5
1
2
3
4
5
[root@ken ~]# seq 2 5     #起始位2,終止位5
2
3
4
5
[root@ken ~]# seq 2 2 10  #起始位2,步長爲2,終止位10
2
4
6
8
10

 

5、tr命令

 

做用:

Linux tr 命令用於轉換或刪除文件中的字符。

tr 指令從標準輸入設備讀取數據,通過字符串轉譯後,將結果輸出到標準輸出設備。

 

a-z 任意小寫

A-Z 任意大寫

0-9 任意數字

 

實例一:替換大小寫

[root@ken ~]# echo "this is ken" | tr a-z A-Z
THIS IS KEN
[root@ken ~]# echo "THIS IS KEN" | tr A-Z a-z
this is ken

 

實例二:刪除特定字符串

s這個字符串都會被刪掉

[root@ken ~]# cat test
6 this:is:ke3
2 this:is:ke4
2 this:is:ke4
2 this:is:ke4
2 this:is:ke4
5 this:is:ke2
6 this:is:ke1
1 this:is:ke6
8 this:is:ke7
[root@ken ~]# cat test | tr -d 's'
6 thi:i:ke3
2 thi:i:ke4
2 thi:i:ke4
2 thi:i:ke4
2 thi:i:ke4
5 thi:i:ke2
6 thi:i:ke1
1 thi:i:ke6
8 thi:i:ke7

 

課後做業

 

做業1. 獲取主機IP地址,獲取結果僅顯示IP,例如:172.20.10.2(使用盡量多的方法)

 

做業2. 有以下一個文件,文件內容以下。

請把下方的內容複製到你的一個文件中,並完成以下需求

需求1. 統計出各個網址出現的次數

需求2. 按照出現次數排序(升序)

需求3. 取出出現次數排名前兩名的網址

[root@ken ~]# cat ken.sh
http://www.baidu.com
http://www.baidu.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.sina.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.qq.com
http://www.qq.com
http://www.qq.com
http://www.qq.com
http://www.qq.com
http://www.qq.com
http://www.qq.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.taobao.com
http://www.taobao.com
http://www.taobao.com
http://www.taobao.com
http://www.taobao.com
http://www.taobao.com
http://www.taobao.com
http://www.taobao.com
http://www.taobao.com
http://www.taobao.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com

 

課後做業答案

 

做業1:

第一種方法:

[root@ken ~]# ip a | grep global | cut -d " " -f 6 | cut -d "/" -f1
172.20.10.6

 

第二種方法:

[root@ken ~]# ip a | grep global | cut -d "b" -f 1 | tr -d [a-z] | cut -d "/" -f 1 | tr -d " "
172.20.10.6

 

第三種方法:

[root@ken ~]# ip a | grep global | tr -d [a-z] | tr -d " " | cut -d "/" -f1
172.20.10.6

方法有不少,你們儘量的本身多思考哦!

 

做業2:

1. 統計出各個網址出現的次數

[root@ken ~]# cat ken.sh  | cut -d '/' -f3 | sort | uniq -c
     19 www.baidu.com
      7 www.qq.com
     12 www.sina.com
     10 www.taobao.com

 

2. 按照出現次數排序(升序)

[root@ken ~]# cat ken.sh  | cut -d '/' -f3 | sort | uniq -c | sort -n
      7 www.qq.com
     10 www.taobao.com
     12 www.sina.com
     19 www.baidu.com

 

3.  取出出現次數排名前兩名的網址

[root@ken ~]# cat ken.sh  | cut -d '/' -f3 | sort | uniq -c | sort -n -r | head -2
     19 www.baidu.com
     12 www.sina.com

 

思考:還有更多的辦法嗎?

相關文章
相關標籤/搜索