本篇
- 練習(xí)Shell編程追迟,以每個腳本為單位
- 不定期更新
- 目前腳本數(shù)量為18個
- 更新時間2019-02-13
- 項目已放到github,希望可以被start
NO.1
這次主要玩一下echo 和read
echo 輸出內(nèi)容
read 輸入內(nèi)容
$ 的使用
#!/bin/bash
#2018-09-04 baron
#github: https://github.com/MyBaron/Shell_practice
# 練習(xí)一:
# echo 輸出內(nèi)容
# read 讀取輸入
# $ 的使用
#--------------------------------------------
# $ 是代表變量替換
# 輸出PATH變量
echo $PATH
echo '\n Hello World! baron \a \n'
# 定義一個變量
name='helloName'
# '' 和"" 的區(qū)別就是 "" 會識別$符號
echo "輸出name變量的值:${name}"
echo '單引號是不會識別$的:${name}'
# read 輸入 輸入的值賦值到fistname這個變量中 -p 是提示
read -p "please enter your firstname " firstname
read -p "and then please enter your lastname " lastname
echo "just a minute..........."
# 引用變量 輸出自己輸入的內(nèi)容
echo "your name is" ${firstname}${lastname}
# $() 是使用命令聂受,這里是使用了data命令輸出日志
echo "Hellp ${firstname}${lastname} today is $(date +%Y%m%d) "
exit 0
NO.2
功能:檢查一下文件是否存在
練習(xí)內(nèi)容:
- echo 內(nèi)容輸出
- read 內(nèi)容輸入
- test 檢查條件
- 命令使用
#!/bin/bash
#2018-09-14 baron
#github: https://github.com/MyBaron/Shell_practice
# 文件測試
# test 命令 -e 是如果文件存在則為真
# && ,com1 && com2,只有當(dāng)com1 為true時,才會執(zhí)行com2
# || 卓囚,與&& 相反 只有com1 為false時幸海,才會執(zhí)行com2
echo "the bash is check one file is exist or not \n"
read -p "請輸入你想檢查的文件 " file
test -e ${file} && echo "${file}文件存在" || echo "${file}文件不存在"
# 數(shù)值比較
# -lt 是小于的意思
num1=100
num2=200
echo "\nnum1=100,num2=200"
test ${num1} -lt ${num2} && echo "num1小于num2" || echo "num1大于num2"
# 字符串
str1="str"
str2="str"
echo "\nstr1=str,str2=str"
test ${str1}=${str2} && echo "相等" || echo "不相等"
exit 0
NO.3
將文件拷貝到指定目錄下
練習(xí)內(nèi)容
- 輸入?yún)?shù)
- 邏輯判斷 If-elif-else
#!/bin/bash
#2018-09-015 baron
#github: https://github.com/MyBaron/Shell_practice
#將文件拷貝到指定目錄下
#輸入?yún)?shù)
# 執(zhí)行該腳本命令 sh xx.sh hello.sh /baron/path
# hello 為輸入的參數(shù)
# ${n} 為第n個傳入?yún)?shù) 從1開始 0是文件名稱
# $# 為傳入?yún)?shù)的個數(shù)
file=${1}
path=${2}
echo "輸入的file為${file}"
echo "輸入的path為${path}"
echo "輸入的參數(shù)個數(shù)為$#"
# if-elif-else 邏輯"
# if判斷語句在[] 里面
# 注意: [] 里面要有空格=氤Α!B丁V剀!虚茶!
# if 配合test語句使用 不需要[]
if [ "${file}" == "" ] && [ "${path}" == "" ]; then
echo "file和path都不能為空"
elif test -e ${file} ; then
echo "將${file}拷貝到${path}"
cp -r -i ${file} ${path}
else
echo "file 文件不存在"
fi
exit 0
No.4 批量檢查ip地址是否被占用
功能:批量檢查ip地址是否被占用
練習(xí)內(nèi)容
- while循環(huán)
- for 循環(huán)
- seq 指令 用于產(chǎn)生從某個數(shù)到另外一個數(shù)之間的所有整數(shù)
#!/bin/bash
#@author baron
#@data 2018-09-07
#@comtent check long-range server status
network="${1}"
# while循環(huán) 循環(huán)獲取用戶輸入Ip字段
# 用法:
# 1. 條件與If一樣[] 里是判斷條件
# 2. do done 里面是判斷邏輯戈鲁,do為開始,done為結(jié)束
while [ "${network}" == "" ]
do
read -p "please input what you want to check network ,format is x.x.x " network
done
read -p "please input what you want to start the number " start
read -p "please input what you want to end the number " end
# for循環(huán)遍歷次數(shù)
# seq指令是從某個數(shù)到另外一個數(shù)之間的所有整數(shù)
# 用法
# 1. for xx in xx
# do done 里面是判斷邏輯嘹叫,do為開始婆殿,done為結(jié)束
#
# 2. 也可以 for ((i=1; i<=100; i ++))
#
#
for sitenu in $(seq "${start}" "${end}" )
do
ping -c 1 "${network}.${sitenu}" &> /dev/null && result=0 || result=1
if [ "${result}" == 0 ]; then
echo "Server ${network}.${sitenu} is UP."
else
echo "Server ${network}.${sitenu} is DOWN."
fi
done
echo "ok,that is checking over"
exit 0
No.5 檢查端口情況
功能:檢查端口情況
練習(xí)內(nèi)容
- 輸入流
- if 判斷條件
- grep 信息篩選
#!/bin/bash
#@author baron
#@data 2018-09-06
#@content check any port is been taken
echo "Now , I will detect your Linux server's services!"
if [ "${1}" != "" ]; then
echo "The www,ftp,ssh,mail(stmp),and you want to check ${1} will be detected! \n"
else
echo "The www,ftp,ssh,mail(stmp) will be detected! \n"
fi
# 設(shè)定輸出路徑
testfile=checkPortResult.txt
# 將netstat結(jié)果輸出到文件
# > 為輸入重定向 例如 xx0 > xx1.txt 意思是將xx0的內(nèi)容輸入到xx1.txt中
netstat -tuln > ${testfile}
# 檢測各個端口情況
# 利用grep 檢索關(guān)鍵字
esting=$(grep ":80" ${testfile})
if [ "${testing}" != "" ]; then
echo "WWW is running in your system"
fi
testing=$(grep ":22" ${testfile})
if [ "${testing}" != "" ]; then
echo "SSH is running in your system"
fi
testing=$(grep ":21" ${testfile})
if [ "${testing}" != "" ]; then
echo "FTP is running in your system"
fi
testing=$(grep ":25" ${testfile})
if [ "${testing}" != "" ]; then
echo "Mail is running in your system"
fi
if [ "${1}" != "" ]; then
testing=$(grep ":${1}" ${testfile})
if [ "${testing}" != "" ]; then
echo "${1} port is running in your system"
fi
fi
echo "check is over , thank you"
exit 0
No.6 檢查CPU情況
功能:檢查CPU情況
效果圖
效果圖 .png
#!/bin/bash
# baron
# 2019-01-18
# 分析cpu使用情況
# 利用vmstat 分析cpu使用情況
# 檢測是否有vmstat命令
if ! which vmstat &> /dev/null ; then
echo "the sy is no vmstat commam"
exit 1
fi
# 創(chuàng)建臨時文件
date=$(date "+%Y-%m-%d_%H:%M:%S")
file="cpu_stat_${date}.txt"
echo "正在收集cpu情況,請等候"
vmstat 2 3 >${file}
# 睡眠三秒
sleep 3s
set US
set SY
R=0
# 循環(huán)處理數(shù)據(jù)
for NR in $(seq 3 5)
do
US1=$(vmstat |awk 'NR==3{print $13}')
SY1=$(vmstat |awk 'NR==3{print $14}')
R1=$(vmstat |awk 'NR==3{print $1}')
if [ $R1 -gt $R ]; then
R=${R1}
fi
US=`expr ${US} + ${US1} `
SY=`expr ${SY} + ${SY1} `
done
# 刪除臨時文件
rm -r ${file}
US=`expr ${US} / 3 `
SY=`expr ${SY} / 3 `
echo "最大的進程數(shù)是:${R}"
echo "平均的CPU占用率是:`expr ${US} + ${SY}`%"
echo "用戶平均CPU占用率:${US}%"
echo "系統(tǒng)平均CPU占用率:${SY}%"
echo "this is all"
exit 0
No.7 檢查內(nèi)存情況
功能:檢查CPU情況
使用free 命令獲取內(nèi)存情況
效果圖
image.png
#!/bin/bash
# baron
# 2019-01-21
# 分析內(nèi)存使用情況
# 利用free 分析內(nèi)存使用情況
# 檢測是否有free命令
if ! which free &> /dev/null ; then
echo "the sy is no free commam"
exit 1
fi
echo "正在檢查內(nèi)存使用情況"
TOTAL=$(free -m |awk '/Mem/{print $2}')
USE=$(free -m |awk '/Mem/{print $3}')
FREE=$(free -m |awk '/Mem/{print $4}')
CACHE=$(free -m |awk '/Mem/{print $6}')
echo -e "當(dāng)前使用情況: \n內(nèi)存總大姓稚取:${TOTAL}M \n內(nèi)存使用量:${USE}M \n可用剩余:${FREE}M\n磁盤緩存大忻怼:${CACHE}M"
exit 0
No.9 trap捕獲信號
對trap指令進行運用
#!/bin/bash
# baron
# 2019-01-23
# trap的使用 捕獲信號
# trap commands signals : commands 捕獲后觸發(fā)的命令,signals 需要捕獲的命令
echo "無法通過ctrl-c 來終止這個腳本,此腳本會運行10秒"
# SIGINT 是終止線程 SIGTERM 是盡可能終止進程
trap "echo '我已經(jīng)告訴過你暮蹂,你無法終止這個腳本'" SIGINT SIGTERM
count=1
while [ $count -lt 10 ]
do
echo "第${count}秒"
sleep 1
count=$[ $count + 1 ]
done
# 捕獲程序退出指令
trap "echo \"腳本運行結(jié)束,運行時間${count}秒\" " EXIT
No.10 數(shù)組和函數(shù)
對數(shù)組和函數(shù)的練習(xí)
效果圖
開始執(zhí)行fun函數(shù),將返回輸入的數(shù)中大于10的數(shù)的數(shù)組
數(shù)組的個數(shù)為6
輸入數(shù)組的值為1 2 3 33 44 55 66
大于10的數(shù)有 33 44 55 66
#!/bin/bash
# baron
# 2019-01-24
# 練習(xí)函數(shù)和數(shù)組
#
# 個人覺得數(shù)組操作是非常難用寞缝,而且功能點很少,在日常中應(yīng)該避免使用數(shù)組
# 在使用數(shù)組中仰泻,經(jīng)常利用到echo來構(gòu)成數(shù)組
function fun(){
echo "開始執(zhí)行fun函數(shù),將返回輸入的數(shù)中大于10的數(shù)的數(shù)組"
# 新建一個數(shù)組荆陆,用于返回
local newarray
local elements
local oldarray
local number=0
#獲取輸入的參數(shù)
elements=$[ $# -1 ]
echo "數(shù)組的個數(shù)為${elements}"
# $@相當(dāng)于獲取所有的參數(shù),利用echo集侯,相當(dāng)于輸入?yún)?shù)被啼,()是組成數(shù)組
oldarray=(`echo "$@"`)
echo "輸入數(shù)組的值為${oldarray[*]}"
for (( i=0; i<=${elements}; i++ )){
if [ $[${oldarray[$i]}] -gt 10 ]; then
newarray[${number}]=${oldarray[$i]}
# 同樣可以這樣寫 number=`expr $number + 1`
number=$[ $number + 1 ]
fi
}
echo "大于10的數(shù)有 ${newarray[*]}"
}
testArray=(1 2 3 33 44 55 66)
# 此處echo就是相當(dāng)于輸入數(shù)組的值作為參數(shù),每一個值當(dāng)做一個參數(shù)
# 如果只傳入數(shù)組棠枉,只能當(dāng)做是一個參數(shù)
arg1=$(echo ${testArray[*]} )
fun $arg1
No.11 函數(shù)的返回值
函數(shù)的返回值
- 返回值return 非必須
- 可以將函數(shù)賦值給變量
效果
此函數(shù)是返回一個數(shù)值
用$?接收的返回值是: 200
變量:此函數(shù)是返回一個數(shù)值
命令返回值是:0
代碼
#!/bin/bash
# baron
# 2019-01-25
# 聯(lián)系函數(shù)的return
function fun1(){
echo "此函數(shù)是返回一個數(shù)值"
return 200
}
# 直接調(diào)用函數(shù)浓体,使用$?獲取返回值
fun1
# $? 上個命令的退出狀態(tài),或函數(shù)的返回值
echo "用\$?接收的返回值是: $?"
# 將函數(shù)賦值給變量
# 用變量來接收返回值
arg=$(fun1)
#這里調(diào)用變量arg辈讶,相當(dāng)于執(zhí)行了函數(shù)fun1
echo "變量:$arg"
#這里返回值是0命浴,是因為這里的命令值的是echo,而不是$arg的函數(shù)命令
echo "命令返回值是:$?"
No.12 awk輸出所有字符串
利用awk切割后贱除,輸出所有字符串
代碼
#!/bin/bash
# baorn
# 2019-01-26
# awk 將輸出所有分割的字符串
# 將echo的以空格切割然后遍歷輸出
# NF是awk的參數(shù)生闲,代表切割后個數(shù)
# print $i 是輸出切割后的第幾列 $0是整行
val=`echo "第一 第二 第三 第四"|awk '{for(i=1;i<=NF;i++){print $i}}'`
echo $val
No.13 練習(xí)函數(shù)傳遞數(shù)組
練習(xí)函數(shù)傳遞數(shù)組
#!/bin/bash
# baron
# 2019-01-26
# 練習(xí)函數(shù)傳遞數(shù)組
function fun(){
local sum=0
local newarray
#接收參數(shù)
newarray=(`echo "$@"`)
#遍歷數(shù)組中的每一個數(shù)
for num in ${newarray[*]}
do
sum=$[ $sum + $num ]
done
echo $sum
}
array=(1 2 3 4 5 6 )
echo "輸入的數(shù)組是 ${array[*]}"
arg1=`echo ${array[*]}`
result=`fun $arg1`
echo "數(shù)組累加的結(jié)果是:$result"
No.14 使用getopts接收輸入?yún)?shù)
使用getopts接收輸入?yún)?shù)
getopts的命令格式:
getopts optstring name [arg...] 例如:getopts "a:fs" OPTION
getopts 作用就是接收用戶在運行腳本的時候輸入的參數(shù),例如sh xx.sh -i
getopts 通常用while來循環(huán)處理月幌,用Case去得到不同的命令處理方式
效果
baron@baron: sh expGetopts.sh -vk -i "this is value"
你輸入的參數(shù)是v
你輸入的參數(shù)沒有找到匹配
你輸入的參數(shù)是i,值是this is value
代碼
#!/bin/bash
# baron
# 2019-01-28
# getopts接收輸入?yún)?shù)
# getopts的命令格式:
# getopts optstring name [arg...] 例如:getopts "a:fs" OPTION
# getopts 作用就是接收用戶在運行腳本的時候輸入的參數(shù)碍讯,例如sh xx.sh -i
# getopts 通常用while來循環(huán)處理,用Case去得到不同的命令處理方式
# 在這里扯躺,接收處理的參數(shù)是i v h 三個參數(shù)
# 設(shè)置的格式是':i:vh'
# 第一個: 代表去掉系統(tǒng)的告警信息
# i: 是指接收i的指令捉兴,這個指令還有value蝎困,可以用$OPTARG來接收這個value
# v和h:就是單單是指令
while getopts ':i:vh' name
do
case $name in
i)
echo "你輸入的參數(shù)是i,值是$OPTARG";;
v)
echo "你輸入的參數(shù)是v";;
h)
echo "你輸入的參數(shù)是h";;
*)
echo "你輸入的參數(shù)沒有找到匹配";;
esac
done
No.15 將腳本添加到全局命令
將腳本添加到全局命令
效果:
[root@sy4 shell]# sh addBin.sh -i
當(dāng)前路徑為/opt/ruqiAgent/shell
temp的內(nèi)容 addBin.sh
腳本所在的路徑 /opt/ruqiAgent/shell/addBin.sh
安裝命令成功
現(xiàn)在可以在終端使用scriptTest命令
代碼
#!/bin/bash
# baron
# 2019-01-29
# 將這個腳本添加到環(huán)境的目錄中,可以使用終端執(zhí)行命令
function add(){
# 獲取當(dāng)前路徑
wd=`pwd`
echo "當(dāng)前路徑為$wd"
## 將腳本名稱寫到臨時文件temp
## basename 是去掉路徑倍啥,只剩下文本名稱
basename "$(test -L "$0" && readlink "$0" || echo "$0")" > temp
echo "temp的內(nèi)容 $(cat temp )"
## 拼接腳本所在的路徑
scriptName=$(echo -e -n $wd/ && cat temp)
echo "腳本所在的路徑 $scriptName"
# 將腳本添加到全局命令中
su -c "cp $scriptName /usr/bin/scriptTest" root && echo "安裝命令成功" || echo "安裝命令失敗"
rm -f temp
echo "現(xiàn)在可以在終端使用scriptTest命令"
}
function succ(){
echo "使用命令成功"
}
while getopts ':i' name
do
case $name in
i)
add ;;
*)
succ ;;
esac
done
exit 0
No.16 查看網(wǎng)絡(luò)情況和系統(tǒng)信息
查看網(wǎng)絡(luò)情況和系統(tǒng)信息
聯(lián)系內(nèi)容:
- 變色字體
- tput sgr0還原終端配置
- ping 查看網(wǎng)絡(luò)情況
- uname 查看系統(tǒng)信息
效果
網(wǎng)絡(luò)狀態(tài):可連接
該系統(tǒng)類型是:GNU/Linux
系統(tǒng)的發(fā)行版本:3.10.0-862.el7.x86_64
系統(tǒng)的名稱:Linux
系統(tǒng)的類型:x86_64
代碼
#!/bash/bin
# baron
# 2019-01-31
# 測試網(wǎng)絡(luò)和系統(tǒng)信息
# tput 可以更改幾項終端功能禾乘,如移動或更改光標(biāo)、更改文本屬性逗栽,以及清除終端屏幕的特定區(qū)域
# sgr0 表示清除所有更改的配置
reset=`tput sgr0`
# 查看是否可以聯(lián)網(wǎng)
# \E[32m 是修改字體顏色盖袭,32m 是綠色
ping -c 1 www.baidu.com &> /dev/null && echo -e '\E[32m'"網(wǎng)絡(luò)狀態(tài):${reset}可連接 " || echo -e '\E[32m'"網(wǎng)絡(luò)狀態(tài):${reset}未連接"
# 查看系統(tǒng)類型
# mac系統(tǒng)并沒有-o選項
os=`uname -o`
echo -e '\E[32m'"該系統(tǒng)類型是:${reset}$os"
# 系統(tǒng)的發(fā)行版本
REV=`uname -r`
# 系統(tǒng)的名稱
OS=`uname -s`
# 系統(tǒng)類型
MACH=`uname -m`
echo -e '\E[32m'"系統(tǒng)的發(fā)行版本:${reset}$REV"
echo -e '\E[32m'"系統(tǒng)的名稱:${reset}$OS"
echo -e '\E[32m'"系統(tǒng)的類型:${reset}$MACH"
No.17 查看系統(tǒng)網(wǎng)絡(luò)
查看網(wǎng)絡(luò)情況和系統(tǒng)信息
效果圖
本地ip地址: 10.10.1.234 172.17.0.1
外網(wǎng)ip地址: 183.238.79.207
DNS地址: 114.114.114.114 8.8.8.8
代碼
#!/bin/bash
# baron
# 2019-02-12
# 查看系統(tǒng)網(wǎng)絡(luò)
reset=`tput sgr0`
# 獲取本地Ip
internalip=`hostname -I`
echo -e '\E[32m' "本地ip地址:"${reset} ${internalip}
# 獲取外網(wǎng)Ip
externalip=`curl -s ipecho.net/plain`
echo -e '\E[32m' "外網(wǎng)ip地址:" ${reset} $externalip
# 定義DNS服務(wù)器的IP地址
# sed '1 d' 代表刪除第一行
nameservers=$(cat /etc/resolv.conf | sed '1 d' | awk '{print $2}' )
# 也可以用awd 的NR 來實現(xiàn)sed的效果
nameservers1=$(cat /etc/resolv.conf | awk 'NR>1{print $2}' )
echo -e '\E[32m' "DNS地址:" ${reset} ${nameservers}
No.18 自動提交push代碼到遠程
自動提交push代碼到遠程
思路:
- 將本腳本的添加到忽略提交名單中
- 利用git命令進行提交
- commit 信息是當(dāng)前日期
#!/bash/bin
# baron
# 2019-02-13
# 自動提交到遠程代碼庫
# 檢查當(dāng)前路徑是否有.git文件夾
function judge(){
if [ -x ".git" ];then
# 獲取當(dāng)前文件的名稱
if [ -f ".git/.gitignore" ];then
echo "添加忽略提交該腳本到遠程代碼庫"
echo "當(dāng)前腳本名稱${0}"
echo ${0} >> .git/.gitignore
push
else
echo "創(chuàng)建 .gitignore文件"
echo "當(dāng)前腳本名稱${0}"
touch .git/.gitignore
echo ${0} >> .git/.gitignore
push
fi
else
echo ".git文件夾不存在,請將該腳本放到與.git文件夾同一級中"
exit -1
fi
}
function push(){
git add .
git commit -m "$(date +%Y-%m-%d)"
git push origin
}
judge
echo "提交完畢"
exit 0