Shell腳本語言是實現Linux/UNIX系統管理及自動化運維所必備的重要工具, Linux/UNIX系統的底層及基礎應用軟件的核心大都涉及Shell腳本的內容。每個合格 的Linux系統管理員或運維工程師,都須要可以熟練地編寫Shell腳本語言,並可以閱讀系統及各種軟件附帶的Shell腳本內容。只有這樣才能提高運維人員的工做效率,適應曰益複雜的工做環境,減小沒必要要的重複工做,從而爲我的的職場發展奠基較好的基礎php
Shell是一個命令解釋器,它在操做系統的最外層,負責直接與用戶對話,把用戶的輸入解釋給操做系統,並處理各類各樣的操做系統的輸出結果,輸出屏幕返回給用戶。html
這種對話方式能夠是:前端
交互的方式:從鍵盤輸入命令,經過/bin/bash的解析,能夠當即獲得Shell的迴應java
非交互的方式: 腳本python
1.1.3 什麼是Shell腳本
linux
Shell腳本三要素:web
命令語句面試
變量docker
邏輯判斷shell
命令、變量和流程控制語句(邏輯判斷)等有機的結合起來
shell腳本擅長處理純文本類型的數據,而linux中,幾乎全部的配置文件,日誌,都是純文本類型文件
1、編譯型語言
定義:指用專用的編譯器,針對特定的操做平臺(操做系統)將某種高級語言源代碼一次性翻譯成可被硬件平臺直接運行的二進制機器碼(具備操做數,指令、及相應的格式),這個過程叫作編譯(./configure make makeinstall );編譯好的可執行性文件(.exe),可在相對應的平臺上運行(移植性差,但運行效率高)。。
典型的編譯型語言有, C語言、C++等。
另外,Java語言是一門很特殊的語言,Java程序須要進行編譯步驟,但並不會生成特定平臺的二進制機器碼,它編譯後生成的是一種與平臺無關的字節碼文件(*.class)(移植性好的緣由),這種字節碼天然不能被平臺直接執行,運行時須要由解釋器解釋成相應平臺的二進制機器碼文件;大多數人認爲Java是一種編譯型語言,但咱們說Java便是編譯型語言,也是解釋型語言也並無錯。
2、解釋型語言
定義:指用專門解釋器對源程序逐行解釋成特定平臺的機器碼並當即執行的語言;至關於把編譯型語言的編譯連接過程混到一塊兒同時完成的。
解釋型語言執行效率較低,且不能脫離解釋器運行,但它的跨平臺型比較容易,只需提供特定解釋器便可。
常見的解釋型語言有, Python(同時是腳本語言)與Ruby等。
python不如C安全
3、腳本語言
定義:爲了縮短傳統的編寫-編譯-連接-運行(edit-compile-link-run)過程而建立的計算機編程語言。
特色:程序代碼便是最終的執行文件,只是這個過程須要解釋器的參與,因此說腳本語言與解釋型語言有很大的聯繫。腳本語言一般是被解釋執行的,並且程序是文本文件。
典型的腳本語言有,JavaScript,Python,shell等。
其餘經常使用的腳本語句種類
PHP是網頁程序,也是腳本語言。是一款更專一於web頁面開發(前端展現)的腳本語言,例如:Dedecms,discuz。PHP程序也能夠處理系統日誌,配置文件等,php也能夠調用系統命令。
Perl腳本語言。比shell腳本強大不少,語法靈活、複雜,實現方式不少,不易讀,團隊協做困難,但仍不失爲很好的腳本語言,存世大量的程序軟件。MHA高可用Perl寫的
Python,不但能夠作腳本程序開發,也能夠實現web程序以及軟件的開發。近兩年愈來愈多的公司都會要求會Python。
Shell腳本與php/perl/python語言的區別和優點?
shell腳本的優點在於處理操做系統底層的業務 (linux系統內部的應用都是shell腳本完成)由於有大量的linux系統命令爲它作支撐。2000多個命令都是shell腳本編程的有力支撐,特別是grep、awk、sed等。例如:一鍵軟件安裝、優化、監控報警腳本,常規的業務應用,shell開發更簡單快速,符合運維的簡單、易用、高效原則.
PHP、Python優點在於開發運維工具以及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)
查看系統中的命解釋器
[root@kai ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
經常使用操做系統的默認shell
1.Linux是Bourne Again shell(bash)
2.Solaris和FreeBSD缺省的是Bourne shell(sh)
3.AIX下是Korn Shell(ksh)
4.HP-UX缺省的是POSIX shell(sh)
[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
sh與bash 的關係
[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
[root@kai ~]# mkdir -p /server/scripts/
[root@kai ~]# cd /server/scripts/
注意格式 ↓
其中開頭的"#!"字符又稱爲幻數,在執行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
使用 .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,爲中文)。
名字要有意義,而且結尾以 .sh 結束
1) 放在統一的目錄
2) 腳本以.sh爲擴展名
3) 開頭指定腳本解釋器。
4) 開頭加版本版權等信息,可配置~/.vimrc文件自動添加。
5) 腳本不要用中文註釋,儘可能用英文註釋。
6) 代碼書寫優秀習慣
a、成對的內容一次性寫出來,防止遺漏,如[ ]、' '、" "等
b、[ ]兩端要有空格,先輸入[ ],退格,輸入2個空格,再退格寫。
c、流程控制語句一次書寫完,再添加內容。(if 條件 ; then 內容;fi)ddd
d、經過縮進讓代碼易讀。
f、腳本中的引號都是英文狀態下的引號,其餘字符也是英文狀態。
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 中執行一個文件中的命令。
[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.sh後echo $user返回的結果__空_ ?
[root@oldboy scripts]# cat test.sh
#!/bin/bash
user=`whoami`
變量能夠分爲兩類:環境變量(全局變量)和普通變量(局部變量)
環境變量也可稱爲全局變量,能夠在建立他們的Shell及其派生出來的任意子進程shell中使用,環境變量又可分爲自定義環境變量和Bash內置的環境變量
普通變量也可稱爲局部變量,只能在建立他們的Shell函數或Shell腳本中使用。普通變量通常是由開發者用戶開發腳本程序時建立的。
特殊變量:位置變量和進程變量
使用 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
本地變量在用戶當前的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}兩種用法
小結:連續普通字符串內容賦值給變量,無論用什麼引號或者不用引號,它的內容是什麼,打印變量就輸出什麼
[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
/etc/proflie
/etc/bashrc
~/.bashrc
~/.bash_profile
/etc/proflie.d/ # 目錄
四文件讀取順序(CentOS6和7都同樣)
① /etc/profile
② ~/.bash_profile
③ ~/.bashrc
④ /etc/bashrc
文件讀取過程示意圖
驗證四文件讀取順序的方法
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
ü 變量名一般要大寫。
ü 變量能夠在自身的Shell及子Shell中使用。
ü 經常使用export來定義環境變量。
ü 執行env默承認以顯示全部的環境變量名稱及對應的值。
ü 輸出時用「$變量名」,取消時用「unset 變量名」。
ü 書寫crond定時任務時要注意,腳本要用到的環境變量最好先在所執行的Shell腳本中從新定義。
定時任務的腳本加上 source /etc/profile 防止執行失敗的狀況
ü 若是但願環境變量永久生效,則能夠將其放在用戶環境變量文件或全局環境變量文件裏。
只有在變量的值中有空格的時候,會使用引號。
單引號與雙引號的區別在於,是否可以解析特殊符號。
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) 內容是純數字、簡單的連續字符(內容中不帶任何空格)時,定義時能夠不加任何引號,例如:
a.kaiAge=22
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. 變量名只能爲字母、數字或下劃線,只能以字母或下劃線開頭。
2. 變量名的定義要有必定的規範,而且要見名知意。
示例:
kaiAge=22 #<==每一個單詞的首字母大寫的寫法
kai_age=22 #<==單詞之間用"_"的寫法
kaiAgeSex=man #<==駝峯語法:首個單詞的首字母小寫,其他單詞首字母大寫
kaiAGE=22 #<==單詞全大寫的寫法
3. 通常的變量定義、賦值經常使用雙引號;簡單連續的字符串能夠不加引號;但願原樣輸出時使用單引號。
4. 但願變量的內容是命令的解析結果時,要用反引號'',或者用$()把命令括起來再賦值。
經常使用的特殊位置參數說明
位置變量 |
做用說明 |
$0 |
獲取當前執行的shell腳本的文件名,若是執行腳本帶路徑那麼就包括腳本路徑。 |
$n |
獲取當前執行的shell腳本的第n個參數值,n=1..9,當n爲0時表示腳本的文件名,若是n大於9用大括號括起來{10},參數以空格隔開。 |
$# |
獲取當前執行的shell腳本後面接的參數的總個數 |
$* |
獲取當前shell的全部傳參的參數,不加引號同$@;若是給$*加上雙引號,例如: 「$*」,則表示將全部的參數視爲單個字符串,至關於「12$3」。 |
$@ |
獲取當前shell的全部傳參的參數,不加引號同$*;若是給$@加上雙引號,例如: 「$@」,則表示將全部參數視爲不一樣的獨立字符串,至關於「$1」 「$2」 「$3」 「……」,這是將參數傳遞給其餘程序的最佳方式,由於他會保留全部內嵌在每一個參數裏的任何空白。 |
當「$*」和「$@」都加雙引號時,二者有區別,都不加雙引號時,二者無區別。 |
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..
Shell進程的特殊狀態變量說明
位置變量 |
做用說明 |
$? |
獲取執行上一個指令的執行狀態返回值(0爲成功,非零爲失敗),這個變量最經常使用 |
$$ |
獲取當前執行的Shell腳本的進程號(PID),這個變量不經常使用,瞭解便可 |
$! |
獲取上一個在後臺工做的進程的進程號(PID),這個變量不經常使用,瞭解便可 |
$_ |
獲取在此以前執行的命令或腳本的最後一個參數,這個變量不經常使用,瞭解便可 |
進程參數實踐
[root@kai scripts]# echo $?0
[root@kai scripts]# echo $$
1368
[root@kai scripts]# echo $!
[root@kai scripts]# echo $_
echo
參數 |
參數說明 |
-n |
不要追加換行 |
-e |
啓用下列反斜槓轉義的解釋 |
-E |
顯式地抑制對於反斜槓轉義的解釋 |
`echo' 對下列反斜槓字符進行轉義: |
|
\n |
換行 |
\r |
回車 |
\t |
橫向製表符 |
\b |
退格 |
\v |
縱向製表符 |
\c |
抑制更多的輸出 |
1、直接賦值
2、傳參 (傳遞參數)
3、交互式設置變量,使用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不顯示終端的任何輸入] [名稱 ...]
直接賦值方法
[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
腳本內容↓
[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
請稍後手動重啓!
表達式 |
說明 |
${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的字符串。
有關替換的小結
一個「/」表示替換匹配的第-個字符串。
兩個「/」表示替換匹配的全部字符串。
表達式 |
說明 |
${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中的變量就都介紹完了
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
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
實現腳本:
[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
腳本內容
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://www.javashuo.com/article/p-twfiqbpo-gg.html
https://blog.51cto.com/oldboy/1867160 #企業shell面試題