zoukankan      html  css  js  c++  java
  • shell脚本01(基础介绍)

    shell脚本01(基本介绍)

    1. shell基本介绍

    #1.shell介绍
    shell是一个命令解释器,主要用来接收用户的指令,进入驱动操作系统,或硬件
    #2.shell存在交互和非交互 ( 创建100个用户 )
    交互:登陆Linux、useradd、passwd   ( 重复100次 )
    非交互: 创建100个用户的操作写入至一个文件中,然后去执行。( 全程不需要用户参与 )
    #3.什么是shell脚本
    1) 将系统命令堆积在一起,顺序执行(简称: 系统命令堆积)
    2) 特定的格式 + 特定的语法 + 系统的命令 = 文件 ( Shell脚本文件)。
    
    #!/usr/bin/bash							#特定的格式
    
    for i in {1..100}						#特定的语法
    do
    	useradd oldboy{1..10}			     #系统的命令
    done
    

    2.shell的书写方式

    • 1.Shell脚本名称必须要有含义 a.sh、b.sh、建议命名的方式最好在30个字节以内解决。 check_memory.sh

    • 2.shell脚本的格式 (建议在文件的首行添加 #!/bin/bash、#!/usr/bin/bash )

    • 3.shell脚本建议添加一些个注释

      #!/usr/bin/bash   #申明系统在执行时使用bash解释器翻译该文件的内容
      # Author: tony、123456789@qq.com
      # Create Time 2021/05/03
      # Script Description: 这个脚本是用来检查系统内存使用情况。
      
      # 所有的注释可以自动生成,可以研究一下vimrc
      

    3.shell执行方式

    添加 #!/bin/bash 的作用。

    • 1.不添加
      • 默认 ./运行时,系统会调bash来运行该脚本。
      • 缺点:如果我写的是python脚本,直接调用bash来运行则会报错。
    • 2.添加
      • ./运行脚本,默认会读取该文件第一行,来确定使用什么解释器运行。
    • 3.直接调用解释器运行 ( 无需在意文件首行指定的解释器 )
      • python check_shell.sh
      • bash check_shell.sh #日常使用最多( 我确定他是一个shell脚本,所以我会选择直接使用bash解释器翻译该脚本文件 )

    4.shell变量

    • 1.什么是变量

    • 变量其实是Shell传递数据的一种方式。以一个固定的字符串去表示一个不固定的值。便于后续的复用,以及维护。

    • 2.变量的命名规范 ( 熟悉 )

      • 变量命令规范:大小写、下划线拼接变量名、尽量字母开头。( 变量最好有含义,如果没有,容易忘记这个变量是做什么的。 )

      • 变量如何定义: 变量名=变量值,等号是赋值。 a=123 a变量 123值

      • 变量定义参考:

        ip=10.0.0.1 #小写,会容易与系统的命令冲突
        ip1=10.0.0.1 #小写+数字
        Hostname_Ip=10.0.0.1 #驼峰式命名 大写开头小写结束_大写开头_小写结束
        Hostname_IP=10.0.0.1 #开头大写,_后面全大写

    ”变量名称“ 首字母大写的原因是为了避免与系统的命令产生冲突。

    3.变量定义的几种方式 ( 使用61服务器 )

    • 1.用户自定义变量,自己随意定义变量。

    • [root@web01 ~]# var="hello world"       #定义变量 ( 等号两边没有空格 )
      [root@web01 ~]# echo $var                     #$变量名   ${变量名}
      hello world
      #使用$变量名  ${变量名} 区别?
      [root@web01 ~]# echo $var_log
      [root@web01 ~]# echo ${var}_loghello world_log  # 单引号和双引号的区别?
      [root@web01 ~]# var2=Iphone
      [root@web01 ~]# echo "$var2 is good"        #双引号会解析中的$符号Iphone is good
      [root@web01 ~]# echo '$var2 is good'        #写什么就是什么$var2 is good
      #什么时候使用 单引号和双引号:    
      如果你输出的结果中包含变量名需要解析,则建议使用双引号。   
      如果你输出的结果仅仅只是一个字符串,但里面存在特殊字符,那么你可以选择使用单引号。
      
    • 2.系统环境变量,保存的是和系统操作环境相关的,所有用户都可以调用。

    • #系统已经定义好了一些个变量,供我们使用。(所有的用户都可以使用)
      
    [root@oldboy ~]# cat check_env.sh 
    #!/bin/bash
    echo "用户的家目录:$HOME"
    echo "当前用户的主机名:$HOSTNAME"
    echo "当前所在目录:$PWD"
    echo "当前ssh连接:$SSH_CONNECTION"
    
    [root@oldboy ~]# cat get_system_info.sh 
    #!/bin/bash
    
    if [ $UID -ne 0 ]
    then
    echo "$USER没有权限执行该脚本!!"
    exit
    fi
      echo "系统状态指标获取完毕!!!"
    
    

    3.位置参数变量,向脚本进行传递参数的,变量名不能自定义,变量作用也是固定的。

    [root@oldboy ~]# cat variables.sh 
    #!/bin/bash
    
    echo "#当前shell脚本的文件名:$0"
    
    echo "#第一个shell脚本位置参数:$1"
    
    echo "#第二个shell脚本位置参数:$2"
    
    echo "#第三个shell脚本位置参数:$3"
    
    echo "#所有传递的位置参数是:$*"
    
    echo "#所有传递的位置参数是:$@"
    
    echo "#总共传递的参数个数是:$#"
    
    echo "#当前程序运行的pid是:$$"
    
    echo "#上一个命令执行的返回结果:$?"
    

    需求1:通过位置变量创建 Linux 系统账户及密码,执行 var1.sh username password

    [root@oldboy ~]# cat create_user_1.sh 
    #!/bin/bash
    #1.添加用户
    useradd $1
    
    #2.为用户设定密码
    
    echo "$2" | passwd --stdin $1
    

    需求2:通过位置变量创建 Linux 系统账户及密码,执行 var1.sh username password,控制最多传递两个参数。【这个脚本仅root能执行,其他普通用户无法执行创建用户脚本。】

    [root@oldboy ~]# cat create_user_2.sh 
    #!/bin/bash
    
    
    
    #判断他是什么用户身份在执行这个脚本
    
    if [ $UID -ne 0 ]
    then
    echo "$USER 用户没有权限执行,请切到root用户在执行"
    exit
    fi
    
    #判断用户传递的参数是否满足2个
    
    if [ $# -ne 2 ]
    then
         echo "please input parameters [ username && password ]"
         exit
    fi
    
    # 添加用户
    
    useradd $1
    
    
    #为用户创建密码
    
    echo "$2" | passwd --stdin $1
    
    

    4.变量赋值的方式read (交互式传递变量)

    [root@oldboy ~]# cat read-1.sh 
    #!/bin/bash
    read -p "Login: " acc
    
    read -p "passwd: " pw
    
    echo "login:$acc      passwd:$pw"
    #################################################################################
    [root@oldboy ~]# cat read-1.1.sh
    #!/bin/bash
    
    #-s 不回显,就是不显示输入的内容
    #-n 指定字符个数
    #-t 超时时间
    
    read -p "Login:" acc
    read -s -t10 -n6 -p "passwd:" pw
    
    echo "login:$acc    passwd:$pw"
    
    

    需求1:使用read模拟Linux登陆页面

    [root@oldboy ~]# cat read-2.sh 
    #!/bin/bash
    hostnamectl | awk -F ':' '/System/ {print $2}'
    
    echo "Kernel $(uname -r) an $(uname -m)"
    echo ""
    
    read -p "$(hostname) login:" acc
    
    read -s -p "Passwd:" pw
    echo ""
    echo "Login:$acc    passwd: $pw"
    

    需求2:使用 read编写一个备份脚本,需要用户传递2个参数,源和目标。

    [root@oldboy ~]# cat read-3.sh 
    #!/bin/bash
    
    read -p "你要备份的文件或目录路径:" src
    
    read -p "你要备份到那个目录下存储:" dest
    
    read -p "你确定要将 $src 备份到 $dest 吗?[ y | n ]" action
    
    
    #判断用户输入的是y还是n 则进行备份,n则提示没有备份
    if [ $action == "y" ]
    echo "---------------------备份开始----------------------"
    
    cp -rp $src $dest
    
    sleep 3
    
    
    echo "----------------------备份结束---------------------"
    
    else
    
    echo "----------------------备份退出---------------------"
    exit
    fi
    

    需求3:使用 read编写一个探测主机存活脚本,需要用户传递测试的IP地址。 [并没有说使用传参,而是让其使用read的方式]

    [root@oldboy ~]# cat read-4.sh 
    #!/bin/bash
    read -p "请输入你要探测的主机IP地址:" IP
    
    ping -c2 $IP &>/dev/null
    
    if [ $? -eq 0 ]
      echo "$IP 存活"
    else
      echo "$IP 不存活"
    fi
    

    需求4:使用read编写一个修改系统主机名称脚本。【询问:是否修改,y修改、n退出脚本不修改】

    [root@oldlai ~]# cat read-5.sh 
    #!/bin/bash
    old_host=$(hostname)
    echo "当前系统的主机名称是:${old_host} "
    read -p "你想修改的主机名称是:" new_host
    
    read -p "你确定要将 ${old_host} 变更为 ${new_host} 名称吗?[ y | n ] " action 
    
    if [ $action == "y" ]
    then
         echo "---------------------------正在修改主机名称---------------------------"
         hostnamectl set-hostname ${new_host}
         sleep 1
         echo ""
         echo "----------------------------主机名称修改完毕---------------------------"
    fi
    
    

    5.变量的替换

    #和双##
    [root@oldboy ~]# url=www.sina.com.cn
    [root@oldboy ~]# url=www.sina.com.cn
    [root@oldboy ~]#  echo "${url}"
    www.sina.com.cn
    [root@oldboy ~]# echo ${url#*.}
    sina.com.cn
    [root@oldboy ~]# echo ${url#*.*.}
    com.cn
    [root@oldboy ~]# echo ${url##*.}
    cn
    # %和双%%
    [root@oldboy ~]# echo ${url%.*}
    www.sina.com
    [root@oldboy ~]# echo ${url%.*.*}
    www.sina
    [root@oldboy ~]# echo ${url%%.*}
    www
    # / 与 //
    [root@oldboy ~]# echo ${url}
    www.sina.com.cn
    [root@oldboy ~]# echo ${url/sina/SINA}
    www.SINA.com.cn
    [root@oldboy ~]# echo ${url//c/C}
    www.sina.Com.Cn
    

    1.希望把$PATH中的/bin全部都替换为 /BIN

    [root@web01 ~]# echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
    
    [root@web01 ~]# echo ${PATH//bin/BIN}
    /usr/local/sBIN:/usr/local/BIN:/usr/sBIN:/usr/BIN:/root/BIN
    
    需求2:变量string="Bigdata process is Hadoop, Hadoop is open source project",执行脚本后,打印输出string变量,并给出用户以下选项:
    1)、打印string长度
    2)、删除字符串中所有的Hadoop
    3)、替换第一个Hadoop为Linux
    4)、替换全部Hadoop为Linux
    用户输入数字1|2|3|4,可以执行对应项的功能,输入q|Q则退出交互模式
    [root@oldboy ~]# cat vars.sh 
    string="Bigdata process is Hadoop, Hadoop is open source project"
    echo "$string"
    cat <<EOF
    1)、打印string长度
    2)、删除字符串中所有的Hadoop
    3)、替换第一个Hadoop为Linux
    4)、替换全部Hadoop为Linux
    EOF
    
    read -p "请输入你想执行的操作 [ 1 | 2 | 3 | 4 | q ]" action
    
    if [ $action -eq 1 ] 
    then
    echo "string变量的长度:${#string}"
    fi
    
    if [ $action -eq 2 ]
    then 
    echo "${string//Hadoop/}"
    fi
    
    if [ $action -eq 3 ]
    then
    echo "${string/Hadoop/Linux}"
    fi
    
    
    if [ $action -eq 4 ]
    then
    echo "${string//Hadoop/Linux}"
    fi
    

    2.查看内存/当前使用状态,如果使用率超过80%则报警发邮件

    [root@oldboy ~]# cat check_memory.sh
    #!/bin/bash
    Mem_Use=$(free -m | awk '/^Mem/ {print $3/$2*100}')
    
    if [ ${Mem_Use%.*} -ge 80 ]
    then
    echo "内存已经超过所设定得阈值,请尽快处理,当前已使用内存为 ${Mem_Use}"
    else
    echo "内存当前状态良好,当前已使用内存为 ${Mem_Use%.*}%"
    fi
    [root@oldboy ~]# bash check_memory.sh
    内存当前状态良好,当前已使用内存为 15%
    

    6变量的运算

    • 1.什么是变量运算? 小学学习的 + - x /
    • 2.为什么要学习呢?
    • 3.shell使用什么方式来实现变量的运算呢?
      • 1.expr
      • 2.$(())
      • 3.$[]
      • 4.bc、awk 小数运算
      • % 余数如果为0,说明两者之间整除
    [root@oldboy ~]# num1=10
    [root@oldboy ~]# num2=20
    [root@oldboy ~]# expr $num1 + $num2
    30
    [root@oldboy ~]# echo $(( $num1 + $num2 ))
    30
    [root@oldboy ~]# echo $[ $num1 + $num2 ]
    30
    [root@oldboy ~]# echo $[ $num1 - $num2 ]
    -10
    [root@oldboy ~]# echo $[ $num1 * $num2 ]
    200
    [root@oldboy ~]# echo $[ $num1 / $num2 ]
    0
    

    1.根据系统的时间,打印今年和明年时间。

    [root@oldboy ~]# echo "This is $(date +%Y) year"
    This is 2021 year
    [root@oldboy ~]# echo "This is $(( $(date +%Y) +1 ))"
    This is 2022
    

    2.根据系统时间获取今年还剩下多少个星期,已经过了多少个星期。

    [root@oldboy ~]# cat vars-2.sh
    #!/bin/bash
    echo "今年已经过了 $(date +%j) days"
    
    echo "今年已经过去了 $(( $(date +%j) / 7 )) weeks"
    echo "距离新年孩剩下多少周 $(( ( 365 - $(date +%j) ) / 7 )) weeks"
    
    

    3.完成一个 "简单" 的计算机功能,通过read方式传入2个值【而不是传参的方式】,进行 加、减、乘、除:

    [root@oldboy ~]# cat vars-3.sh 
    #!/bin/bash
    read -p "请输入你要计算得第一个数字:" num1
    
    read -p "请输入你要计算得第二个数字:" num2
    
    echo "$num1 + $num2 = $(( $num1 + $num2))"
    echo "$num1 - $num2 = $(( $num1 - $num2))"
    echo "$num1 * $num2 = $(( $num1 * $num2))"
    echo "$num1 / $num2 = $(( $num1 / $num2))"
    
  • 相关阅读:
    ZOJ 3332 Strange Country II
    ZOJ 3331 Process the Tasks(双塔DP)
    ZOJ 3326 An Awful Problem(模拟)
    HDU 1796 How many integers can you find(容斥原理)
    HDU 4059 The Boss on Mars(容斥原理)
    HDU 4135 Co-prime(容斥原理)
    HDU 5677 ztr loves substring(回文串加多重背包)
    CodeForces 668B Little Artem and Dance
    CodeForces 667A Pouring Rain
    Java实现 LeetCode 764 最大加号标志(暴力递推)
  • 原文地址:https://www.cnblogs.com/lailaoban/p/14781201.html
Copyright © 2011-2022 走看看