Shell 腳本集合

本篇

  • 練習Shell編程,以每個腳本爲單位
  • 不定期更新
  • 目前腳本數量爲16個
  • 更新時間2019-01-31
  • 項目已放到github,希望可以被start

NO.1 echo 和read

這次主要玩一下echo 和read
echo 輸出內容
read 輸入內容
$ 的使用

#!/bin/bash
#2018-09-04 baron
#github: https://github.com/MyBaron/Shell_practice
# 練習一:
# echo 輸出內容
# read 讀取輸入
# $ 的使用
#--------------------------------------------

# $ 是代表變量替換
# 輸出PATH變量
echo $PATH
echo  '\n Hello World! baron \a \n'

# 定義一個變量
name='helloName'
# '' 和"" 的區別就是 "" 會識別$符號
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..........."
# 引用變量 輸出自己輸入的內容
echo "your name is" ${firstname}${lastname}
# $() 是使用命令,這裏是使用了data命令輸出日誌
echo "Hellp ${firstname}${lastname} today is $(date +%Y%m%d) "
exit 0

NO.2 檢查一下文件是否存在

功能:檢查一下文件是否存在
練習內容:

  1. echo 內容輸出
  2. read 內容輸入
  3. test 檢查條件
  4. 命令使用

#!/bin/bash
#2018-09-14 baron
#github: https://github.com/MyBaron/Shell_practice

# 文件測試
# test 命令 -e 是如果文件存在則爲真
# && ,com1 && com2,只有當com1 爲true時,纔會執行com2
# || ,與&& 相反 只有com1 爲false時,纔會執行com2

echo "the bash is check one file is exist or not \n"
read -p "請輸入你想檢查的文件 " file
test -e ${file} && echo "${file}文件存在" || echo "${file}文件不存在"

# 數值比較
# -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 將文件拷貝到指定目錄下

將文件拷貝到指定目錄下
練習內容

  1. 輸入參數
  2. 邏輯判斷 If-elif-else
#!/bin/bash
#2018-09-015 baron
#github: https://github.com/MyBaron/Shell_practice
#將文件拷貝到指定目錄下

#輸入參數
# 執行該腳本命令 sh xx.sh hello.sh /baron/path
# hello 爲輸入的參數
# ${n} 爲第n個傳入參數 從1開始 0是文件名稱
# $# 爲傳入參數的個數

file=${1}
path=${2}
echo "輸入的file爲${file}"
echo "輸入的path爲${path}"
echo "輸入的參數個數爲$#"


# if-elif-else 邏輯"
# if判斷語句在[] 裏面
# 注意: [] 裏面要有空格!!!!!!
# 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地址是否被佔用
練習內容

  1. while循環
  2. for 循環
  3. seq 指令 用於產生從某個數到另外一個數之間的所有整數
#!/bin/bash

#@author baron
#@data 2019-1-16
#@comtent check long-range server status

network="${1}"

# while循環 循環獲取用戶輸入Ip字段
# 用法:
# 1. 條件與If一樣[] 裏是判斷條件
# 2. do done 裏面是判斷邏輯,do爲開始,done爲結束


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循環遍歷次數
# seq指令是從某個數到另外一個數之間的所有整數
# 用法
# 1. for xx in xx 
# do done 裏面是判斷邏輯,do爲開始,done爲結束
# 
# 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 檢查端口情況

功能:檢查端口情況
練習內容

  1. 輸入流
  2. if 判斷條件
  3. 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
# 設定輸出路徑
testfile=checkPortResult.txt


# 將netstat結果輸出到文件
# > 爲輸入重定向 例如 xx0 > xx1.txt 意思是將xx0的內容輸入到xx1.txt中

netstat -tuln > ${testfile}


# 檢測各個端口情況
# 利用grep 檢索關鍵字

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

# 創建臨時文件
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

# 循環處理數據
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 "最大的進程數是:${R}"
echo "平均的CPU佔用率是:`expr ${US} + ${SY}`%"
echo "用戶平均CPU佔用率:${US}%"
echo "系統平均CPU佔用率:${SY}%"

echo "this is all"
exit 0

No.7 檢查內存情況

功能:檢查CPU情況
使用free 命令獲取內存情況

效果圖

image.png

#!/bin/bash
# baron
# 2019-01-21
# 分析內存使用情況
# 利用free 分析內存使用情況

# 檢測是否有free命令
if  ! which free &> /dev/null ; then
        echo "the sy is no free commam"
        exit 1
fi

echo "正在檢查內存使用情況"

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  "當前使用情況: \n內存總大小:${TOTAL}M \n內存使用量:${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 捕獲後觸發的命令,signals 需要捕獲的命令

echo "無法通過ctrl-c 來終止這個腳本,此腳本會運行10秒"
# SIGINT 是終止線程  SIGTERM 是儘可能終止進程
trap "echo '我已經告訴過你,你無法終止這個腳本'" SIGINT SIGTERM

count=1

while [ $count -lt 10 ]
do
        echo "第${count}秒"
        sleep 1
        count=$[ $count + 1 ]

done
# 捕獲程序退出指令
trap "echo \"腳本運行結束,運行時間${count}秒\" " EXIT

No.10 數組和函數

對數組和函數的練習

效果圖

開始執行fun函數,將返回輸入的數中大於10的數的數組
數組的個數爲6
輸入數組的值爲1 2 3 33 44 55 66
大於10的數有 33 44 55 66
#!/bin/bash
# baron
# 2019-01-24
# 練習函數和數組
#
# 個人覺得數組操作是非常難用,而且功能點很少,在日常中應該避免使用數組
# 在使用數組中,經常利用到echo來構成數組

function fun(){
        echo "開始執行fun函數,將返回輸入的數中大於10的數的數組"
        # 新建一個數組,用於返回
        local newarray
        local elements
        local oldarray
        local number=0
        #獲取輸入的參數
        elements=$[ $# -1 ]
        echo "數組的個數爲${elements}"
        # $@相當於獲取所有的參數,利用echo,相當於輸入參數,()是組成數組
        oldarray=(`echo "$@"`)
        echo "輸入數組的值爲${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的數有 ${newarray[*]}"
}
testArray=(1 2 3 33 44 55 66)
# 此處echo就是相當於輸入數組的值作爲參數,每一個值當做一個參數
# 如果只傳入數組,只能當做是一個參數
arg1=$(echo ${testArray[*]} )
fun $arg1

No.11 函數的返回值

函數的返回值

  1. 返回值return 非必須
  2. 可以將函數賦值給變量

效果

此函數是返回一個數值
用$?接收的返回值是: 200
變量:此函數是返回一個數值
命令返回值是:0

代碼

#!/bin/bash
# baron
# 2019-01-25
# 聯繫函數的return

function fun1(){
         echo "此函數是返回一個數值"
         return  200
}


# 直接調用函數,使用$?獲取返回值
fun1
# $? 上個命令的退出狀態,或函數的返回值
echo "用\$?接收的返回值是: $?"

# 將函數賦值給變量
# 用變量來接收返回值
arg=$(fun1)
#這裏調用變量arg,相當於執行了函數fun1
echo "變量:$arg"
#這裏返回值是0,是因爲這裏的命令值的是echo,而不是$arg的函數命令
echo "命令返回值是:$?"

No.12 awk輸出所有字符串

利用awk切割後,輸出所有字符串

代碼

#!/bin/bash
# baorn
# 2019-01-26
# awk 將輸出所有分割的字符串

# 將echo的以空格切割然後遍歷輸出
# NF是awk的參數,代表切割後個數
# print $i 是輸出切割後的第幾列 $0是整行
val=`echo "第一 第二 第三 第四"|awk '{for(i=1;i<=NF;i++){print $i}}'`
echo $val

No.13 練習函數傳遞數組

練習函數傳遞數組

    #!/bin/bash
# baron
# 2019-01-26
# 練習函數傳遞數組

function fun(){
        local sum=0
        local newarray
        #接收參數
        newarray=(`echo "$@"`)
        #遍歷數組中的每一個數
        for num in ${newarray[*]}
        do
                sum=$[ $sum + $num  ]
        done
        echo $sum

}

array=(1 2 3 4 5 6 )
echo "輸入的數組是 ${array[*]}"
arg1=`echo ${array[*]}`
result=`fun $arg1`
echo "數組累加的結果是:$result"

No.14 使用getopts接收輸入參數

使用getopts接收輸入參數
getopts的命令格式:
getopts optstring name [arg…] 例如:getopts “a:fs” OPTION
getopts 作用就是接收用戶在運行腳本的時候輸入的參數,例如sh xx.sh -i
getopts 通常用while來循環處理,用Case去得到不同的命令處理方式

效果

baron@baron: sh expGetopts.sh -vk -i "this is value"
你輸入的參數是v
你輸入的參數沒有找到匹配
你輸入的參數是i,值是this is value

代碼

#!/bin/bash
# baron
# 2019-01-28
# getopts接收輸入參數


# getopts的命令格式:
# getopts optstring name [arg...]     例如:getopts "a:fs" OPTION
# getopts 作用就是接收用戶在運行腳本的時候輸入的參數,例如sh xx.sh -i
# getopts 通常用while來循環處理,用Case去得到不同的命令處理方式

# 在這裏,接收處理的參數是i v h 三個參數
# 設置的格式是':i:vh'
# 第一個: 代表去掉系統的告警信息
# i: 是指接收i的指令,這個指令還有value,可以用$OPTARG來接收這個value
# v和h:就是單單是指令

while getopts ':i:vh' name
do
        case $name in
          i)
                echo "你輸入的參數是i,值是$OPTARG";;
          v)
                echo "你輸入的參數是v";;
          h)
                echo "你輸入的參數是h";;
         *)
                echo "你輸入的參數沒有找到匹配";;
        esac
done

No.15 將腳本添加到全局命令

將腳本添加到全局命令

效果:

[root@sy4 shell]# sh addBin.sh -i
當前路徑爲/opt/ruqiAgent/shell
temp的內容 addBin.sh
腳本所在的路徑 /opt/ruqiAgent/shell/addBin.sh
安裝命令成功
現在可以在終端使用scriptTest命令

代碼


#!/bin/bash
# baron
# 2019-01-29
# 將這個腳本添加到環境的目錄中,可以使用終端執行命令

function add(){
	# 獲取當前路徑
	wd=`pwd`
	echo "當前路徑爲$wd"
	## 將腳本名稱寫到臨時文件temp
	## basename 是去掉路徑,只剩下文本名稱
	basename "$(test -L "$0" && readlink "$0" || echo "$0")" > temp
	echo "temp的內容 $(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 "現在可以在終端使用scriptTest命令"
}

function succ(){
	echo "使用命令成功"
}
while getopts ':i' name
do
	case $name in
	i)
		 add ;;
	*)
		succ ;;
	esac
done
exit 0

No.16 查看網絡情況和系統信息

查看網絡情況和系統信息
聯繫內容:

  1. 變色字體
  2. tput sgr0還原終端配置
  3. ping 查看網絡情況
  4. uname 查看系統信息

效果

網絡狀態:可連接
該系統類型是:GNU/Linux
系統的發行版本:3.10.0-862.el7.x86_64
系統的名稱:Linux
系統的類型:x86_64

代碼

#!/bash/bin
# baron
# 2019-01-31
# 測試網絡和系統信息


# tput 可以更改幾項終端功能,如移動或更改光標、更改文本屬性,以及清除終端屏幕的特定區域
# sgr0 表示清除所有更改的配置
reset=`tput sgr0`

# 查看是否可以聯網
# \E[32m 是修改字體顏色,32m 是綠色
ping -c 1 www.baidu.com &> /dev/null && echo -e '\E[32m'"網絡狀態:${reset}可連接 " || echo -e '\E[32m'"網絡狀態:${reset}未連接"


# 查看系統類型
# mac系統並沒有-o選項
os=`uname -o`
echo -e '\E[32m'"該系統類型是:${reset}$os"


# 系統的發行版本
REV=`uname -r`
# 系統的名稱
OS=`uname -s`
# 系統類型
MACH=`uname -m`
echo -e '\E[32m'"系統的發行版本:${reset}$REV"
echo -e '\E[32m'"系統的名稱:${reset}$OS"
echo -e '\E[32m'"系統的類型:${reset}$MACH"


No.17 查看系統網絡

查看網絡情況和系統信息

效果圖

 本地ip地址: 10.10.1.234 172.17.0.1
 外網ip地址:  183.238.79.207
 DNS地址:  114.114.114.114 8.8.8.8

代碼


#!/bin/bash
# baron
# 2019-02-12
# 查看系統網絡

reset=`tput sgr0`

# 獲取本地Ip
internalip=`hostname -I`
echo -e '\E[32m' "本地ip地址:"${reset} ${internalip}

# 獲取外網Ip
externalip=`curl -s ipecho.net/plain`
echo -e '\E[32m' "外網ip地址:" ${reset} $externalip

# 定義DNS服務器的IP地址
# sed '1 d' 代表刪除第一行
nameservers=$(cat /etc/resolv.conf | sed '1 d' | awk '{print $2}' )
# 也可以用awd 的NR 來實現sed的效果
nameservers1=$(cat /etc/resolv.conf | awk 'NR>1{print $2}' )
echo -e '\E[32m' "DNS地址:" ${reset} ${nameservers}

No.18 自動提交push代碼到遠程

自動提交push代碼到遠程
思路:

  1. 將本腳本的添加到忽略提交名單中
  2. 利用git命令進行提交
  3. commit 信息是當前日期
#!/bash/bin
# baron
# 2019-02-13
# 自動提交到遠程代碼庫

# 檢查當前路徑是否有.git文件夾
function judge(){
	if [  -x ".git" ];then
		# 獲取當前文件的名稱
		if [ -f  ".git/.gitignore"  ];then
			echo "添加忽略提交該腳本到遠程代碼庫"
			echo "當前腳本名稱${0}"
			echo ${0} >> .git/.gitignore
			push
		else
			echo "創建 .gitignore文件"
			echo "當前腳本名稱${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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章