shell脚本基本配置

内置函数RANDOM可以随机生成随机数其范围为:0~32767

脚本内第一行:#!/bin/bash
  标记该脚本要使用的bash环境,不同系统可能需要使用不同的bash环境
执行脚本
  1、脚本有执行(x)权限,切换到脚本所在目录下, chmod +x 脚本名
     ./脚本名.sh
  2、脚本没有执行权限,可以在任何目录位置下执行
     sh  脚本名.sh
     sh -x 脚本名.sh  显示执行过程
     sh -n 脚本名.sh  检测脚本语法错误
  3、脚本没有执行权限,可以在任何目录位置下执行
     source  脚本名.sh

标准输入:从该设备接收用户输入的数据,描述编号:0
  设备文件:/dev/stdin,默认设备:键盘
标准输出:通过该设备向用户输出数据,描述编号:1
  设备文件:/dev/stdout,默认设备:显示器
标准错误:通过该设备报告执行出错信息,描述编号:2
  设备文件:/dev/stderr,默认设备:显示器
重定向输入:<  从文件中读取数据,不通过键盘输入
重定向输出:>  把控制台要显示的内容输出到文件,覆盖文件内原有内容
           >>  把控制台要显示的内容输出到文件,在原有内容后追加
标准错误输出:2> 把控制台要输出的错误信息输出到文件
             2>>
混合输出:&>  将标准输出、标准错误的内容保存到同一个文件中
          &>>
          
echo "123.com" > pwd.txt
useradd  usera
passwd --stdin usera < pwd.txt
samba里如果要给程序用户设置密码,密码文件中的密码要输入两遍
vim  pwd.txt
  123.com
  123.com
pdbedit -a -u usera < pwd.txt

变量:代表某个不确定的值
变量的类型
  自定义变量:由用户自己定义、修改和使用
  环境变量:由系统维护,用于设置工作环境
  位置变量:通过命令行给脚本程序传递参数
  预定义变量:Bash中内置的一类变量,不能直接修改
定义变量:变量名=变量值
使用变量:$变量名
输出变量值:echo  $变量名
双引号:值为字符串的时候要加"",里面可以引用变量
  a="world"
  b="Hello $a"  
  echo  $b   结果为  Hello world
单引号:用法跟双引号类似,里面不能引用变量
  a="world"
  b='Hello $a'  
  echo  $b   结果为  Hello $a
反撇号(1左边那个~) :命令替换,提取命令执行后的输出结果,不能用于命令嵌套
  res=`uname -s`   
  echo $res  结果为linux  
$():用法跟反撇号类似,但可以用于命令嵌套
  rpm  -qf  $(which  rpm)
  先查找rpm命令文件位置,再查看rpm的命令文件是由哪个软件包安装的

从控制台输入内容给变量赋值
read  [-p "提示信息"]  变量名

read -p "请输入数字" NUM
请输入数字 23
echo  $NUM   结果  23

等待后面的命令一段时间,超时就自动往后运行
stty -icanon min 0 time 100  (100=10秒)

export  变量=变量值     定义全局变量

数字运算
expr  数字1  运算符  数字2
NUM1=10
NUM2=5
NUM3=$(expr $NUM1 + $NUM2)
let NUM3=NUM1+NUM2
NUM3=$(($NUM1 + $NUM2))
+ - 
乘:\* 
除:/ 
取余:%  10%3=1

位置变量:
./test.sh   one   two   three   four   five   six
            $1    $2    $3       $4    $5     $6
$0:当前执行的进程/程序名
$#:命令行中位置变量的个数
$?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
$*:所有位置变量

测试命令:test
test 条件表达式
[ 条件表达式 ]:条件表达式前后跟中括号之间有空格
条件表达式:判断语句,结果只有真(0)和假(非0)两种

文件测试
-d:测试是否为目录(Directory)
-e:测试目录或文件是否存在(Exist)
-f:测试是否为文件(File)
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试当前用户是否有权限执行(eXcute)

[ -d /etc ]
echo  $?  结果为0
   
整数比较
-eq:等于(Equal)
-ne:不等于(Not Equal)
-gt:大于(Greater Than)
-lt:小于(Lesser Than)
-le:小于或等于(Lesser or Equal)
-ge:大于或等于(Greater or Equal)
[ 2 -gt 1 ]
echo $?   结果为0

字符串比较
=:字符串内容相同
!=:字符串内容不同,! 号表示相反的意思
-z:字符串内容为空

[ -z 字符串 ]  判断一个字符串是否为空

逻辑测试
格式1:[  表达式1  ]  操作符  [  表达式2  ]  前后连接两个条件表达式
格式2:命令1  操作符  命令2  ... 

&&:①逻辑运算符,并且
   ②命令连接符,当前一条命令正确执行才执行后一条命令
-a或&&:逻辑与,“而且”的意思
-o或||:逻辑或,“或者”的意思
!:逻辑否

判断是否存在目录/media/cdrom,如果不存在就创建
[ ! -d /media/cdrom ] && mkdir /media/cdrom

单分支结构
if  条件测试操作
then
   命令序列
fi

判断是否存在目录/media/cdrom,如果不存在就创建
if [ ! -d /media/cdrom ]
then
  mkdir  /media/cdrom
fi

双分支结构
if  条件测试操作
    then   命令序列1
    else   命令序列2
fi

启动服务,成功或失败输出一个提示语句
systemctl  start  ****
if [ $? = 0 ]      $?表示上一条启动服务的命令是否正确执行
then
  echo "服务启动成功"
else
  echo "服务启动失败"
fi

多分支结构:在条件1不满足的时候去判断条件2
if  条件测试操作1
    then  命令序列1
elif  条件测试操作2 
    then  命令序列2
else
  命令序列3
fi

if  分数为85~100之间
    then   判为优秀
elif   分数为70~84之间
    then   判为合格
esle
    判为不合格
fi

数字运算 expr  变量1  运算符  变量2
a=1
b=2
c=$(expr $a + $b) ==> c=$(($a+$b)) ==> let c=a+b
 

数组:用一个变量表示一组值
在shell中数组长度(就是数组中值的个数)是不定的
用法:
n=(1 2 3 4)
echo ${n[0]}  结果1
[]里是下标(index),从0开始,
0是第一个,1是第二个,...
num=${#n[@]}:num的值就是数组中值的个数
${数组名[@]}:显示数组中的所有值

循环:用来执行大量重复、有规律的操作
for循环(语法1)  

for ((初始化变量①;循环条件②;变量迭代③))
do
  命令序列④
done

执行过程①->②->④->③->②->④->③->....
直到②中的条件不满足就结束循环执行done后面的命令

遍历数组(输出数组中的每一个值)
n=(1 2 3 4)
for ((i=0;$i<${#n[@]};i++))
do
  echo ${n[$i]}
done

计算从1到100相加的值(1+2+3+4+5+...+100)
sum=0
for ((i=1;$i<=100;i++))
do
  sum=$(($sum+$i))
done
echo $sum;

乘法表
for ((i=1;$i<10;i++))
do
  for ((j=1;$j<=$i;j++))
  do
   echo -e "${j}*${i}=$(($j*$i))\t\c"
  done
  echo ""
done

-e  输出的时候支持转义符
\t  制表位
\c  不换行输出
\n  换行输出

for循环(语法2:for each循环)
for 临时变量 in 变量2
do
  命令序列
done
临时变量在每一次循环的时候分别表示变量2中的每一个值

从数据库读取用户名和密码,然后在系统中创建相同用户名和密码的用户

create database guigu;
use  guigu;
create table stu (
stu_name varchar(50),
stu_pwd varchar(50)
);
insert into stu values ('aa','aa');
....(多插入几条数据)

#!/bin/bash
mysql -u root -p123.com -e "select stu_name from guigu.stu;" > /root/name.txt
mysql -u root -p123.com -e "select stu_pwd from guigu.stu;" > /root/pwd.txt
i=0
NAME=$(cat /root/name.txt)
PWD=$(cat   /root/pwd.txt)
NAME1=()
PWD1=()
for SNAME in $NAME
do
  NAME1[$i]=$SNAME
  let i++
done
i=0
for SPWD in $PWD
do
  PWD1[$i]=$SPWD
  let i++
done
for ((i=1;$i<${#NAME1[@]};i++))
do
  useradd ${NAME1[$i]} >> /dev/null
  echo ${PWD1[$i]} | passwd --stdin ${NAME1[$i]} >> /dev/null
done

while循环
while  循环条件
do
  命令序列
done

计算从1到100相加的值(1+2+3+4+5+...+100)
#sum=0
#i=1
#while [ $i -lt 101 ]
#do
#  sum=$(($sum+$i))
#  let i++
#done
#echo $sum 
sum=0
i=0
while [ $i -lt 100 ]
do
  let i++
  sum=$(($sum+$i))
done
echo $sum 

while循环必须要有一个改变条件变量的命令,否则会死循环

case多分支选择结构
case  变量  in
值1)
  命令序列1
  ;;
值2)
  命令序列2
  ;;
...
*)
  默认命令序列
esac

变量如果是值1,就执行序列1,如果是值2,就执行序列2,...
如果都不是,就执行默认序列
;;用来打断,只要匹配上某个值,就不会继续往下执行

vim test.sh

#!/bin/bash
case $1 in
start)
  echo "启动服务$2"
  ;;
stop)
  echo "停止服务$2"
  ;;
status)
  echo "查看服务$2"
  ;;
*)
  echo "请输入正确指令"
esac

sh test.sh start httpd

结果:启动服务httpd

正则表达式:
  是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串
正则表达式组成
  普通字符
    大小写字母、数字、标点符号及一些其他符号
  元字符
    在正则表达式中具有特殊意义的专用字符

基础正则表达式的常见元字符    
^、用在一个字符串前,表示以..开头(^[a-z],表示小写字母开头的行)
$、用在一个字符串后,表示以..结尾(,$),表示用,结尾的行
.、表示最多一个任意字符
\、转义符,用在一个符号前,取消该符号的特殊作用("\"",用来表示一个")
*、用在一个字符串后,表示这个字符串出现0或多次(a*,表示字母a出现0到多次)
[ ]、表示内容包含的内容([a],表示包含小写字母a,[5]表示包含数字5)
[^]、表示内容不包含的范围([^A-Z],表示不包含大写字母)
[n1-n2]、表示内容包含一个范围([a-z],表示包含小写字母,[0-9]表示包含数字)
{n}、表示前面的字符串出现的次数最多n次,可以不连续
  ([a-z]{5},表示最多有5个小写字母)
{n,}、表示前面的字符串出现的次数至少n次,可以不连续
  ([A-Z]{5,},表示至少有5个大写字母)
{n,m}表示前面的字符串出现的次数大于n小于m,可以不连续
  ([A-Z]{5,10},表示有5-10个大写字母)

查找文件内包含小写字母的行
grep "[a-z]" 文件
查找行内至少有3个o的行
grep "o{3,}"  文件
查找包含以w开头,d结尾,中间至少两个o的行
grep "wo\{2,\}d" 文件   
查找至少以两个wo开头,d结尾的内容
grep "[wo]\{2,\}d" 文件
查找有连续的o的行
grep "o*" 文件  (可以一个o都没有)
grep "oo*" 文件 (至少有一个)

扩展正则表达式的常见元字符

+    重复一个或者一个以上的前一个字符(a+,表示至少一个a)
?    零个或者一个的前一个字符(a?,表示最多一个a)
|    使用或者(or)的方式找出多个字符
( )    查找“组”字符串
( )+    辨别多个重复的组
  
扩展正则表达式要用egrep
egrep "t(e|a)st"  文件   test、tast都能被查到
egrep "t(e|a)+st" 文件   teest、teast、taest、taast..

直接修改文件
sed -i ""  文件

把ONBOOT行内的no改成yes
sed -i "/ONBOOT/s/no/yes/g" 文件
删除UUID所在行
sed -i "/UUID/d"  文件
在第12行后面添加IPADDR=$IP
sed -i "12a IPADDR=$IP"  文件
删除第18行
sed -i "18d" 文件
把文件内所有ens33改成ens37
sed -i "s|ens33|ens37|" 文件 
在option所在行的下一行添加subnet
sed -i "/option/a subnet"  文件

awk -F. '{print $2}' 文件 
awk  '{print $1}'

s="abcdefghijklmn"
s1=${变量名:0:2}
结果:ab
s2=${s:1:-1}
结果:bcdefghijklm
s3=${s:0-5:3}
结果:jkl
s4=${s:0-5:-3}
结果:jk
第二个参数为正数,作用是从左开始数
第二个参数为0-n,作用是从右开始保留n个
第三个参数为正数,作用是从前面开始保留的数量
第三个参数为负数,作用是从后面开始去掉的数量
统计字符串长度${#变量名}
乘方运算
vim mi.sh

#!/bin/bash
num=1
for ((i=0;$i<$2;i++))
do
  num=$(($num*$1))
done
echo $num

sh mi.sh 2 3    结果是8

冒泡排序
vim  mp.sh

#!/bin/bash
n=(3 2 4 5 1)
for ((i=${#n[@]};$i>1;i--))
do
  for ((j=0;$j<$(($i-1));j++))
  do
   k=$(($j+1))
   if [ ${n[$j]} -gt ${n[$k]} ]
   then
    m=${n[$j]}
    n[$j]=${n[$k]}
    n[$k]=$m
   fi
  done
done
for ((i=0;$i<${#n[@]};i++))
do
  echo ${n[$i]}
done

#!/bin/bash
n=()
for ((i=0;i<=i;i++ ));do
        read -p "请输入第 $(($i+1)) 个数字:" qw
        if [ -z $qw ];then
                break
        fi
        n[$i]=$qw
done
echo "排序前:${n[@]}"
l=${#n[@]}
for ((i=1;i<$l;i++))
do
 for ((j=0;j<$(($l-$i));j++))
 do
  k=$(($j+1))
  if [ ${n[$j]} -gt ${n[$k]} ]
  then
   t=${n[$j]}
   n[$j]=${n[$k]}
   n[$k]=$t
  fi
 done
done
echo "排序后:${n[@]}"

水仙花数:一个n位数,每个数位上数字的n次方加起来还等于原来的数

for ((i=100;$i<9999;i++))
do
  sum=0
  n=$i
  for ((j=0;$j<${#i};j++))
  do
    a=$(($n%10))
    s=1
    for((k=0;$k<${#i};k++))
    do
      s=$(($s*$a))
    done
    sum=$(($sum+$s))
    n=$(($n-$a))
    n=$(($n/10))
  done
  if [ $sum = $i ]
  then
    echo $i
  fi
done

#!/bin/bash
for ((i=100;i<10000;i++))
do
  l=${#i}
  s=0
  for ((j=0;j<$l;j++))
  do
   n=${i:$j:1}
   c=1
   for ((k=0;k<$l;k++))
   do
    c=$(($c*$n))
   done
   s=$(($s+$c))
  done
  if [ $s -eq $i ]
  then
   echo $s
  fi
done

乘法表

#for ((i=1;$i<10;i++))
#do
#  for ((j=1;$j<=$i;j++))
#  do
#   echo -e "$j*$i=$(($j*$i))\t\c"
#  done
#  echo ""
#done

i=1
while [ $i -lt 10 ]
do
  j=1
  while [ $j -le $i ]
  do
   echo -e "$j*$i=$(($j*$i))\t\c"
   let j++
  done
  echo ""
  let i++
done


退出脚本
exit

退出循环
break
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据库从删库到跑路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值