shell脚本

案列1:批量创建任意数量的用户并设置随机密码


[root@shell_test example_shell]# cat useradd_set_passwd.sh 
#!/bin/bash
#auth:sunwei
#以下几种方式都可以从命令行读取参数,进而传入脚本中
#userlist="$@"
#userlist="$*"
#userlist=$@
userlist=$*
userinfo=./user.info
#接收从命令行传入的用户名,进而创建
#for user in $userlist;do
num1=$1
num2=$2
#用户名前缀固定,接收从命令行传入的用户名后缀
for user in $(seq -f 'user%03g' $num1 $num2);do
  if ! id $user &>/dev/null;then
    pass=$(echo $RANDOM|md5sum |cut -c 1-8)
    useradd $user
    echo $pass |passwd --stdin $user
    echo "$user $pass" >>$userinfo
    if id $user &>/dev/null;then
      echo "$user user was created successful..."
      echo "======================================"
    else
      echo "$user create failed..."
    fi
  else
    echo "$user user already exists..."
  fi
done

案例2:批量主机执行命令(shell)

可以阅读网友博客:https://www.jellythink.com/archives/373
我们可以使用ssh root@192.168.1.4 "df -h"这种方式去远程主机执行密码(前提是做好免密码ssh配置),但是还可以使用expect脚本去实现,更加方便。下面为脚本:

#主机文件(存放用户名密码的文件)
[root@shell_test example_shell]# cat host.info 
192.168.1.4 root 22 sunwei@123
#192.168.1.5 root 22 123
192.168.1.6 root 22 sunwei@123

脚本示例:
[root@shell_test example_shell]# cat expect.sh 
#!/bin/bash
#auth:sunwei
COMMAND=$*
HOST_INFO=host.info

for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO);do
  USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
  PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
  PASS=$(awk -v ip=$IP 'ip==$1{print $4}' $HOST_INFO)
  expect -c "
    spawn ssh -p $PORT $USER@$IP
    expect {
      \"(yes/no)\" {send \"yes\r\"; exp_continue}
      \"password:\" {send \"$PASS\r\"; exp_continue}
      \"$USER@*\" {send \"$COMMAND\r exit\r\"; exp_continue}
    }
  "
  echo "---------------------"
done
[root@shell_test example_shell]# ./expect.sh free -g

案例3:检测网站可用性(使用curl)

脚本核心是采用curl工具探测网站通过状态返回码来判断网站是否可用

#!/bin/bash
#auth:sunwei
URL_LIST="www.baidu.com www.abcd.com"

for URL in $URL_LIST;do
  FAIL_COUNT=0
  for ((i=1;i<=3;i++ ));do
    HTTP_CODE=$(curl -s -o /dev/null --connect-timeout 3 -w "%{http_code}" $URL)
    if [ $HTTP_CODE -eq 200 ];then
      echo "$URL is ok..."
      break
    else
      echo "$URL retry $i"
      let FAIL_COUNT++
    fi   
  done
  if [ $FAIL_COUNT -eq 3 ];then
    echo "$URL had retry $FAIL_COUNT..failure"
  fi
done

案例4:shell处理用户命令行选项

#!/bin/bash
while [ -n "$1" ];do
  case $1 in
    -a)
       echo "Found the -a option";;
       
    -b)
       para="$2"
       echo "fount the -b option,and the $para"
       shift ;;
    --)
       shift
       break;;
  esac
  shift
done

count=1
for para in "$@";do
  echo "para#$count: $para"
  count=$[$count+1]

done
[root@shell_test shell]# sh para.sh -a -b test1 -- test2 test3
Found the -a option
fount the -b option,and the test1
para#1: test2
para#2: test3

案例5: vmstat输出小脚本

需求:学习vmstat命令中各项参数的含义。开发一个脚本,定时(一分钟
一次)执行vmstat,连续执行两个小时,将其输出定向到一个文件。两小时后,由脚本将这些值进行处理,处理后重新写入到新的文件中,处理包括以下内容:

  • 1.自动求出每个参数在这两个小时里的平均值,最大值和最小值。
  • 2.对超过平均值浮动范围10%的数值以红色或粗体标出。
#!/bin/bash

#定义变量
current_time=`date '+%Y-%m-%d %H:%M:%S'`
one_mins_later=`date '+%Y-%m-%d %H:%M:%S' -d +1min`
output_file1=/tmp/vmstat.log
output_file2=/tmp/file_vmstat
>${output_file2}

#定义vmstat输出函数
function vmstat_out(){
  vmstat|tail -n 1  >> ${output_file1}
  sleep 5
}

#定义统计指标函数
function average_max_min(){
  num=$2
  field=$1
  average=`awk '{sum+=$'$num'} END {print sum/(NR-1)}' ${output_file1}`
  max=`awk 'NR!=1{print }' ${output_file1} |awk 'NR==1{max=$'$num';next}{max=max>$'$num'?max:$'$num'}END{print max}'`
  min=`awk 'NR!=1{print }' ${output_file1} |awk 'NR==1{min=$'$num';next}{min=min<$'$num'?min:$'$num'}END{print min}'`
  #平均值上限:平均值乘以110%  
  #平均值下限:平均值乘以90%
  upper_value=`echo ${average}*1.1|bc`
  lower_value=`echo ${average}*0.9|bc`
  #echo "$1: $average  $max  $min ${upper_value}   ${lower_value}"
  echo -e "$1:\t${average}\t${max}\t${min}" >> ${output_file2}
  echo -ne "$field\t"
  awk 'NR!=1{if($'$num'<$upper_value||$'$num'>$lower_value){printf $'$num'"\t"}else{printf "\033[31m"$'$num'"\033[0m""\t"}}'  ${output_file1}
  echo ""
  
}


#脚本主入口
#屏幕格式化输出
echo -e "当前时间为:【\033[32m${current_time}\033[0m】,【\033[32m${one_mins_later}\033[0m】将统计vmstat命令输出的各项指标..."
#文件中打印首行
vmstat |awk 'NR==2{print}' > ${output_file1}
#当前时间如果等于预设的时间,则退出,进行数据的计算,否则,继续收集数据。
while [ "`date '+%Y-%m-%d %H:%M:%S'`" != "${one_mins_later}" ];do
  vmstat_out
done

echo -e "\033[41;36m超出上下限范围分布\033[0m"
for i in `seq 1 17`
do
  field=`awk 'NR==1{print $'$i'}' ${output_file1}`
  average_max_min $field $i
done
echo -e "\033[41;36m下列数据依次为平均值、最大值、最小值!!!\033[0m"
cat ${output_file2}
后续改进点:格式化输出(屏幕打印时关键数据加上高亮);”平均值“、“最大值”、“最小值”与数据需一一对应
----------------------------------------------------------
实现2:

案例6: shell实现cp -r

需求:用shell编一个文件夹拷贝工具,不使用cp 的-r选项(可以使用cp),并对文
件夹中的每个文件使用进度条(打印’+'号即可)显示传输进度。

比较low:
#!/bin/bash

#假设a中全是文件,b中无任何文件或者目录,进而实现cp -r a b
# .
# ├── a
# │   ├── file1
# │   ├── file2
# │   └── file3
# └── b
#获取命令行参数
src=`basename $1`
dest=`basename $2`
flag=false
#遍历源目录,并进行传输
mkdir "$2/${src}"
for element in `ls $1`;do
  src_file_size=`ls -l "$1/${element}"|awk '{print $5}'` 
  echo "开始传输${element},数据总大小为:${src_file_size} Bytes,目标路径为$2/${src}/${element}"
  cp "$1/${element}" "$2/${src}/${element}"
  while true;do
    if [ `ls -l "$2/${src}/${element}"|awk '{print $5}'` == ${src_file_size} ];then
      #dest_file_size=`ls -l "$2/${src}/${element}"|awk '{print $5}'`
      #echo "传输进度:`echo ${dest_file_size}/${src_file_size}|bc`"
      echo "传输完成..."
      break
    fi
  done
done
后续改进需要考虑的点:
1.	b目录不存在,需要进行判断。
2.	a中也存在目录,需要递归将a目录里面的文件进行拷贝;a为文件时,需要考虑。
3.	命令行传参的判断,判断命令行参数数目个数。
4.	拷贝时进度条的实现。

案列7:scp

#!/bin/bash
servers=("126" "127" "128" "129")
for v in ${servers[@]}; do
	scp $1 192.168.12.$v:/root/ 
done
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值