shell脚本-基础
程序员文章站
2022-08-04 11:55:11
shell脚本 基础 编程基础 shell脚本说明 变量介绍 变量的作用: 数据暂存 参与运算 表示数据范围 强类型变量: 变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。 一般定义变量时必须指定类型、参与运算必须符合类型要求。 调用未声明变量会产生错误。 如 java,c 的变量 ......
shell脚本-基础
编程基础
程序是指令+ 数据 程序编程风格: 过程式:以指令为中心,数据服务于指令 对象式:以数据为中心,指令服务于数据 shell 程序提供了编程能力,解释执行。 计算运行二进制指令。 编译执行: 高级语言--> 编译器--> 目标代码 如java,C# 解释执行: 高级语言--> 解释器--> 机器代码 如shell, perl, python 编程逻辑处理方式: 顺序执行 循环执行 选择执行 shell 编程: 过程式、解释执行 编程语言的基本结构: 各种系统命令的组合 数据存储:变量、数组等 表达式: a + b等 语句:if的等
shell脚本说明
shell 脚本: 包含一些命令或声明,并符合一定格式的文本文件 shell 脚本的用途有: 自动化常用命令 执行系统管理和故障排除 创建简单的应用程序 处理文本或文件 格式要求: 首行shebang 机制 #!/bin/bash #!/usr/bin/python #!/usr/bin/perl .... #! 就是告诉系统,这个脚本文件需要使用指定的命令解释器来执行。 紧随 #!的是一个路径名,此路径指向用来解释此脚本的程序,它可以是shell,可以是程序设计语言,也可以是实用程序。 这个解释器从头( #!的下一行)开始执行整个脚本的命令,同时忽略注释。 shell脚本的创建和运行: 创建脚本: 使用文本编辑器vim等来创建文本。 第一行必须是shell声明序列#!,一般为#!/bin/bash。 其余行为执行的命令。 添加注释使用#,注释以#开头。 运行脚本: 给予执行权限,在命令行上指定脚本的绝对或相对路径 chmod +x FILE.sh /PATH/TO/FILE.sh 直接运行解释器,将脚本作为解释器程序的参数运行 source or . +脚本,一般不这么用,这样会对当前环境进行影响 bash + 脚本,就不会影响外部工作环境 脚本规范: 脚本代码开头约定 1 、第一行一般为调用使用的语言 2 、程序名,避免更改文件名为无法找到正确的文件 3 、版本号 4 、更改后的时间 5 、作者相关信息 6 、该程序的作用,及注意事项 7 、最后是各版本的更新简要说明 脚本开头的示例: #!/bin/bash #------------------------------------------------- #Filename: #Description: #Revision: #Date: #Author: #Email: #Phonenumb: #Copyright: #------------------------------------------------ 脚本结构: 解释器:#!/bin/shell,等 配置变量:自己定义的变量,A=123等 功能描述:以#开头来说明接下来执行语句的作用 执行命令:指令+参数,包括各种语句表达式等 脚本调试: 检测脚本中的语法错误 bash -n /PATH/TO/FILE.sh 调试执行 bash -x /PATH/TO/FILE.sh 脚本中默认不支持别名 尽可能用命令的绝对路径
变量介绍
变量的作用: 数据暂存 参与运算 表示数据范围 强类型变量: 变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。 一般定义变量时必须指定类型、参与运算必须符合类型要求。 调用未声明变量会产生错误。 如 java,c#的变量 弱类型变量: 语言的运行时会隐式做数据类型转换。 无须指定类型,默认均为字符型。 参与运算会自动进行隐式类型转换。 变量无须事先定义可直接调用 如bash,php的变量 变量的命名规则: 不能使程序中的保留字,如if、for等。 只能使用数字、字母及下划线,且不能以数字开头。 需见名知义。 统一命名规则,即驼峰命名法 bash中的变量种类 根据变量的生效范围作为标准 本地变量: 生效范围为当前shell进程。对当前shell之外的其它shell 进程,包括当前shell的子shell 进程均无效。 环境变量: 生效范围为当前shell进程及其子进程。 局部变量: 生效范围为当前shell进程中某代码片断( 通常指函数)。 位置变量: $1, $2, ...来表示,用于让脚本在脚本代码中通过调用命令行传递给它的参数,大于9的数,就应该加大括号:${10} 特殊变量: $?, $0, $*, $@, $#,$$ 本地变量 变量赋值: name=value 引用value: 直接字串: name=“root" 变量引用: name="$USER" 命令引用: name=` COMMAND `; name =$(COMMAND) 变量引用: ${name} $name " " : 弱引用,其中的变量引用会被替换为变量值 ' ': 强引用,其中的变量引用不会被替换为变量值,而保持原字符串 ${name[$i]} i是变量,name[$i]也是变量 ' ':最傻的那个 ;" ":中间傻 ; ` `:聪明 显示已定义的所有变量: set 删除变量: unset name 环境变量 变量声明和赋值: export name=VALUE declare -x name=VALUE 变量引用: $name, ${name},"$name"(尽量用带括和带双引号的) 显示所有环境变量: env printenv bash内建的环境变量 PATH,SHELL,USER,UID,HOME,PWD,SHLVL,LANG,MAIL,HOSTNAME,HISTSIZE,— 只读变量 只能声明,但不能修改和删除。 声明只读变量: readonly name declare -r name 先赋值再声明或者是声明赋值一起做,不然,声明过后就不能再赋值了 查看只读变量: readonly –p 位置变量 在脚本代码中调用通过命令行传递给脚本的参数 $1, $2, ... : 对应第1 、第2 等参数,是脚本后面跟着的参数,且9以后需要加大括号:${10} shift [n] 可以更换位置 $0: 命令本身 $*: 传递给脚本的所有参数,全部参数合为一个字符串 $@: 传递给脚本的所有参数,每个参数为独立字符串 $#: 传递给脚本的参数的个数 $@与$* 只在被双引号包起来的时候才会有差异 set - - 清空所有位置变量 涉及到位置参数,脚本前面放置这个 [ $# -lt 1 ] && echo "Usage:`basename $0` arg1... " && exit 10 转换变量类型 可以使用declare或者typeset来转换变量类型 [root@localhost ~]# a=1;b=2;c=a+b; [root@localhost ~]# echo $c a+b [root@localhost ~]# typeset -i a;typeset -i b;typeset -i c; [root@localhost ~]# a=1;b=2;c=a+b; [root@localhost ~]# echo $c
退出状态
进程使用退出状态来报告成功或失败 0 代表成功,1 -255 代表失败 $?变量保存最近的命令退出状态 示例: ping -c1 -W1 hostdown &> /dev/null echo $? bash 自定义退出状态码 exit [n]:自定义退出状态码 注意: 脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit 命令后面的数字 如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
算术运算
help let let arg [arg ...] 运算 +, -, *, /, % 取模(取余), ** (乘方) 注:乘法符号有些场景中需要转义 , 如* 增强型赋值: +=, -=, *=, /=, %= 自增和自减: let var+=1 let var++ let var-=1 let var-- 实现算术运算 let var= 算术表达式 var=$[ 算术表达式] var=$(( 算术表达式)) var=$(expr arg1 arg2 arg3 ...) ##expr判断后面的变量是否为整数,但不能为0。 declare –i var = 数值 echo ‘ 算术表达式’ | bc bc $RANDOM (0-32767) ##bash内建的随机数生成器 echo $[$RANDOM%50] ##0-49 之间随机数
逻辑运算
true和false 1, 0 输出0为假 设置空为假 设置0为真 与: 1 与 1 = 1 1 与 0 = 0 0 与 1 = 0 0 与 0 = 0 或: 1 或 1 = 1 1 或 0 = 1 0 或 1 = 1 0 或 0 = 0 非:! ! 1 = 0 ! 0 = 1 短路运算 短路与 第一个为0 ,结果必定为0 第一个为1 ,第二个必须要参与运算 短路或 第一个为1 ,结果必定为1 第一个为0 ,第二个必须要参与运算 异或:^ 异或的两个值, 相同为假,不同为真 数值交换:
条件性执行操作符:&&和||
根据退出状态而定,命令可以有条件地运行。 && 代表条件性的and、then,与 || 代表条件性的or、else,或
条件测试:
判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成测试过程 评估布尔声明,以便用在条件性执行中 若真,则返回0 若假,则返回1 测试命令和表达式 test EXPRESSION [ EXPRESSION ] [[ EXPRESSION ]] ##支持扩展的正则表达式算法 注意: EXPRESSION 前后必须有空白字符 多测试在使用 ![](http://images2017.cnblogs.com/blog/1250974/201802/1250974-20180207000632435-1219260200.png) 数值测试: -gt (great than) 大于 -ge (great equal) 大于等于 -eq (equal) 等于 -ne (not equal) 不等于 -lt (lower than) 小于 -le (lower equal) 小于等于 字符串测试: == 等于 > ascii 码大于ascii码 < 小于 != 不等于 =~ 左侧字符串能够被右侧的PATTERN所匹配 -z "STRING“ 字符串为空,空为真,不空为假 -n "STRING“ 字符串不空,不空为真,空为假 注意: 此表达式一般用于[[ ]] 中;扩展的正则表达式。 用于字符串比较时,用到的操作数STRING都应该使用引号。 文件测试 存在为真,不存在为假 存在性和类别测试: -a|-e FILE: 是否文件存在 -b FILE : 是否存在且为块设备文件 -c FILE : 是否存在且为字符设备文件 -d FILE : 是否存在且为目录文件 -f FILE : 是否存在且为普通文件 -h|-L FILE : 存在且为符号链接文件 -p FILE : 是否存在且为命名管道文件 -S FILE : 是否存在且为套接字文件 文件权限测试: -r FILE : 是否存在且可读 -w FILE: 是否存在且可写 -x FILE: 是否存在且可执行 测试的是实际权限,例如root就有大多数权限 文件特殊权限测试: -u FILE : 是否存在且拥有suid 权限 -g FILE : 是否存在且拥有sgid 权限 -k FILE : 是否存在且拥有sticky 权限 文件大小测试: -s FILE: 是否存在且非空 文件是否打开: -t fd: fd表示文件描述符是否已经打开且与某终端相关 -N FILE: 文件自从上一次被读取之后是否被修改过 -O FILE : 当前有效用户是否为文件属主 -G FILE : 当前有效用户是否为文件属组 双目测试: FILE1 -ef FILE2: FILE1与FILE2 是否指向同一个设备上的相同inode FILE1 -nt FILE2: FILE1是否新于FILE2 (mtime) FILE1 -ot FILE2: FILE1是否旧于FILE2 组合测试 命令 COMMAND1 && COMMAND2 并且 COMMAND1 || COMMAND2 或者 ! COMMAND 非 如:[[ -r FILE ]] && [[ -w FILE ]] 表达式 EXPRESSION1 -a EXPRESSION2 并且 EXPRESSION1 -o EXPRESSION2 或者 ! EXPRESSION 非 必须使用测试命令进行 示例: [ -z “$HOSTNAME” -o $HOSTNAME "=="localhost.localdomain" ] && hostname shen [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
括号的用法
小括号() (子进程),小括号是开子进程了,开子shell,小括号内值,只能在括号内用。 中括号[ ] [表达式],用于测试 大括号{ } { cmd ; cmd ; …. ; }不会开子shell
参数导入:read
使用read 来把输入值分配给一个或多个shell 变量。 使用read 从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量。 示例: read -p “Enter a filename: “ FILE read a b c <<< "xxx yyy zzz"
展开命令行的优先级
优先级从高到低 把命令行分成单个命令词 展开别名 展开大括号的声明({}) 展开波浪符声明(~) 命令替换$() 和 (``) 再次把命令行分成命令词 展开文件通配(* 、? 、[abc] 等等) 准备I/0 重导向(< 、>) 运行命令
防参数属性扩展
反斜线(\ )会使随后的字符按原意解释 $ echo Your cost: \$5.00 Your cost: $5.00 加引号来防止扩展 单引号(’ )防止所有扩展 双引号(” )也防止所有扩展,但是以下情况例外: $ (美元符号)#变量扩展 ` (反引号)#命令替换 \ (反斜线) #禁止单个字符扩展 ! (叹号)#历史命令替换
$- 变量
echo $- himBH h:hashall , 打开这个选项后,Shell会将命令所在的路径hash下来,避免每次都要查询,通过set +h 将h 选项关闭。 i:interactive-comments, 包含这个选项说明当前的shell的是一个交互式的 shell ,所谓的交互式shell, 在脚本中i 选项是关闭的。 m:monitor, 打开监控模式,就可以通过Job control 来控制进程的停止、继续,后台或者前台执行等。 B:braceexpand , 大括号扩展 H:history , H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!” 返回上最近的一个历史命令,“!n”第 返回第 n个历史命令