shell編程基礎(一)

編程語言排行

image.png

學好shell編程所需的基礎知識

image.png

1.1.1 爲什麼學Shell

Shell腳本語言是實現Linux/UNIX系統管理及自動化運維所必備的重要工具, Linux/UNIX系統的底層及基礎應用軟件的核心大都涉及Shell腳本的內容。每一個合格 Linux系統管理員或運維工程師,都需要能夠熟練地編寫Shell腳本語言,並能夠閱讀系統及各類軟件附帶的Shell腳本內容。只有這樣才能提升運維人員的工作效率,適應曰益複雜的工作環境,減少不必要的重複工作,從而爲個人的職場發展奠定較好的基礎

1.1.2 什麼是shell

Shell是一個命令解釋器,它在操作系統的最外層,負責直接與用戶對話,把用戶的輸入解釋給操作系統,並處理各種各樣的操作系統的輸出結果,輸出屏幕返回給用戶。

這種對話方式可以是:

交互的方式:從鍵盤輸入命令,通過/bin/bash的解析,可以立即得到Shell的迴應

非交互的方式: 腳本

1.1.3 什麼是Shell腳本

        Shell腳本三要素:

        命令語句

        變量

        邏輯判斷

 命令、變量和流程控制語句(邏輯判斷)等有機的結合起來

 shell腳本擅長處理純文本類型的數據,而linux中,幾乎所有的配置文件,日誌,都是純文本類型文件

1.1.4 腳本語言的種類

一、編譯型語言

定義:指用專用的編譯器,針對特定的操作平臺(操作系統)將某種高級語言源代碼一次性翻譯成可被硬件平臺直接運行的二進制機器碼(具有操作數,指令、及相應的格式),這個過程叫做編譯(./configure  make makeinstall );編譯好的可執行性文件(.exe),可在相對應的平臺上運行(移植性差,但運行效率高)。。

典型的編譯型語言有, C語言、C++等。

另外,Java語言是一門很特殊的語言,Java程序需要進行編譯步驟,但並不會生成特定平臺的二進制機器碼,它編譯後生成的是一種與平臺無關的字節碼文件(*.class)(移植性好的原因),這種字節碼自然不能被平臺直接執行,運行時需要由解釋器解釋成相應平臺的二進制機器碼文件;大多數人認爲Java是一種編譯型語言,但我們說Java即是編譯型語言,也是解釋型語言也並沒有錯。

二、解釋型語言

定義:指用專門解釋器對源程序逐行解釋成特定平臺的機器碼並立即執行的語言;相當於把編譯型語言的編譯鏈接過程混到一起同時完成的。

解釋型語言執行效率較低,且不能脫離解釋器運行,但它的跨平臺型比較容易,只需提供特定解釋器即可。

常見的解釋型語言有, Python(同時是腳本語言)與Ruby等。

python不如C安全

三、腳本語言

定義:爲了縮短傳統的編寫-編譯-鏈接-運行(edit-compile-link-run)過程而創建的計算機編程語言。

特點:程序代碼即是最終的執行文件,只是這個過程需要解釋器的參與,所以說腳本語言與解釋型語言有很大的聯繫。腳本語言通常是被解釋執行的,而且程序是文本文件。

典型的腳本語言有,JavaScriptPythonshell等。

其他常用的腳本語句種類

PHP是網頁程序,也是腳本語言。是一款更專注於web頁面開發(前端展示)的腳本語言,例如:Dedecms,discuzPHP程序也可以處理系統日誌,配置文件等,php也可以調用系統命令。

Perl腳本語言。比shell腳本強大很多,語法靈活、複雜,實現方式很多,不易讀,團隊協作困難,但仍不失爲很好的腳本語言,存世大量的程序軟件。MHA高可用Perl寫的

Python,不但可以做腳本程序開發,也可以實現web程序以及軟件的開發。近兩年越來越多的公司都會要求會Python

Shell腳本與php/perl/python語言的區別和優勢?

shell腳本的優勢在於處理操作系統底層的業務 linux系統內部的應用都是shell腳本完成)因爲有大量的linux系統命令爲它做支撐。2000多個命令都是shell腳本編程的有力支撐,特別是grepawksed等。例如:一鍵軟件安裝、優化、監控報警腳本,常規的業務應用,shell開發更簡單快速,符合運維的簡單、易用、高效原則.

  PHPPython優勢在於開發運維工具以及web界面的管理工具,web業務的開發等。處理一鍵軟件安裝、優化,報警腳本。常規業務的應用等php/python也是能夠做到的。但是開發效率和複雜比用shell就差很多了。

系統環境說明

[root@kai scripts]# cat /etc/redhat-release

CentOS Linux release 7.4.1708 (Core)

[root@kai scripts]# uname -r

3.10.0-693.el7.x86_64

[root@kai scripts]# getenforce Disabled

[root@kai scripts]# systemctl status firewalld.service

● firewalld.service - firewalld - dynamic firewall daemon

Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)

Active: inactive (dead)

Docs: man:firewalld(1)

1.1.5 系統中的shell

查看系統中的命解釋器

[root@kai ~]# cat /etc/shells

/bin/sh

/bin/bash

/sbin/nologin

/usr/bin/sh

/usr/bin/bash

/usr/sbin/nologin

常用操作系統的默認shell

1.LinuxBourne Again shellbash

2.SolarisFreeBSD缺省的是Bourne shellsh

3.AIX下是Korn Shellksh

4.HP-UX缺省的是POSIX shellsh

[root@kai ~]# echo $SHELL

/bin/bash

bash版本

[root@kai scripts]# bash -version

GNU bash, 版本 4.2.46(2)-release (x86_64-redhat-linux-gnu)

Copyright (C) 2011 Free Software Foundation, Inc.

許可證 GPLv3+: GNU GPL 許可證版本3或者更高 <http://gnu.org/licenses/gpl.html>

這是自由軟件,您可以自由地更改和重新發布。

在法律允許的範圍內沒有擔保.

bash 破殼漏洞

使用 命令 env x='() { :;}; echo be careful' bash -c "echo this is a test"

如果返回結果爲一行,則爲正常,

[root@kai ~]# env x='() { :;}; echo be careful' bash -c "echo this is a test"

this is a test

#解決辦法 升級當前的bash版本

yum install update bash

shbash 的關係

[root@kai ~]# ll /bin/sh

lrwxrwxrwx. 1 root root 4 11月 13 11:15 /bin/sh -> bash

/bin /user/bin 的關係

[root@kai ~]# ll /bin -d

lrwxrwxrwx. 1 root root 7 11月 13 11:15 /bin -> usr/bin


1.2腳本書寫規範(培養一個好習慣)

1.2.1 腳本統一存放目錄

[root@kai ~]# mkdir -p /server/scripts/

[root@kai ~]# cd /server/scripts/

1.2.2 選擇解釋器

注意格式 

其中開頭的"#!"字符又稱爲幻數,在執行bash腳本的時候,內核會根據"#!"後的解釋器來確定該用那個程序解釋這個腳本中的內容。

[root@kai scripts]# head -1 /etc/init.d/*

==> /etc/init.d/functions <==

# -*-Shell-script-*-

==> /etc/init.d/netconsole <==

#!/bin/bash

==> /etc/init.d/network <==

#! /bin/bash

1.2.3 編輯腳本使用vim

使用 .vimrc 文件,能夠快速的生成開頭的註釋信息

[root@kai scripts]# cat ~/.vimrc

autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"

func SetTitle()

if expand("%:e") == 'sh'

call setline(1,"#!/bin/bash")

call setline(2, "##############################################################")

call setline(3, "# File Name: ".expand("%"))

call setline(4, "# Version: V1.0")

call setline(5, "# Author: kai")

call setline(6, "# Organization: http://blog.znix.top")

call setline(7, "# Created Time : ".strftime("%F %T"))

call setline(8, "# Description:")

call setline(9, "##############################################################")

call setline(10, "")

endif

endfunc

Shell腳本中,跟在#後面的內容表示註釋。註釋部分不會被執行,僅給人看。註釋可以自成一行,也可以跟在命令後面,與命令同行。要養成寫註釋的習慣,方便自己與他人。

最好不用中文註釋,因爲在不同字符集的系統會出現亂碼(字符集爲zh_CN.UTF-8,爲中文)

1.2.4 文件名規範

         名字要有意義,並且結尾以 .sh 結束

1.2.5 開發的規範和習慣小結

1) 放在統一的目錄

2) 腳本以.sh爲擴展名

3) 開頭指定腳本解釋器。

4) 開頭加版本版權等信息,可配置~/.vimrc文件自動添加。

5) 腳本不要用中文註釋,儘量用英文註釋。

6) 代碼書寫優秀習慣

  a、成對的內容一次性寫出來,防止遺漏,如[  ]' '" "

  b[  ]兩端要有空格,先輸入[  ],退格,輸入2個空格,再退格寫。

  c、流程控制語句一次書寫完,再添加內容。(if 條件 ; then  內容;fi)ddd

  d、通過縮進讓代碼易讀。

  f、腳本中的引號都是英文狀態下的引號,其他字符也是英文狀態。


1.3 shell 腳本的執行

1.3.1 執行腳本的辦法

sh/bash scripts.sh

chown +x ./scripts.sh && ./scripts.sh

source scripts.sh

. (空格) scripts.sh

cat oldboyedu.sh |bash # 效率較低

### source 與 . (點) 的作用(意思一樣)

soucre命令

[root@kai ~]# help source |head -2source: source 文件名 [參數]

在當前 shell 中執行一個文件中的命令。

. ()

[root@kai scripts]# help . |head -2.: . 文件名 [參數]

在當前 shell 中執行一個文件中的命令。

1.3.2 sh  source的區別

image.png

[root@kai scripts]# sh kai_test.sh Hello World!

[root@kai scripts]# echo $kai

# sh 新建一個Shell窗口(新建一個進程)執行一個文件中的命令。

[root@kai scripts]# source kai_test.sh Hello World!

[root@kai scripts]# echo $kai

Hello World!

面試題:

sh test.shecho $user返回的結果___ ?

[root@oldboy scripts]# cat test.sh

#!/bin/bash

user=`whoami`


1.4 Shell的變量

1.4.1 什麼是變量

變量可以分爲兩類:環境變量(全局變量)和普通變量(局部變量)

  環境變量也可稱爲全局變量,可以在創建他們的Shell及其派生出來的任意子進程shell中使用,環境變量又可分爲自定義環境變量和Bash內置的環境變量

  普通變量也可稱爲局部變量,只能在創建他們的Shell函數或Shell腳本中使用。普通變量一般是由開發者用戶開發腳本程序時創建的。

       特殊變量:位置變量和進程變量

1.4.2 環境變量

使用 env/declare/set/export -p 命令查看系統中的環境變量,這三個命令的的輸出方式稍有不同。

[root@kai scripts]# env

XDG_SESSION_ID=1

HOSTNAME=kai

TERM=linux

SHELL=/bin/bash

HISTSIZE=1000

SSH_CLIENT=10.0.0.1 5537 22

SSH_TTY=/dev/pts/0

USER=root

~~~

         輸出一個系統中的 環境變量

[root@kai ~]# echo $LANG

zh_CN.UTF-8

echo $_的作用和Esc+.一樣:取出上條命令的最後一個參數

1.4.3 普通變量

本地變量在用戶當前的Shell生存期的腳本中使用。例如,本地變量OLDBOY取值爲bingbing,這個值在用戶當前Shell生存期中有意義。如果在Shell中啓動另一個進程或退出,本地變量值將無效       

定義普通變量實踐

[root@kai ~]# a=1

[root@kai ~]# b='2'

[root@kai ~]# c="3"

[root@kai ~]# echo "$a"

1

[root@kai ~]# echo "$b"

2

[root@kai ~]# echo "${c}"

提示:$變量名錶示輸出變量,可以用$c${c}兩種用法

小結:連續普通字符串內容賦值給變量,不管用什麼引號或者不用引號,它的內容是什麼,打印變量就輸出什麼

1.4.4 export命令

[root@kai ~]# help export

export: export [-fn] [名稱[=值] ...] 或 export -p

爲 shell 變量設定導出屬性。

標記每個 NAME 名稱爲自動導出到後續命令執行的環境。如果提供了 VALUE

則導出前將 VALUE 作爲賦值。

export命令的說明

當前shell窗口及子shell窗口生效

在新開的shell窗口不會生效,生效需要寫入配置文件

# 定義變量

[root@kai scripts]# KAI=kai

[root@kai scripts]# export KAI1=1

# 當前窗口查看

[root@kai scripts]# echo $KAI

[root@kai scripts]# echo $KAI1

1

# 編寫測試腳本

[root@kai scripts]# vim quanju.sh

#!/bin/bash

echo $KAI

echo $KAI1

# 使用sh執行

[root@kai scripts]# sh quanju.sh

1

# 使用source 執行

[root@kai scripts]# source quanju.sh kai

1

#刪除環境變量

unset KAI

1.4.5 環境變量相關配置文件

/etc/proflie

/etc/bashrc

~/.bashrc

~/.bash_profile

/etc/proflie.d/  # 目錄

四文件讀取順序(CentOS67都一樣)

 /etc/profile

 ~/.bash_profile

 ~/.bashrc

 /etc/bashrc

image.png


文件讀取過程示意圖

驗證四文件讀取順序的方法

sed -i '1a echo "$(date +%T-%s) /etc/profile1" >>/tmp/kai' /etc/profile

sed -i '$a echo "$(date +%T-%s) /etc/profile2" >>/tmp/kai' /etc/profile

sed -i '1a echo "$(date +%T-%s) /etc/bashrc1" >>/tmp/kai' /etc/bashrc

sed -i '$a echo "$(date +%T-%s) /etc/bashrc2" >>/tmp/kai' /etc/bashrc

sed -i '1a echo "$(date +%T-%s) ~/.bashrc1" >>/tmp/kai' ~/.bashrc

sed -i '$a echo "$(date +%T-%s) ~/.bashrc2" >>/tmp/kai' ~/.bashrc

sed -i '1a echo "$(date +%T-%s) ~/.bash_profile1" >>/tmp/kai' ~/.bash_profile

sed -i '$a echo "$(date +%T-%s) ~/.bash_profile2" >>/tmp/kai' ~/.bash_profile

1.4.6 環境變量的知識小結

ü 變量名通常要大寫。

ü 變量可以在自身的Shell及子Shell中使用。

ü 常用export來定義環境變量。

ü 執行env默認可以顯示所有的環境變量名稱及對應的值。

ü 輸出時用“$變量名”,取消時用“unset 變量名”。

ü 書寫crond定時任務時要注意,腳本要用到的環境變量最好先在所執行的Shell腳本中重新定義。

    定時任務的腳本加上 source /etc/profile 防止執行失敗的情況

ü 如果希望環境變量永久生效,則可以將其放在用戶環境變量文件或全局環境變量文件裏。

1.4.7 變量中引號的使用

只有在變量的值中有空格的時候,會使用引號。

單引號與雙引號的區別在於,是否能夠解析特殊符號。

      echo $(ls $(pwd))  推薦,支持嵌套

echo `ls `pwd``  不支持嵌套

[root@kai ~]# name=znix

[root@kai ~]# name2='kai'

[root@kai ~]# name3="http://blog.znix.top"

[root@kai ~]# echo $nameznix

[root@kai ~]# echo $name2kai

[root@kai ~]# echo $name3

http://blog.znix.top

[root@kai ~]# name4='ka i'

[root@kai ~]# echo $name4

ka i

[root@kai ~]# name5="ka i"

[root@kai ~]# echo $name5

ka i

[root@kai ~]# name6='ka i $PWD'

[root@kai ~]# echo $name6

ka i $PWD

[root@kai ~]# name6="ka i $PWD"

[root@kai ~]# echo $name6

ka i /ro

1.4.8 普通變量的要求

1)     內容是純數字、簡單的連續字符(內容中不帶任何空格)時,定義時可以不加任何引號,例如:

a.kaiAge=22

b.NETWORKING=yes

2)     沒有特殊情況時,字符串一律用雙引號定義賦值,特別是多個字符串中間有空格時,例如:

a.NFSD_MODULE="no load"

b.MyName="Oldboy is a handsome boy."

3)     當變量裏的內容需要原樣輸出時,要用單引號(M),這樣的需求極少,例如:

a.OLDBOY_NAME='OLDBOY'

變量使用反引號賦值

[root@kai scripts]# time=`date`

[root@kai scripts]# echo $time

2017年 12月 05日 星期二 09:02:06 CST

[root@kai scripts]# file=`ls`

[root@kai scripts]# echo $file

kai_test.sh panduan.sh quanju.sh yhk.sh

使用${}

打印變量的時候防止出現“金庸新著”的問題

[root@kai scripts]# time=`date`

[root@kai scripts]# echo $time_day

[root@kai scripts]# echo ${time}_day

2017年 12月 05日 星期二 09:02:06 CST_day

[root@kai scripts]# echo $time-day

2017年 12月 05日 星期二 09:02:06 CST-day

編寫腳本測試${}

# 使用腳本測試

[root@kai scripts]# vim bianliang.sh

#!/bin/bash

#############################################################

# File Name: bianliang.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-05 09:10:29

# Description:

#############################################################

time=`date`

echo $timeday

echo ${time}day

[root@kai scripts]# sh bianliang.sh

2017年 12月 05日 星期二 09:11:19 CSTday

1.4.9 定義變量名技巧

1. 變量名只能爲字母、數字或下劃線,只能以字母或下劃線開頭。

2. 變量名的定義要有一定的規範,並且要見名知意。

示例:

kaiAge=22       #<==每個單詞的首字母大寫的寫法

kai_age=22      #<==單詞之間用"_"的寫法

kaiAgeSex=man   #<==駝峯語法:首個單詞的首字母小寫,其餘單詞首字母大寫

kaiAGE=22       #<==單詞全大寫的寫法

3. 一般的變量定義、賦值常用雙引號;簡單連續的字符串可以不加引號;希望原樣輸出時使用單引號。

4. 希望變量的內容是命令的解析結果時,要用反引號'',或者用$()把命令括起來再賦值。


1.5特殊變量

1.5.1 位置變量

常用的特殊位置參數說明

位置變量

作用說明

$0

獲取當前執行的shell腳本的文件名,如果執行腳本帶路徑那麼就包括腳本路徑。

$n

獲取當前執行的shell腳本的第n個參數值,n=1..9,當n0時表示腳本的文件名,如果n大於9用大括號括起來{10},參數以空格隔開。

$#

獲取當前執行的shell腳本後面接的參數的總個數

$*

獲取當前shell的所有傳參的參數,不加引號同$@;如果給$*加上雙引號,例如: $*,則表示將所有的參數視爲單個字符串,相當於“112$3”。

$@

獲取當前shell的所有傳參的參數,不加引號同$*;如果給$@加上雙引號,例如: $@,則表示將所有參數視爲不同的獨立字符串,相當於“$1 $2 $3 “……”,這是將參數傳遞給其他程序的最佳方式,因爲他會保留所有內嵌在每個參數裏的任何空白。

當“$*”和“$@”都加雙引號時,兩者有區別,都不加雙引號時,兩者無區別。

$0,$1.$2 ~ 參數實踐

[root@kai scripts]# vim chanshu.sh

#!/bin/bash

#############################################################

# File Name: chanshu.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-05 09:39:16

# Description:

#############################################################

echo $0

echo "第一個參數:" $1

echo "第二個參數:" $2

echo "第11個參數:" ${11}

[root@kai scripts]# sh chanshu.shchanshu.sh

第一個參數:

第二個參數:

第11個參數:

[root@kai scripts]# sh chanshu.sh 1 2 3 4 5 6 7 8 9 10 11 chanshu.sh

第一個參數: 1

第二個參數: 2

第11個參數: 11

$# 參數實踐

[root@kai scripts]# vim chanshu.sh

#############################################################

# File Name: chanshu.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-05 09:39:16

# Description:

#############################################################

echo $0

echo "第一個參數:" $1

echo "第二個參數:" $2

echo "第10個參數:" ${10}

echo "第11個參數:" ${11}

echo "參數個數:" $#

[root@kai scripts]# sh chanshu.sh 55 2 3 4 5 6 7 8 9 10 11 112chanshu.sh

第一個參數: 55

第二個參數: 2

第10個參數: 10

第11個參數: 11

參數個數: 12

$* 參數實踐

[root@kai scripts]# vim chanshu.sh

#############################################################

# File Name: chanshu.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-05 09:39:16

# Description:

#############################################################

echo $0

echo "第一個參數:" $1

echo "第二個參數:" $2

echo "第10個參數:" ${10}

echo "第11個參數:" ${11}

echo "參數個數:" $#

echo "參數:" $*

"chanshu.sh" 18L, 456C 已寫入

[root@kai scripts]# sh chanshu.sh 55 2 3 4 5 6 7 8 9 10 11 112chanshu.sh

第一個參數: 55

第二個參數: 2

第10個參數: 10

第11個參數: 11

參數個數: 12

參數: 55 2 3 4 5 6 7 8 9 10 11 112

$*  $@ 對比實踐

[root@kai scripts]# set -- "I am" handsome boy..

[root@kai scripts]# echo $1

I am

[root@kai scripts]# echo $2

handsome

[root@kai scripts]# echo $3

boy..

[root@kai scripts]# echo $*

I am handsome boy..

[root@kai scripts]# echo $@

I am handsome boy..

[root@kai scripts]# for i in $*;do echo $i ;done

I

am

handsome

boy..

[root@kai scripts]# for i in $@;do echo $i ;done

I

am

handsome

boy..

[root@kai scripts]# for i in "$@";do echo $i ;done

I am

handsome

boy..

[root@kai scripts]# for i in "$*";do echo $i ;done

I am handsome boy..

1.5.2 進程狀態變量

Shell進程的特殊狀態變量說明

位置變量

作用說明

$?

獲取執行上一個指令的執行狀態返回值(0爲成功,非零爲失敗),這個變量最常用

$$

獲取當前執行的Shell腳本的進程號(PID),這個變量不常用,瞭解即可

$!

獲取上一個在後臺工作的進程的進程號(PID),這個變量不常用,瞭解即可

$_

獲取在此之前執行的命令或腳本的最後一個參數,這個變量不常用,瞭解即可

進程參數實踐

[root@kai scripts]# echo $?0

[root@kai scripts]# echo $$

1368

[root@kai scripts]# echo $!

[root@kai scripts]# echo $_

echo

1.5.3 echo參數說明

參數

參數說明

-n

不要追加換行

-e

啓用下列反斜槓轉義的解釋

-E

顯式地抑制對於反斜槓轉義的解釋

`echo' 對下列反斜槓字符進行轉義:

\n

換行

\r

回車

\t

橫向製表符

\b

退格

\v

縱向製表符

\c

抑制更多的輸出


1.6定義變量的方式

1.6.1 三種定義變量的方式

  1、直接賦值

  2、傳參 (傳遞參數)

  3、交互式設置變量,使用read命令

1.6.2 read命令說明

在命令行中使用

[root@kai scripts]# read

132

[root@kai scripts]# echo $REPLY

132

[root@kai scripts]# read kai

456

[root@kai scripts]# echo $kai

456

[root@kai scripts]# echo $REPLY

132

在腳本中使用

[root@kai scripts]# vim kai_test.sh

#!/bin/bash

read -p '請輸入:' kai

echo $kai

執行結果

[root@kai scripts]# sh kai_test.sh 請輸入:kai_znix

kai_znix

read命令的幫助說明

[root@kai scripts]# read --help

-bash: read: --: 無效選項

read: 用法:read [-ers] [-a 數組] [-d 分隔符] [-i 緩衝區文字] [-n 讀取字符數] [-N 讀取字符數] [-p 提示符] [-t 超時] [-u 文件描述符] [-s不顯示終端的任何輸入] [名稱 ...]

1.6.3 定義方法實踐

直接賦值方法

[root@kai scripts]# vim bianliang.sh

# File Name: bianliang.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-05 09:10:29

# Description:

##############################################################

name=kai

age=22

sex=Man

hobby=`ls`

ethFile=/etc/sysconfig/network-scripts/ifcfg-eth0

echo $hobby

ls $ethFile

[root@kai scripts]# sh bianliang.sh

bianliang.sh chanshu.sh kai.sh kai_test.sh panduan.sh quanju.sh xiugaizhuji.sh yhk.sh

/etc/sysconfig/network-scripts/ifcfg-eth0

傳參 (傳遞參數)

[root@kai scripts]# vim bianliang.sh

##############################################################

# File Name: bianliang.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-05 09:10:29

# Description:

##############################################################

name=kai

age=22

sex=Man

hobby=$1

ethFile=$2

echo $hobby

ls $ethFile

[root@kai scripts]# sh bianliang.sh kai /etc/hostname kai

/etc/hostname

交互式設置變量 read

[root@kai scripts]# vim yhk.sh

#!/bin/bash

##############################################################

# File Name: yhk.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-04 17:01:44

# Description:

##############################################################

read -p "請輸入你的銀行卡號:" Yhk

read -s -p "請輸入密碼:" miMa

echo

echo "你的銀行卡號:" $Yhk

echo "你的密碼爲:" $miMa

# 測試結果

[root@kai scripts]# sh yhk.sh

請輸入你的銀行卡號:123456

請輸入密碼:

你的銀行卡號: 123456

你的密碼爲: 123456

1.6.4 寫一個交互腳本,實現能夠定義主機名及IP地址

腳本內容

[root@kai scripts]# cat xiugaizhuji.sh

#!/bin/bash

#############################################################

# File Name: jiaohu.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-05 10:55:42

# Description:

#############################################################

ethFile=/etc/sysconfig/network-scripts/ifcfg-eth[01]

Now_eth=`hostname -I|awk -F "[. ]+" '{print $4}'`

read -p "請輸入主機名:" Hostname

read -p "請輸入IP地址的主機位:" HostIP

hostnamectl set-hostname $Hostname

sed -i "s#${Now_eth}#${HostIP}#g" $ethFile

read -p "是否重啓服務器:{yes/no}" REboot

if [ $REboot == yes ]

then

echo "系統將在10秒後重啓!"

shutdown -r 10

else

echo "請稍後手動重啓系統!"

fi

腳本測試結果

[root@kai scripts]# sh xiugaizhuji.sh

請輸入主機名:kai

請輸入IP地址的主機位:180

是否重啓服務器:{yes/no}yes

系統將在10秒後重啓!

[root@kai scripts]# sh xiugaizhuji.sh

請輸入主機名:kai

請輸入IP地址的主機位:180

是否重啓服務器:{yes/no}no

請稍後手動重啓!


1.7變量的子串

1.7.1 變量子串說明

表達式

說明

${parameter}

返回變量$parameter的內容

${#parameter}

返回變內容的長度(按字符),也適用於特殊變量

${parameterioffset}

在變量${parameter}中,從位置offset之後開始提取子串到結尾

${parameter:offset:length}

在變量${parameter}中,從位置offset之後開始提取長度爲length的子串

${parameter#word}

從變量${parameter}開頭開始刪除最短匹配的word子串

${parameter##word}

從變量${parameter}開頭開始刪除最長匹配的word子串

${parameter%word}

從變量${parameter}結尾開始刪除最短匹配的word子串

${parameter%%word}

從變量${parameter}結尾開始刪除最長匹配的word子串

${parameter/pattem/string}

使用string代替第一個匹配的pattern

${parameter//pattem/string}

使用string代替所有匹配的pattern

計算變量賦值的長度

-L:獲取文件中最長的一行的內容的長度

#:echo ${#kai}

[root@kai scripts]# kai=http://blog.znix.top

[root@kai scripts]# echo ${kai} |wc -L

20

[root@kai scripts]# echo ${#kai}

20

[root@kai scripts]# time echo ${kai} |wc -L

20

real 0m0.002s

user 0m0.002s

sys 0m0.000s

[root@kai scripts]# time echo ${#kai}

20

real 0m0.000s

user 0m0.000s

sys 0m0.000s


例:以下示例結果會說明#號要比wc -L效率高很多

time for i in $(seq 11111);do count=${#oldboy};done

time for i in $(seq 11111);do count=$(echo ${oldboy}|wc -L);done


截取變量中的字符

kai=george

echo ${oldboy:4:2}

[root@kai scripts]# kai=abcABC123ABCabc

[root@kai scripts]# echo ${kai#abc}ABC123ABCabc

[root@kai scripts]# echo ${kai##abc}ABC123ABCabc

[root@kai scripts]# echo ${kai%abc}abcABC123ABC

[root@kai scripts]# echo ${kai%%abc}abcABC123ABC

[root@kai scripts]# echo ${kai#a*c}ABC123ABCabc

[root@kai scripts]# echo ${kai##a*c}

[root@kai scripts]# echo ${kai%a*c}abcABC123ABC

[root@kai scripts]# echo ${kai%%a*c}

[root@kai scripts]# echo ${kai#a*C}123ABCabc

[root@kai scripts]# echo ${kai#a*C}123ABCabc

[root@kai scripts]# echo ${kai##a*C}abc

[root@kai scripts]# echo ${kai%a*c}abcABC123ABC

[root@kai scripts]# echo ${kai%A*c}abcABC123

[root@kai scripts]# echo ${kai%%A*c}

abc

替換變量內容

[root@kai scripts]# echo $kai

abcABC123ABCabc

[root@kai scripts]# echo ${kai/abc/kai}

kaiABC123ABCabc

[root@kai scripts]# echo ${kai//abc/kai}

kaiABC123ABCkai

有關上述匹配刪除的小結

#表示從幵頭刪除匹配最短。

##表示從開頭刪除匹配最長。

%表示從結尾刪除匹配最短。

%%表示從結尾刪除匹配最長。

a*c表示匹配的突符串,*表示匹配所有,a*c匹配開頭爲a、中間爲任意多個字符、結尾爲c的字符串。

a*C表示匹配的字符串,*表示匹配所有,a*C匹配開頭爲a、中間爲任意多個字符、結尾爲C的字符串。

有關替換的小結

一個“/”表示替換匹配的第-個字符串。

兩個“/”表示替換匹配的所有字符串。

1.7.2 Shell的特殊擴展變量說明

表達式

${parameter:-word}

如果parameter的變量值爲空或未賦值,則會返回word字符串並替代變量的值用途.如果變量未定義,則返回備用的值,防止變量爲空值或因未定義而導致異常(臨時賦值)

${parameter:=word}

如果parameter的變量值爲空或未賦值,則設置這個變量值爲word,並返回其值。位置變量和特殊變量不適用用途:基本同上一個${parameter>word},但該變量又額外給parameter變量賦值了(臨時並定義賦值)

${parameter:?word}

如果parameter變量值爲空或未賦值,那麼word字符串將被作爲標準錯誤輸出,否則輸出變量的值。用途:用於捕捉由於變量未定義而導致的錯誤,並退出程序

${parameter:+word}

如果parameter變量值爲空或未賦值,則什麼都不做,否則word字符串將替代變量的值

特殊變量實踐

腳本內容

[root@kai scripts]# cat kai.sh

#!/bin/bash

#############################################################

# File Name: kai.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-05 12:13:38

# Description:

#############################################################

dir=

echo ${dir:-/tmp}

echo ${dir}

echo ${dir:=/mnt}

echo ${dir}

dir2= (空格)

echo ${dir2-/tmp}

echo ${dir2}

echo ${dir2:-/tmp}

echo ${dir2}

echo ${dir2=/mnt}

echo ${dir2}

測試結果

[root@kai scripts]# sh kai.sh

/tmp

/mnt

/mnt

/tmp

至此shell中的變量就都介紹完了


1.8 變量的數值計算

1.8.1 僅支持整數的運算

echo $((數學運算表達式))

# 形式一

[root@kai scripts]# echo $((1 + 1))

2

[root@kai scripts]# echo $((2*7-3/6+5))

19

# 形式二

[root@kai scripts]# ((kai=2*8))

[root@kai scripts]# echo $kai

16

# 形式三

[root@kai scripts]# znix=$((2*7-3/6+5))

[root@kai scripts]# echo $znix

19

延伸產物(重要)

i++ 自增1

i-- 自減1

++i

--i

         示例:

[root@kai scripts]# i=1

[root@kai scripts]# echo $((i++))

1

[root@kai scripts]# echo $((i++))

2

[root@kai scripts]# echo $((i--))

3

[root@kai scripts]# echo $((i--))

2

[root@kai scripts]# echo $((i--))

1

[root@kai scripts]# echo $((++i))

1

[root@kai scripts]# echo $((++i))

2

[root@kai scripts]# echo $((++i))

3

[root@kai scripts]# echo $((--i))

2

[root@kai scripts]# echo $((--i))

1

[root@kai scripts]# echo $((--i))

0

記憶方法:++--

變量a在前,表達式的值爲a,然後a自增或自減,變量a在符號後,表達式值自增或自減,然後a值自增或自減。

let命令

[root@kai scripts]# i=1

[root@kai scripts]# i=i+1

[root@kai scripts]# echo $i

i+1

[root@kai scripts]# i=1

[root@kai scripts]# let i=i+1

[root@kai scripts]# echo $i

2

expr 命令

1.整數計算

2.判斷擴展名

3.判斷輸入是否爲整數,非整數返回值爲2

4.計算變量的長度

[root@kai scripts]# expr 1+1

1+1

[root@kai scripts]# expr 1 + 1

2

[root@kai scripts]# expr 1 * 1expr: 語法錯誤

[root@kai scripts]# expr 1 \* 1

1

非整數返回值爲2 示例:正常計算返回值爲0表示正常,特殊情況:如果計算結果爲0,那麼返回值結果就爲1

[root@kai scripts]# expr 1 + 1

2

[root@kai scripts]# echo $?

0

[root@kai scripts]# expr -1 + 1

0

[root@kai scripts]# echo $?

1

[root@kai scripts]# expr a + 1

expr: 非整數參數

[root@kai scripts]# echo $?

2

$[ ]運算符

[root@kai scripts]# echo $[1+2]

3

[root@kai scripts]# echo $[1-2]

-1

[root@kai scripts]# echo $[1*2]

2

[root@kai scripts]# echo $[1/2]

0

typeset命令進行運算

[root@kai scripts]# typeset -i A=2017 B=2018

[root@kai scripts]# A=A+B

[root@kai scripts]# echo $A

4035

1.8.2 可以進行小數運算的命令

bc    命令

# 安裝 bc 依賴於base源

[root@kai scripts]# yum -y install bc

  交互模式測試bc命令

[root@kai scripts]# bc

bc 1.06.95

Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.

1+1

2

[root@kai scripts]# echo 1+1.1|bc

2.1

免交互模式測試bc命令

小數保留6位:

[root@kai scripts]# echo 'scale=6;1/3'|bc

.333333

python 命令

[root@kai scripts]# file `which yum `

/usr/bin/yum: Python script, ASCII text executable

[root@kai scripts]# python

>>> import os

>>> os.system('df -h')

>>> 1+1.1

2.1

>>>exit()

awk 命令

[root@kai ~]# echo "7.7 3.8"|awk '{print ($1-$2)}'

3.9

[root@kai ~]# echo "358 113"|awk '{print ($1-3)/$2}'

3.14159

[root@kai ~]# echo "3 9"|awk '{print ($1+3)*$2}'

54

[root@backup scripts]# awk BEGIN'{print 1.2+3.3}'

4.5

1.8.3 運算相關練習題

1.8.3.1 【練習題】實現一個加減乘除等功能的計算器

實現腳本:

[root@kai scripts]# cat jishuanqi.sh

#!/bin/bash

#############################################################

# File Name: jishuanqi.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-06 08:57:13

# Description:

#############################################################

read -p "請輸入第一個整數:" a

read -p "請輸入第二個整數:" b

echo $a + $b =$(($a+$b))

echo $a - $b =$(($a-$b))

echo $a \* $b =$(($a*$b))

echo $a / $b =$(($a/$b))

         腳本執行過程:

[root@kai scripts]# sh jishuanqi.sh

請輸入第一個整數:12

請輸入第二個整數:12

12 + 12 =24

12 - 12 =0

12 * 12 =144

12 / 12 =1

精簡方法

[root@kai scripts]# vim jishuanqi2.sh

#!/bin/bash

#############################################################

# File Name: jishuanqi2.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-06 15:02:41

# Description:

#############################################################

echo $(($1))

         腳本執行過程:

[root@kai scripts]# sh jishuanqi2.sh 1+1

2

[root@kai scripts]# sh jishuanqi2.sh 1*9

9

1.8.3.2 【練習題】打印結果1+2+3+4+5+6+7+8+9+10=55

腳本內容

sed -s "+"  :-s指定分割

[root@kai scripts]# vim yunshuan.sh

#!/bin/bash

#############################################################

# File Name: yunshuan.sh

# Version: V1.0

# Author: kai

# Organization: http://blog.znix.top

# Created Time : 2017-12-06 09:40:31

# Description:

#############################################################

Num=`seq -s + 1 10`

echo $Num=$(($Num))

for的寫法:

#!/bin/bash

for i in {1..100}

do

 # ((sum=sum+i))

 #  sum=$(($sum+i))

   ((sum+=i))

done

echo $(seq -s "+" 100)=$sum

C的寫法:

for((i=1;i<=100;i++))

do

    ((sum+=i))

done

while的寫法:

#!/bin/bash

i=1

while ((i<=100))

do

((sum+=i))

((i+=1))

done

echo $(seq -s "+" 100)=$sum

腳本執行結果

[root@kai scripts]# sh yunshuan.sh

1+2+3+4+5+6+7+8+9+10=55


參考文檔:

http://blog.csdn.net/lansesl2008/article/details/20558369

https://www.abcdocker.com/abcdocker/269

http://blog.51cto.com/life2death/1657133

http://blog.51cto.com/oldboy/1867160    #企業shell面試題


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章