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


 

本節內容

 

1.shell簡介

2. shell分類

3. 查看shell

4. 第一個shell腳本

5. shell編程常用命令

  5.1 grep

  5.2 cut

  5.3 sort

  5.4 uniq

  5.5 seq

  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 

 

 

一、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

 

二、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

 

 三、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

 

 四、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

 

五、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

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM