shell学习总结

关于shell

  • 运维人员会写一些shell
  • 管理集群/开发效率提高需要shell
  • shell是一个命令解释器,接收用户的命令,然后调用操作系统内核
  • 计算机
    • 硬件-linux内核-shell-外层应用程序
    • shell是翻译官,是桥梁
  • shell可以一行行命令的执行,也可以一堆命令作为脚本来执行
    • 因此,其可以当做一种编程语言
  • 红帽系用的默认是bash,ubuntu用的是dash

第一个shell脚本

  • 一般后缀是.sh (约定俗称)
  • 第一句 #!/bin/sh 指定解析器
  • 脚本执行方式
    • bash或sh +脚本的绝对or相对路径 (一般不用)
    • 直接输入脚本路径直接运行,需要x权限(chmod +x 脚本路径) ./hello.sh
    • source or . +脚本路径(用的少)
      • source就是一种shell内嵌, . 也差不多, 就是一种shell命令
    • 前面两种是在当前的bash shell中起了一个子shell,不影响当前环境
    • source是用的是当前shell
      • 要考虑到作用范围, 父子之前是否需要交互
      • 有时候改一些profile,需要source一下,就是这样的

shell中的变量

  • 临时在shell编程中保存的信息
  • 分类
    • 系统or用户
      • 系统一般以$开头
      • echo $HOME 看某个变量含义
      • env 看所有系统定义的全局变量
      • set 看所有变量
    • 全局(当前shell)or局部(子shell)
  • 自定义变量
    • 定义变量 变量名=变量值 =前后不能有空格
      • 空格是命令的标识
    • 撤销变量 unset 变量名
    • 声明静态变量 readonly变量, 不能unset,不能改
      • readonly是静态变量,不可修改撤销
    • 直接定义的变量是局部变量
      • export 变量名 设置为全局变量
    • 如果有空格,需要引号包括
  • 父shell定义的全局变量
    • 子shell可以看到
    • 子shell可以修改,但只限于自己这个环境修改有效,对其他环境修改失败,即使你export,也不行
    • 只能在父shell中修改
    • 其次,子shell中定义的全局变量,在子shell exit后会消失
  • 自定义变量值默认是字符串
    • 运算需要shell中的运算符
  • 特殊变量
    • 输入参数
    • $n表示1-9个参数,如果十以上,用大括号包含,0代表当前脚本名称
    • 在字符串中,单引号会将$认为是字符串,而双引号会认为是变量
    • $#获取输入参数个数,一般用于循环
    • $*将所有参数做成一个整体,
    • $@也是获取所有参数,但是分开对待,类似于数组
      • 如果没有引号包括,二者都是一样的,都是数组
    • $?最后一次执行命令的返回状态 0 为正常执行, 其他是非零,有报错含义
      • 随便什么命令

运算符

  • $((运算式))
  • $[运算式]

条件判断

  • test 条件 (条件中的等于号一定要空格,不然就一定为0,判断用空格,赋值不用)
    • 正确返回0
    • 错误返回1
  • 简写: 直接[ condition ] (前后一定要空格)
    • 这里可以用双小括号,就方便很多了
  • 主要一定要空格,连在一起,就会认为是一个值,就会出问题
  • !=为不等于
  • 常用判断条件
    • 整数之间
      • -eq 等于 equal
      • -ne不等于 notequal
      • -lt小于 less than
      • -le小于等于 less equal
      • -gt大于 greater than
      • -ge大于等于 greater equal
    • 文件权限
      • -r 可读
      • -w 可写
      • -x 可执行
    • 文件类型
      • -e 文件存在
      • -f 文件类型
      • -d文件存在且是目录
  • 多条件: && ||
    • [condition] && xxx1 || xxx2 (这里就是if-else)

流程控制

  • if [ condition ]
    then
    	xxx
    elif [ condition ]
    then
    	xxx
    fi
    
    可以用;代表换行
    
  • 为了防止输入参数为空报错

    • [ $1 = “xxx”]
    • 改为 [ "$1"s = "xxx"s ] 拼接一个字符串,保证一定非空
  • case语句

    • case $变量名 in
      "值1")
      	xxx
      ;;
      "值2")
      	xxxx
      ;;
      *)
      	xxx
      ;;
      esac
      

for循环

  • for ((初始值;循环控制条件;条件变化))
    do
    	程序
    done
    
  • image-20220508151207007

  • 双小括号里可以直接数学运算

  • for 变量 in 值1 值2 值3
    do
    	程序
    done
    
  • image-20220508151707086

  • {}表示一段序列

    • {1…100} 从1-100的序列

while 循环

  • while [condition]
    do
    	程序
    done
    

read读取控制台输入

  • read (选项) (参数)
    -p 指定读取值时的提示符
    -t 等待时间
    
    
  • image-20220508153705225

函数

  • 一段代码的集合

  • 脚本本质上也是函数

    • 脚本没有返回值
    • 脚本的调用过程太笨重
  • 系统函数

    • 使用系统函数 $(系统函数)

    • image-20220508154658128

    • date 当前时间

      • +%s 时间戳
    • basename 路径

      • 获得最后一个斜杠后面的文件名称
      • 参数 suffix 例如 basename xxx.txt .txt 删除后缀
    • dirname

      • 获得目录路径,去除文件名

      • 获得当前绝对路径

        • cd $(dirname $0)
          pwd
          进入当前文件的目录,然后pwd打印目录信息
          
  • 自定义函数

    • [function]funname[()]
      {
      	action;
      	[return int;]
      }
      
    • 这里的return只能在0-255之间,int就很蠢

    • 所以实际接收

    • image-20220508161601889

    • 此时当结果超过255,则不正确

    • 所以return其实不好用

    • 可以这么来

    • image-20220508161958874

    • 实际上$()获得的是函数中最后一行命令的执行结果

      • 这句话是老师说,但我测试之后感觉不对,image-20220508162458893如此操作,会有两个返回值
      • 感觉echo在函数中,就是返回的意思,而非打印

归档文件 综合应用联系

  • 实现一个脚本,每天对指定目录进行归档备份

    • 输入一个目录名称
    • 将目录下的所有文件按天归档保存,将归档日期附加在文件名上,放在/root/archive下
  • 脚本内容分析

    • # 首先判断输入参数个数是否为1
      
      if [ $# != 1 ]
      then
              echo "参数个数错误,只需要1个参数"
              exit
      fi
      
      # 从参数中获取目录名称
      if [ -d $1 ]
      then
              echo
      else
              echo
              echo "目录不存在"
              echo
              exit
      fi
      
      # 转换为绝对路径
      DIR_NAME=$(basename $1)
      DIR_PATH=$(cd $(dirname $1);pwd)
      
      # 获取当前日期
      DATE=$(date +%y%m%d%H%M)
      
      # 定义生成的归档文件名称
      FILE=archive_${DIR_NAME}_$DATE.tar.gz
      DEST=/root/archive/$FILE
      
      # 开始归档目录文件
      echo "开始归档..."
      echo
      
      # c归档 z压缩 f可视化 生成文件名称 归档目录名称
      tar -czf $DEST $DIR_PATH/$DIR_NAME
      
      # 是否执行成功
      if [ $? -eq 0 ]
      then
              echo
              echo "归档成功!"
              echo "归档文件为:$DEST"
              echo
      else
              echo "归档出现问题"
              echo
      fi
      
      exit
      
    • exit为退出

    • tar实际上就是备份,归档

  • 定时任务

    • crontab -l 查看当前定时任务

    • crontab -e修改定时任务

    • # 分 时 日 周 月 脚本路径 参数  (定时执行)
      0 2 * * *  /root/scripts/daily_archive.sh /root/scripts
      

关于echo

  • 明显,在函数中其作用为函数的返回值,可以多次返回,但和return这种是不一样的
  • 而在最外层命令执行时,它会打印
  • 因此,可以这样理解,实际上,它就是将值往外一层返回
  • bash为一层,函数再往里一层,只有到bash外,才算打印
    • 这样就可以理解的通了,虽然这样理解可能不对,但
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值