shell脚本基础介绍与特使变量

一shell介绍

1.用途:使用简单,是Shell命令的集合

优点:运行节省时间,可实现批量管理,自动化,批量处理减少出错概念率。
2.shell概述:

shell:命令解释器,也是一个程序
种类:sh,bash,ksh,csh…(大多数的l=Linux发行版为 bash)

3.bash的特性:
a 历史记录----> 用户行为升级
b 别名 --------->企业垃圾桶(rm --> mv)
c 补全 ----------->命令 ($PATH), 目录
d 支持通配符—> , [ ] , [^]
e 前后台作业 —> jobs ,& ,bg ,fg
f 运行脚本:系统Shell类型cat /etc/shells(默认 shell echo $SHELL)

4.bash安全性:

输入env x=’(){:;}; echo be careful ’ bash -c “echo this is a test”
this is a test 则不需要升级系统
如果返回
be careful
this is a test 则需要升级系统
[root@localhost ~]# yum -y update bash
[root@localhost ~]# rpm -qa bash

5.shell的建立:

a:登录(交互)式shell和非登录(交互)式shell
**登录式shell:环境变量文件加载顺序/etc/profile(/etc/profile.d/),/.bash_profile,/.bashrc,/etc/bashrc
登录式shell场景:输入用户名和密码,“su - test002”定时计划任务,ansible的playbook。

b shell执行:加载环境变量ENV,该变量制定了环境文件(/etc/profile(/etc/profile.d/*),/.bash_profile,/.bashrc,/etc/bashrc) —》执行内容
6.shell的执行

a 通过sh或者bash命令执行
[root@bogon test]# bash useradd.sh
[root@bogon test]# sh useradd.sh

b 直接运行,脚本必须要有可执行权限
[root@bogon test]# /root/test/useradd.sh

c 通过. 或者source 执行,在文件中的变量,函数的返回值将会加载到父及bash环境中。
[root@bogon test]# . useradd.sh
[root@bogon test]# source useradd.sh
在脚本中定义的变量时局变量,
在命令行可以echo $hanhan 的是全变量,

d 通过重定向,说明bash和sh是可以接受标准输入的。
[root@bogon test]# bash < test.sh
[root@bogon test]# sh < test.sh

7.Shell脚本的注释
单行注释:#
多行注释::<<BLOCK
BLOCK

8.shell脚本规范
(1)开头指定脚本解释器
#!/bin/sh或#!/bin/bash
其他行#表示注释
名称见名知义 backup_mysql.sh,以sh结尾
(2)开头加版本版权等信息
#Date:创建日期
#Author:作者
#Mail:联系方式
#Function:功能
#Version:版本
(3)脚本中尽量不用中文注释
别吝啬添加注释,必要的注释方便自己别人理解脚本逻辑和功能;
尽量用英文注释,防止本机或切换系统环境后中文乱码的困扰;
单行注释,可以放在代码行的尾部或代码行的上部;
多行注释,用于注解复杂的功能说明,可以放在程序体中,也可以放在代码块的开始部分
代码修改时,对修改的内容
(4)多使用内部命令
内部命令可以在性能方面为你节省很多。
type 命令。
(5)没有必要使用cat命令,尽量少使用管道。
eg:cat /etc/passwd | grep guru
使用以下方式即可
eg:grep guru etc/passwd
(6)代码缩进
(7)仔细阅读出错信息
有时候我们修改了某个错误并再次运行后,系统依旧会报错。然后我们再次修改,但系统再次报错。这可能会持续很长时间。
但实际上,旧的错误可能已经被纠正,只是由于出现了其它一些新错误才导致系统再次报错
(8)脚本以.sh为扩展名
eg:script-name.sh

二shell变量

1.查看:env: 系统的全局变量
set: 所有的全局变量
declare: 所有导入的全局变量和函数

定义全局变量
[root@bogon test]# export a=“123”
[root@bogon test]# b=456
[root@bogon test]# export b

局部变量的定义
’ ’ : 强引
" " :弱引
: 执行Shell命令
在这里插入图片描述
永久生效
/etc/profile(/etc/profile.d/*),/.bash_profile,/.bashrc,/etc/bashrc

2.shell中常见的固定性的内容的生成
加密码:

          Centos 6:
           grub-md5-cryp
         
        Centos 7:
        grub2-mkpasswd-pbkdf2 

         grub-md5-crypt >> /etc/grub.conf
        grub-md5-crypt |tee -a /etc/grub.conf

md5文件校验码:
[root@bogon test]# md5sum passwd1
56cf56372303c1c769ec0d030144e60c passwd1
[root@bogon test]# md5sum passwd
911bc5a50ff7cb7e2de6addb28c94abe passwd
(1)生成自然数:
方法一:
[root@bogon test]# echo {001…100}
[root@bogon test]# echo {1…100}
在这里插入图片描述
实例:
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-19 18:26:33
#Name:num.sh
#Version:V1.0
#Description:This is a test script.
read -p “请输入起始值:” sta
read -p “请输入终止值:” sto

for i in eval echo {$sta..$sto}
do
echo $i
done
总结:bash不会解析多层变量,eval命令能解析多层变量。
[root@bogon test]# set 11 22 33 44
[root@bogon test]# echo $4
44
[root@bogon test]# echo $# #打印参数的个数
4
[root@bogon test]# echo $$#
$4
[root@bogon test]# eval echo $$#
44

方法二:
seq命令用于产生从某个数到另外一个数之间的所有整数。
seq [选项]… 尾数
seq [选项]… 首数 尾数
seq [选项]… 首数 增量 尾数
-f, --format=格式 使用printf 样式的浮点格式
-s, --separator=字符串 使用指定字符串分隔数字(默认使用:\n)
-w, --equal-width 在列前添加0 使得宽度相同
[root@localhost ~]# seq -f “%3g” 8 12

[root@localhost ~]# seq -f “%03g” 8 12

[root@localhost ~]# seq -w 8 12

[root@localhost ~]# seq -s" " -f"str%02g" 9 11

[root@localhost ~]# seq -s"echo -e "\t"" 9 11

[root@localhost ~]# seq -s"echo -e "\n"" 9 11

[root@localhost ~]# seq -s"=" 9 11

(2)随机数生成:
方法一: $RANDOM

[root@bogon test]# cat random.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-20 09:11:09
#Name:random.sh
#Version:V1.0
#Description:This is a test script.

function rand(){
min=KaTeX parse error: Expected 'EOF', got '#' at position 4: 1 #̲400000 max…(( 2 − 2- 2min+1)) #500000-400000+1 100001
num= ( ( (( ((RANDOM+1000000000)) #增加一个10位的数再求余 #4012 +10000000000 = 1000004012
echo ( ( (( ((num% m a x + max+ max+min)) # 1000004012%100001 +400000 < 100001 +400000 < 500000;
}

read -p “please input your num of start:” sta
read -p “please input your num of end:” sto

rnd=$(rand $sta $sto)
echo $rnd
exit 0

方法二:openssl
[root@bogon test]# openssl rand -base64 8 |md5sum |cut -c 1-12
[root@bogon test]# openssl rand -base64 8 |cksum |cut -c 1-10 #最大十位
在这里插入图片描述
生成UUID:
[root@bogon test]# uuidgen
[root@bogon test]# cat /proc/sys/kernel/random/uuid
在这里插入图片描述
生成MAC:
[root@bogon test]# echo “00:0c:29:openssl rand -hex 3 | sed 's/\(..\)/\1:/g; s/.$//'
在这里插入图片描述

(3)命令排序
; 拼接多个命令没有逻辑关系
[root@bogon test]# ll 123;sh useradd.sh
&& 拼接多个命令,有逻辑关系
[root@bogon test]# sh useradd.sh && ll 123
[root@bogon test]# ll 123 && sh useradd.sh
|| 拼接命令,有逻辑关系,
[root@bogon test]# ll 123 || sh useradd.sh
注意:
command & 后台执行
command &>/dev/null 混合重定向(标准输出1,错误输出2)
command1 && command2 命令排序,逻辑判断

(4)通配符及转移


  • [] :
    [^] :

{} 集合
[root@bogon boot]# mkdir /home/{111,222}
[root@bogon boot]# mkdir -pv /home/{333/{aaa,bbb},444}
[root@bogon boot]# cp -vp /etc/sysconfig/network-scripts/ifcfg-ens32 /etc/sysconfig/network-scripts/ifcfg-ens32.bak
“/etc/sysconfig/network-scripts/ifcfg-ens32” -> “/etc/sysconfig/network-scripts/ifcfg-ens32.bak”
[root@bogon boot]# cp -vp /etc/sysconfig/network-scripts/{ifcfg-ens32,ifcfg-ens32.bak1}
“/etc/sysconfig/network-scripts/ifcfg-ens32” -> “/etc/sysconfig/network-scripts/ifcfg-ens32.bak1”
[root@bogon boot]# cp -vp /etc/sysconfig/network-scripts/ifcfg-ens32{,.bak2}
“/etc/sysconfig/network-scripts/ifcfg-ens32” -> “/etc/sysconfig/network-scripts/ifcfg-ens32.bak2”

[root@bogon ~]# echo -e “a\tb”
a b
[root@bogon ~]# echo -e “a\tb”
a b
[root@bogon ~]# echo -e “a\nb”
a
b
[root@bogon ~]# echo -e “anb”
anb
[root@bogon ~]# echo -e ‘a\nb’
a
b
[root@bogon ~]# echo -e “a\nb”
a
b

(5) 位置变量
$0,
$1,$2 … 9 , 9, 9,{10},${11} … # 接收脚本或者函数的位置参数。
$0 文件名,若执行脚本时带有路径,会将路径和将本名同事输出。
$# 表示参数的个数
实例:
[root@bogon test]# cat random.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-20 09:11:09
#Name:random.sh
#Version:V1.0
#Description:This is a test script.

function rand(){
min=KaTeX parse error: Expected 'EOF', got '#' at position 4: 1 #̲400000 max…(( 2 − 2- 2min+1)) #500000-400000+1 100001
num= ( ( (( ((RANDOM+1000000000)) #增加一个10位的数再求余 #4012 +10000000000 = 1000004012
echo ( ( (( ((num% m a x + max+ max+min)) # 1000004012%100001 +400000 < 100001 +400000 < 500000;
}

#read -p “please input your num of start:” sta
#read -p “please input your num of end:” sto

#rnd=$(rand $1 $2)
if [ KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ -eq 2 ] …# :用户传递的参数个数
then
rnd=$(rand $1 $2) # $1 $2 :用户传递的位置参数
echo $rnd
exit 0

else
echo “parameter is not anough,[ $0 parameter1 parameter2]” #$0 :脚本名
fi

        $*                   获取当前Shell脚本所有传参的参数,不加引号和$@相同;如果给$*加上双引号,例如:"$*",则表示将所有的参数视为单个字符串,相当于"$1 $2 $3"
        $@                 获取当前Shell脚本所有传参的参数,不加引号和$*相同;如果给$@加上双引号,例如:"$@",则表示将所有参数视为不同的独立字符串,相当于"$1" "$2" " $3" "..."。当"$@"和"$*"都加双引号时,两者是有区别的;都不加双引号时,两者无区别。

# ∗ , *, ,@ 获取所有参数。
:<<BLOCK
n=0
for i in "KaTeX parse error: Expected 'EOF', got '#' at position 6: *" #̲"" 表示把所有参数当成一个整体,$ 表示所有参数是独立的个体。
do
echo $i
let n++
done
echo $n #统计循环次数
#echo $*
BLOCK

n=0
for i in “KaTeX parse error: Expected 'EOF', got '#' at position 5: @" #̲ "@”,$@ 表示所有参数是独立的个体。
do
echo $i
let n++
done
echo $n

(6)dirname,basename
[root@bogon test]# dirname /root/test/var2.sh
/root/test
[root@bogon test]# basename /root/test/var2.sh
var2.sh

实例:
[root@bogon test]# cat var2.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-20 11:23:32
#Name:var2.sh
#Version:V1.0
#Description:This is a test script.
echo $0
echo “dirname $0” #dirname 打印路径
echo “basename $0” #basename 打印文件名

(7)状态变量
$? :(1)判断上一条命令是否执行成功,成功则返回0,不成功则返回非0;
(2)获取脚本的exit的退出码
(3)获取的是函数的返回值

实例:监控web服务状态是否正常
思路:a 判断进程:[root@bogon test]# ps -ef |grep httpd
[root@bogon test]# killall -0 httpd
b 判断端口:[root@bogon test]# netstat -tunalp |grep 80
c 判断链接:[root@bogon test]# curl 127.0.0.1

实例
[root@bogon test]# cat monitor_httpd.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-20 11:45:41
#Name:monitor_httpd.sh
#Version:V1.0
#Description:This is a test script.

service=httpd

while true
do
killall -0 $service &>/dev/null
#curl 127.0.0.1 &>/dev/null
#ps -ef |grep httpd |grep -v grep &>/dev/null
#netstat -tulanp |grep 80 &>/dev/null
if [ $? -eq 0 ]
then
echo “httpd is up …”
else
echo “httpd is down …”
fi
sleep 1
done

实例:
[root@bogon test]# cat state1.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-20 14:56:47
#Name:state1.sh
#Version:V1.0
#Description:This is a test script.

testfun(){
#i=$1
if (($1<200))
then
echo “$1”
#exit 1
return 1
fi
}

testfun $1
#echo $?
if [ ? − e q 1 ] t h e n e c h o " 输 对 了 。 。 。 " e l s e e c h o " 输 错 了 。 。 。 " f i ( 8 ) ? -eq 1 ] then echo "输对了。。。" else echo "输错了。。。" fi (8) ?eq1]thenecho""elseecho""fi8$: 获取当前脚本的进程号
实例:
[root@bogon test]# cat test_ping.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-20 15:49:20
#Name:test_ping.sh
#Version:V1.0
#Description:This is test script.
if [ -f /tmp/pid.ping ]
then
kill cat /tmp/pid.ping
echo > / t m p / p i d . p i n g e l s e e c h o >/tmp/pid.ping else echo >/tmp/pid.pingelseecho >/tmp/pid.ping
fi

while true
do
for i in cat IP.txt
do
#echo $i
sleep 5
ping -c 1 $i &>/dev/null
if [ ? − e q 0 ] t h e n e c h o " ? -eq 0 ] then echo " ?eq0]thenecho"i tong …" >> ping.log
else
echo “$i not tong …” >> ping.log
fi
done
#sleep 5
#echo $$ > /tmp/pid.ping
done
#rm -rf /tmp/pid.ping

$! :获取上一个在后台运行的进程PID
$_ :获取上一个命令的最后一个参数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值