AI智能
改变未来

7.shell脚本基础


shell脚本

1.脚本介绍

1.1 shell脚本基础

  1. shell脚本:
    包含一些命令或声明,并符合一定格式的文本文件
  2. 格式要求:首行shebang机制
    #!/bin/bash
    #!/usr/bin/python
    #!/usr/bin/perl
  3. shell脚本的用途有:
    自动化常用命令
    执行系统管理和故障排除
    创建简单的应用程序
    处理文本或文件

1.2 创建shell脚本

  1. 第一步:使用文本编辑器来创建文件文件
    第一行必须包括shell声明序列:#!
    #!/bin/bash
    添加注注释:注释以#开头
  2. 第二步:运行脚本
    给予执行权限,在命令行指定脚本的绝对或相对路径
    直接运行解释器,将脚本作为解释器程序的参数运行(没有执行权限也可以)
eg:vim   /data/bash.shchomd +x  /data/bash.shbahs.sh 可用看做外部命令(不在PATH路径下找不到文件因此不能执行)/data/bash/sh   绝对路径执行cd /data/ 相对路径执行./bash.shcat  hello.sh | bashcat /var/www/html/hello.sh(192.168.20.128)curl http://192.168.20.128/hello.sh(远程运行)

1.3 脚本规范

  1. 第一行一般为调用使用的语言

  2. 程序名,避免更改文件名为无法找到正确的文件

  3. 版本号

  4. 更改后的时间

  5. 作用相关信息

  6. 该程序的作用,及注意事项

  7. 最后是各版本的更新简要说明

    #!/bin/bash#--------------------------------#filename : hello.sh#revision: 1.1#date: 2019/10/5#autor: wang#email: [email protected]#website: www.magedu.com#description: This is the first script#----------------------------------#copyright: 2019 wang#license: GPLecho  \"hello world \"

1.4 脚本的基本结构

1.脚本的基本结构
#!shebang
configuration_variables
function_definitions
main_code

1.5脚本调试

  1. 检查脚本中的语法错误:
    bash -n /path/to/some_script
  2. 调试执行
    bash -x /path/to/some_script

2.变量

2.1 变量

  1. 变量:命令的内存空间
    数据存储方式:
    字符:
    数值:整型,浮点型
  2. 变量:变量类型
    作用:
    1.数据存储格式
    2.参与的运算
    3.表示的数据范围
    类型:
    字符
    数值:整型、浮点型
  3. 强类型:变量不经过强制转化,它永远是这个数据类型,不允许隐式的类型转换。一般定义变量是时
    必须符合类型要求,调用未声明变量会产生错误
    如 Java,c#
  4. 弱类型:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动
    进行隐式类型转换;变量无须事先定义可直接调用
    如:bash不支持浮点数,PHP
  5. 变量命令法则
    不能使用程序中的保留字: 例如if,for
    只能使用数字、字母及下划线,且不能以数字开头
    见名知义
    同一命名规则:驼峰命名法

2.2 bash中变量的种类

根据变量的生效范围等标准划分下面变量类型:

1. 局部变量:生效范围为当前shell进程;对当前shell之外的其他shell进程。包括当前shell的子shell进程均无效2. 环境(全局)变量:生效范围为当前shell进程及其子进程3. 本地变量:生效范围为当前shell进程中某代码片段,通常指函数4. 位置变量:$1,$2,$3....来表示,用于让脚本在代码中国调用通过命令行传递给它的参数5. 特殊变量:$?,$0,$@,$#,$$

2.3 局部变量:

  1. 变量赋值:name=‘value’
  2. 可以使用引用value:
    可以是直接字符串:name= “root”
    变量引用:name= \”USER\”命令引用:name=‘command‘name=USER\”命令引用:name=`command` name=USER\”命令引用:name=‘command‘name=(command)
  3. 变量引用:$(name) name\”\”:弱引用,其中的变量引用会被替换为变量值′′:强引用,其中的变量引用不会被替换为变量值,而保持原字符串echo\”name\”\”: 弱引用,其中的变量引用会被替换为变量值\’\’ : 强引用,其中的变量引用不会被替换为变量值,而保持原字符串echo \”name\”\”:弱引用,其中的变量引用会被替换为变量值′′:强引用,其中的变量引用不会被替换为变量值,而保持原字符串echo\”name\” 保留格式
    echo $name 不保留格式
  4. 显示已定义的所有变量:set
  5. 删除变量:unset name

2.4环境变量

  1. 变量声明、赋值:
    export name=VALUE
    declare -x name=VALUE

  2. 变量引用: $name , $(name)

  3. 显示所有环境变量:
    env
    printenv
    export
    declare -x

  4. 删除变量:
    unset name

  5. bash内建的环境变量:


    PATH
    SHELL
    USER
    UID
    HOME
    PWD
    SHLVL
    LANG
    HOSTNAME
    HISTSIZE

2.5 只读和位置变量

  1. 只读变量:只能声明,但不能修改和删除
    声明只读变量:
    readonly name
    declare name
    查看只读变量:
    readonly -p
  2. 位置变量:在脚本代码中调用通过命令行传递给脚本的参数
    $1,$2,…:对应第1、2参数,shift[n[换位置
    $0 :命令本身
    $*:传递给脚本的所有参数,全部参数合为一个字符串
    $@:传递给脚本的所有参数,每个参数为独立字符串
    $#:传递给脚本的参数的个数
    @@@*只在被双引号包起来的时候才会有差异
    set –清空所有位置变量
eg:(umask 666; touch /data/f1) 一次性任务,开启子shell,执行后结束,不影响当前环境(name=wang;echo  $name)echo $name{name=mage;echo $name;}   {}影响当前环境echo $namex=1;echo \"pid=$$\";(echo\"subpid=$$\";echo \"subx=$x\"; x=2;echo \"subx2=$x\");echo x=$x

2.6 退出状态:

  1. 进程使用退出状态来报告成功或失败
    0代表成功,1-255代表失败
    $?变量保存最近的命令退出状态
  2. 例如:
    ping -c1 -W1hostdowm &> /dev/null
    ehco $?
  3. bash自定义退出状态码
    exit
    :自定义退出状态码
    注意:脚本中一旦遇到exit命令,脚本会 立即终止;终止退出状态取决于exit命令后面的数字
    注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

3. 运算

3.1 算法运算:

  1. bash中的算术运算:help let

    +,-,*,/,%取模(取余),**(乘方)实现算法运算:let var=算术表达式var=$[算术表达式]var=$((算术表达式))var=$(expr arg1 and arg3...)declare -i var=数值echo ‘算术表达式’ | bc
  2. 乘法符号有些场景中需要转义,如*

  3. bash有内建的随机数生成器:$RANDOM (0-32767)

    echo $[$RANDOM%50]

    :0-49之间随机数

3.2 赋值

  1. 增强型赋值:
    +=,-=,*=,/= ,%=
  2. let varOPERvalue
    例如:let count+3= 自加3后自赋值
  3. 自增,自减:
    let var+=1
    let var++
    let var-=1
    let var–

3.3 逻辑运算

  1. 非:!
    !1=0
    !0=1
  2. 短路运算
    短路与:&&
    第一个为0,结果必为0
    第一个为1,第二个必须参与运算
    短路或: ||
    第一个为1,结果必为1
    第一个为0,第二个必须参与运算
  3. 异或:^
    异或的两个值,相同为假,不同为真
    0^1=1
    0^0=0
    1^0=1
    1^1=0
    a=$[a^b];b=$[a^b];a=$[a^b];echo $a $b

    互换值

  4. true,false
    1,0
  5. 与:&
    1&1=1
    1&0=1
    0&1=0
    0&0=0
  6. 或:|
    1|1=1
    1|0=1
    0|1=1
    0|0=0

4.条件测试

4.1 条件测试

  1. 判断某需求是否满足,需要由测试机制来实现
    专用的测试表达式需要由测试命令辅助完成测试过程
  2. 评估布尔声明,以便用在条件性执行中
    若真,则返回0
    若假,则返回1
  3. 测试命令:
    test EXPRESSION
    [EXPRESSION]
    注意:EXPRESSION前后必须有空白字符窜

4.2 bash的字符串测试

-eq	是否等于-ne	是否不等于-gt	是否大于-lt	是否小于-le	是否等于或小于-ge	是否大于或等于=	比较字符串内容是否相同!=	比较字符串内容是否不同=~  左侧字符串是否能够被右侧的pattern所匹配-z“string”字符串是否为空,空为真,不空位假-n  \"string\" 字符串是否不空,不空为真,空位假注意:用于字符串比较时的用到的操作数应该使用引号

4.3 条件性的执行操作符

  1. 根据退出状态而定,命令可以有条件地执行
    &&代表条件性的AND THEN
    ||代表条件性的OR ELSE

  2. 例如:

    grep -q no_such_user /etc/passwd || echo \'No such user\'NO shch userping -c1 -W2 station &> /dev/null && echo \"station1 is up \" || (echo \'station1 is unreachable\';exit 1)station1 is up

4.4 test命令

  1. 长格式的例子:
    test \"$A\" = \"$B\" && echo \"strings are equal\"

    test \"$A\" -eq \"$B\" && echo \"strings are equal\"
  2. 简要格式的例子:
    [ \"$A\" = \"$B\" ] && echo \"strings are equal\"

    [ \"$A\" -eq \"$B\" ] && echo \"strings are equal\"

4.5 bash的文件测试

  1. 存在性测试
    -a file : 同-e
    -e file :文件存在性测试,存在为真,否则为假
  2. 存在性及类别测试
-b  file: 是否存在且为块设备-c  file:  		字符设备文件-d file:		目录文件-f file:		普通文件-h file或 -L file:	符号链接文件-p file:		命令管道文件-S file:		套接字文件
  1. 文件权限测试:
    -r file:是否存在且可读
    -w file: 写
    -x file: 执行
  2. 文件特殊权限测试:
    -u file:是否存在且拥有suid权限
    -g file: sgid权限
    -k file: sticky权限
  3. 文件大小测试:
    -s file:是否存在非空
  4. 文件是否打开:
    -t fd:fd 文件描述是否在某终端已经打开
    -N file: 文件自从上一次被读取之后是否被修改过
    -O file:当前有效用户是否为文件属组
    -G file:当前有效用户是否为文件属组
  5. 双目测试
    file1 -ef file2 : file1 是否是file2 的硬链接
    file1 -nt file2:file1是否新于file2(Mtime)
    file1 -ot file2 : file1是否旧于file2

4.6 bash的组合测试条件

  1. 第一种方式:
    command1 && command2 并且
    command1 || command2 或者
    !command 非
    如 [[ -t file ] && [ [ -w file ]]
  2. 第二种方式:
    expression1 -a expression2 并且
    expression1 -o expression3
    !expression
    必须使用测试命令进行
  3. 示例:
    [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

4.6 使用read命令来接受输入

使用read 来把输入值分配给一个或多个shell变量

-p:   指定要显示的提示-s:   静默输入,一般用于密码-n N 指定输入的字符长度N-d  ‘字符’输入结束符-t N  timeout  为N秒read  从标准输入中读取值,给每个单词分配一个变量所有剩余单词都被分配给最后一个变量read -p \"enter a filename:\" FILE

ifconfig ens333 | grep -Eo\" \\>(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]\\.){3} ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\>\"

5.配置用户环境

5.1 防止扩展

  1. 反斜杠()会使随后的字符按原意解释
    $echo Your cost:$5.00
  2. 加引号来防止扩展
    单引号(’)防止所有扩展
    双引号(\”\”)也防止所有扩展,但是以下情况例外:
    $(美元符号) —— 变量扩展
    `(反引号) —— 命令替换
    (反斜线) —— 禁止单个字符扩展
    !(叹号) —— 历史命令替换

5.2 bash的配置文件

1)全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
2)个人配置:
~/.bash_profile
~~/.bashrc

5.3shell登录两者方式

  1. 交互式登录:
    直接通过终端输入账号密码登录
    使用“su – UserName ”切换的用户
    执行顺序:/etc/profile–> /etc/profile.d/
  2. 非交互式登录:
    su UserName
    图形界面下打开的终端
    执行脚本
    任何其他的bash示例
    执行顺序:~/.bashrc–>/etc/bashrc–>/etc/profile.d/*.sh

5.4修改配置文件生效

  1. 修改profile和bashrc文件后生效
    两种方法:
    重新启动shell进程
    .或source
    例如: . ~/.bashrc

5.5 profile 类

  1. 按照功能划分,存在两类:
    profile类和bashrc类
  2. profile类:为交互式登录的shell提供配置
    全局:/etc/profile,/etc/profile.d/*.sh
    个人:~/.bash_profile
    功能:
    用于定义环境变量
    运行命令或脚本
  3. bash退出任务
    1)保存在~./.bash_logout文件中(用户)
    2)在退出登录shell时运行
    3)用于创建自动备份,清除临时文件

5.6$-变量

  1. h: hashall,打开这个选项后,shell会将命令所在的路径hash下来,避免每次都要查询。通过set+h将h选项关闭
  2. i: interactive-comments,包含这个选项说明当前的shell是一个交互式的shell。所谓的交互式shell,在脚本中,i选项是关闭的
  3. m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等。
  4. 4)B:braceexpand,大括号扩展
  5. H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,\”!n\”

5.7 bash如何展开命令行

  1. 把命令行分成单个命令词
  2. 展开别名
  3. 展开大括号的声明({})
  4. 展开波浪符声明(~)
  5. 命令替换$()和 “)
  6. 再次把命令分成命令词
  7. 展开文件通配(*、?、[abc]等)
  8. 准备 I/O重定向(<>)
  9. 运行命令
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 7.shell脚本基础