Bo2SS

Bo2SS

7 Shell编程基础

高级语言、脚本语言、解释型语言:xxx.sh,一般基于 bash

课程内容#

第一个 Shell 脚本#

#!/bin/bash
#注释
echo "Hello"
  • 第一行 #! 指定解释器,只在第一行才有效
  • 注释:"#"

变量#

a=123
a=hello
a=`pwd`
PATH=${PATH}:path  # 变量后接字符串,可以直接拼接字符串
# 【注意】":a"有特殊含义,会指到当前路径
  • 不需要定义变量类型【弱类型语言】
    • 如 a=123 可以是字符串,也可以是整数
  • "" 有特殊含义
    • img
    • 可用双引号包住 a,如 a=$a:"a" 或 a=$a"",得到 a=123

特殊变量#

位置变量

  • image-20201218170251055

结果:

  • image-20201215174953312
  • $n:如果 n>9,需要用大括号括起来

  • $@ 和 $* 的区别在于:传入参数分别被双引号包围、且 $ 变量也被双引号包围时,"$@" 会将所有的参数分开【一般情况】,而 "$*" 会将所有的参数作为一个整体

  • $#:不算 $0

状态变量

  • $?:【上一条】指令执行结果,0—— 成功,非 0—— 不成功
    • 图片
    • 便于脚本自动判断指令成功与否
  • $$、$!:当前进程、最后运行的后台进程的 PID,一般用于自动化测试、多脚本交互场景

输入输出#

  • 输入:read
    • 图片
    • -p:显示友好提示,需在 bash 下使用
    • -s:静默模式
    • -t:输入等待时长,超时结束 (单位:s)
  • 输出:echo
    • -e:开启转义
  • 输出:printf
    • 和 C 语言的 printf 非常像!
    • 图片
    • [PS] ! 和 \n 放一起有特殊含义,需要分开
      • bash 下需要分开
      • zsh 下可以分开,或用 \ 转义
      • 一般对于特殊符号—— 菜鸟教程,需要警觉!

函数#

  • 图片
  • 没有形参

  • 定义:写法很多,function、()、{} 组合搭配,第 3 种更类似 C 语言写法

  • 调用:函数名 参数...

    • 图片
    • 加 function 方便阅读
  • ❗【注意】shell 中函数 return 的返回值有限制,范围是 0-255,溢出会循环换算

流程控制#

do——done、if——then——fi、case——esac

【重点】TEST 表达式⭐#

  • 可判断类型:字符串、整型、文件
  • ❗ 【注意】条件为真时,返回 0,否则返回非 0
    • Linux 中命令的返回值也是如此,0 才代表成功
  • [PS]
    • STRING1 = STRING2 也可以用 == 【推荐后者,两个中括号 [[]] 支持】
    • -G FILE:文件存在并且被有效组 ID 拥有
      • 如果组被解散了,则组控制的文件的组 ID 就是无效的
    • 具体可查阅 man 手册:man test

分支结构#

if

case

  • 图片
  • 分号;;不能没有!相当于 break,加了 break 也要有

  • 默认情况可用 *)

  • case 用的较少,一般用来做菜单,比 if 更美观

循环结构#

for

  • 利用 seq 生成序列

  • 图片
  • 利用 ls 的匹配规则

  • 图片
  • for 的两种形式

  • 图片
  • 双小括号 (()) 中的内容只要符合 C 语言运算规则即可,变量可以不使用变量前缀 $,可以写 i++,平常不可以用 ++

while

  • 图片
  • 同样适用 test 表达式

  • 初始化 num 变量,否则

    • 第一次 echo $num 时,$num 是空值,表现为空行
    • 当遇到后面的 + 1 时,系统判定它为整数类型,才当做整数用

until

  • 图片
  • 与 while 唯一的区别在于:until 写的是停止条件,while 写的是循环条件

数组#

  • 图片
  • 数组赋值【方式①】和调用

  • 图片
  • 【常用的数组操作】还可以输出数组元素的下标,见后

  • 图片
  • 声明数组:declare -a num,方便阅读,不声明也可以 [弱类型语言]

  • 赋值【方式②、③】

    • num[2]=10 num[5]=7 num[100]=3.2.4
    • num=(1 a b 10)
  • 数组元素不一定要连续赋值,且可以为任意类型

    • 【常用的数组操作】加!:输出所有数组元素对应的下标,可以看出不是连续的

【其它数组操作】

  • 图片
  • +=:追加

  • unset:删除数组,或元素 [通过下标删除]

  • [PS] 赋值方式③对多个空格也只作一个分隔符

应用

  • 图片
  • 可以用来存储文件名列表

  • 【注意】赋值方式③给数组赋值是以空格作为分隔符,所以如果文件名里有空格,需要特殊处理

  • 【PS】素数筛、线性筛

随堂练习#

1~100 的偶数和#

  • 图片
  • $[ ] 可用来做整数运算

  • seq 效率稍低

暴力求素数#

  • 图片
  • 函数的 return 值

    • 通过 $? 获得,在调用函数后 echo $? 即可,但是 return 值有范围限制 0~255!
    • 通过命令替换符 `` 取到
  • 注意对于循环变量 i 的冲突问题:定义局部变量

  • 🆒调试程序

    • 习惯:适当的 echo 输出
    • 全局调试:bash -x *.sh
    • 局部调试:set -x [调试代码区域] set +x

素数筛#

  • img
  • 方式一方便操作素数,且输出时可减少判断

  • 方式二还可以操作合数

【暴力法、素数筛 2 种方法效果比较】求 2~10000 的素数和

img

  • 9.prime.sh 暴力法 —— 10.prime.sh 素数筛

附加知识点#

  • .sh 脚本可以直接 bash 或 source 执行,如果要使用./ 需要有可执行权限
  • set -x 可以开启 shell 调试
  • Shell 命令替换:将命令的输出结果赋值给变量——C 语言中文网
    • $() 支持嵌套,反引号 `` 不行
    • $() 仅在 Bash 中有效 [似乎 zsh、sh 都支持],而反引号 `` 可在多种 Shell 中使用
  • 双小括号 (()) 中的内容
    • 只要符合 C 语言运算规则即可
    • 变量可以不使用变量前缀 $
    • 可以写 i++,平常不可以用 ++
  • ⭐在 Shell 中,变量还未定义时,其值为空,echo 输出表现为空行
  • ⭐空格问题【严格】
    • 赋值语句:= 左右不能有空格
    • TEST 表达式相关:[[]] 两端必须有空格
  • 对于变量名 i,如果想将 $i 与_i 拼接,用 $i_i,会去找变量 i_i,所以要用 ${i}_i

Tips#

  • 写 Shell 脚本
    • 不要太考虑性能,单纯做数学计算效率低
    • 为的是快速解决一个问题,用来规划所有任务的流程
    • 做操作前记得加【备份】操作
    • 一般是让系统做事情,难于操作特定的程序做事情
      • 程序一般有自己的参数设置,但不具有普适性
  • API 一般指服务
  • Shell 风格指南——Google 开源项目风格指南 ——Shell 编程规范
  • Shell 脚本多行注释和单行注释的方法—— 博客
:<<!
[要注释的代码]
!
  • 可以了解let—— 菜鸟教程,方便的语法

课程速记#

  • 图片
  • 图片
  • 图片
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。