shell脚本编程初步
程序:由数据和指令组成, 指令:由程序文件提供 数据:可以通过IO设备、文件、管道来得到,
程序:算法+数据结构 变量:变量名+变量名指向的内存空间 变量赋值: name = value变量类型:存储格式:字符 数值(精确数值 近似数值) 表示数据范围 参与的的运算 编程语言: 强类型变量编程语言:c 弱类型变量编程语言: bash把所有变量统统视作字符型。不支持浮点数据,除非借助第三方工具 bash中的变量无需事先声明 声明: 类型 变量名 变量替换:把变量名的出现位置替换为其所指向的内存空间中的数据 变量引用:$(var_name) $var_name 变量名:变量名只能包含数字、字母、下划线,而且不能以数字开头 变量名:见名知意,命名机制遵循某种法则,不能使用程序的保留字。例如:if else then while ...
变量类型:
本地变量:作用域仅为当前shell进程 环境变量:作用域为当前shell进程及其子进程 局部变量:作用域仅为某代码片段(函数上下文) 位置参数变量:当执行脚本的shell进程传递的参数 特殊变量:shell内置的有特殊功能的变量 $? 0:成功 1-255:失败 本地变量: 变量赋值:name = value 变量引用:$(name) $name “”:变量名会替换为其值 ‘’:变量名不会替换为其值 查看变量:set撤销变量:unset name 注意:此处非变量引用,不要加$符号 环境变量: 变量赋值: (1)export name =value (2)name = value export name (3)declare -x name=value (4)name = vlaue declare -x name 变量引用:$(name),$name 注意:bash内嵌了许多环境变量(通常为全大写字符),用来定义bash的工作环境 PATH HISTFILE HISTFILESIZE SHELL 。。 查看环境变量:export, declare -x, printenv,env 撤销环境变量:unset name只读变量: (1)declare -r name (2)readonly name 只读变量无法重新赋值,并且不支持撤销; 存活时间为当前shell进程的生命周期,随shell进程终止而终止。
逻辑运算:
运算数:只有真(true,1)或假(false,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 异或:相同为假不同为真 短路法则: ~] COMMAND1 && COMMAN D2 COMMAND1:为假,则COMMAND2不会再执行: 否则,COMMAND1为真,COMMAND2必须执行 ~] COMMAND1 || COMMAND2 COMMAND1 为真,COMMAND2不会在执行 COMMAND1 为假,COMMAND2必须执行 实例:~] id $username || useradd $username 如果$username存在 则useradd $username不执行 如果$username不存在,则执行useradd $username,创建$username 用户
shell脚本编程:
编程语言的分类:根据运行之前是否需要编译(运行方式) 编译运行:源代码-->编译器(编译)-->程序文件 解释运行:源代码-->运行时启动解释器,由解释器边解释边运行; (源代码本身不可执行,而是解释器处理运行) 根据其编程过程当中,功能的实现,是调用库还是调用外部的程序文件可分为: shell脚本编程: 利用系统上的命令及编程组件进行编程 完整编程: 利用库或编程组件进行编程 根据编程模型分类: 面向过程式编程语言 面向对象式编程语言 程序 = 指令 + 数据 过程式:以指令为中心来组织代码,数据是服务于代码 顺序执行 选择执行 循环执行 代表:C语言 bash 对象式:以数据为中心来组织代码,围绕数据来组织指令 执行过程中先生成指定的对象 编写程序的过程中要编写很多的类(class) 类:实例化对象 代表:java ,c++, Python SHELL脚本编程:过程式编程,解释运行,依赖于外部执行文件运行 如何写shell脚本: 脚本文件的第一行,固定格式: 顶格写:给出shebang,解释器路径,用于解释执行当前的脚本的解释器程序文件。 常见的解释器: #!/bin/bash #!/usr/bin/python #!/usr/bin/pertshell脚本是什么? 可以认为是命令的堆积: 但是大多命令不具有幂等性,需要用程序逻辑来判断运行条件是否满足,以避免其运行中发生错误; 运行脚本: (1):赋予执行权限,并直接运行此脚本程序文件 chmod + x file (2):直接运行解释器,将脚本以命令行参数传递给解释器程序。 注意: 脚本中的空白行会被解释器自动忽略 脚本中,除了shebang,余下的所有以#开头的行 ,都会被视作注释行而被忽略; shell脚本的运行是通过一个子shell进程实现的 bash的配置文件: 两类 profile类:为交互式登录的shell进程提供配置 bashrc类:为非交互式登录的shell进程提供配置 登录类型: 交互式登录shell进程: 直接通过某终端输入账号和密码后登录打开的SHELL进程。 使用su命令:su - USERNAME,或者使用su -l USERNAME执行的登录切换 非交互式登录shell进程: su USERNAME执行的登录和切换 图形界面下打开的终端 运行脚本 profile类: 全局生效:对所有用户都生效 /etc/profile /etc/profile.d/*.sh 用户个人:仅对当前用户有效 ~/.bash_profile 功用: 1、用于定义环境变量 2、运行命令或脚本 bashrc类: 对全局生效: /etc/bahsrc 用户个人: ~/.bashrc 功用: 1、定义本地变量 2、定义命令别名 注意:只有管理员可修改全局配置文件; 配置文件的读取顺序: 交互式登录shell进程: /etc/profile-->/etc/profile.d/*-->~/.bash_profile-->~/.bashrc-->/etc/bashrc 非交互式登录的shell进程: ~/.bashrc-->/etc/bashrc-->/etc/profile.d/* 命令行中定义的特性,其作用域为当前shell进程的声明周期 配置文件定义的特性,只对随后重新启动的SHELL进程有效 让通过配置文件定义的特性立即生效: (1)通过命令行重复定义一次 (2)让shell进程重新读取配置文件 ~]# source /PATH/FROM/CONF_FILE ~]# ./PATH/FROM/CONF_FILE shell脚本之算术运算 加:+ 减:- 乘:* 除:/ 次方:** 取余运算:% 算数运算格式: (1)let VAR = 算数运算表达式 [root@localhost ~]# let sum=5+9 [root@localhost ~]# echo $sum 14 (2)VAR=$[算数运算表达式] [root@localhost ~]# echo $[5+9] 14 (3)VAR=$((算数运算表达式)) [root@localhost ~]# echo $((5+9)) 14 (4)VAR=$(expr $num1 + $num2) [root@localhost ~]# expr 5 + 9 14 要是想引用计算的结果要使用变量引用; [root@localhost ~]# sum=$(expr 5 + 9) [root@localhost ~]# echo $sum 14 注意乘法符号*在有些场景中需要使用转义字符; 脚本文件格式: 第一行,顶格:#!/bin/bash 注释信息:# 代码注释:写脚本一定要写代码注释,方便自己,利于他人看懂。 规范写代码: 缩进 适度添加空白行 编程思想: 问题空间--》解空间 变量: 局部变量:只在当前shell进程中的一段代码片段中有效 本地变量:只在当前shell进程中有效,对其他shell进程包括当前shell的子进程均无效 环境变量:生效范围为当前shell进程以及其子进程 只读变量 位置参数变量:用于让脚本在脚本代码中调用通过命令传递给它的参数。 特殊变量:$?,$0,$*,$@,$# 数据类型: 字符型,数值型(精确数值,近似数值) (shell脚本内置不支持浮点数运算,需要借助其他工具) 增强型赋值: 变量做某种算术运算后结果回存至此变量中 let $i + # = let i+=# += -= *= /= %= 自增:++ let VAR =$[$VAR+1] let VAR+=1 let VAR++ 自减:-- let VAR =$[$VAR-1] let VAR-=1 let VAR-- 子shell进程:在当前脚本中用用括号将一段命令括起来说明此中的代码将在当前脚本进程的子进程中运行。 例如: echo "$1"|grep -E '\<((([0-9]|[1-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|2[0-4][0-9]|25[0-5]))\>' && (ping -c1 -w1\$1 &> /dev/null && echo "您所给的IP是:$1-->该IP可访问"||echo "您所给的IP是:$1-->该IP不可访问")|| echo "您所给的IP格式不合法";exit 上面的代码中:(ping -c1 -w1\$1 &> /dev/null && echo "您所给的IP是:$1-->该IP可访问"\||echo "您所给的IP是:$1-->该IP不可访问") 就是在其shell进程中的子shell进程中运行。
条件测试
判断某需求是否满足,需要由测试机制来实现; 专用的测试表达式需要由测试命令辅助完成测试过程; 评估布尔声明,以便用在条件性执行中 若真,则返回0 若假,则返回1测试命令: test EXPRESSION [ EXPRESSION ] [[ EXPRESSION ]] 注意:EXPRESSION前后必须有空白字符
bash的测试类型
数值测试: -gt: 是否大于; -ge: 是否大于等于; -eq: 是否等于; -ne: 是否不等于; -lt: 是否小于; -le: 是否小于等于; 字符串测试: == :是否等于; >: ascii 码是否大于ascii码 码 <: 是否小于 !=: 是否不等于 =~: 左侧字符串是否能够被右侧的PATTERN所匹配 注意: 此表达式一般用于[[ ]] 中; -z "STRING" :字符串是否为空,空为真,不空为假 -n "STRING" :字符串是否不空,不空为真,空为假 注意:用于字符串比较时的用到的操作数都应该使用引号 文件测试: 存在性测试 -a FILE :同-e -e FILE: 文件存在性测试,存在为真,否则为假; 存在性及类别测试 -b FILE :是否存在且为块设备文件; -c FILE :是否存在且为字符设备文件; -d FILE :是否存在且为目录文件; -f FILE :是否存在且为普通文件; -h FILE 或 -L FILE :存在且为符号链接文件; -p FILE :是否存在且为命名管道文件; -S FILE :是否存在且为套接字文件; 文件权限测试: -r FILE :是否存在且可读 -w FILE: 是否存在且可写 -x FILE: 是否存在且可执行 文件特殊权限测试: -g FILE :是否存在且拥有sgid 权限; -u FILE :是否存在且拥有suid 权限; -k FILE :是否存在且拥有sticky 文件大小测试: -s FILE :是否存在且非空 文件是否打开: -t fd: fd 表示文件描述符是否已经打开且与某终端相关 -N FILE :文件自动上一次被读取之后是否被修改过 -O FILE :当前有效用户是否为文件属主 -G FILE :当前有效用户是否为文件属组组合测试条件: COMMAND1 && COMMAND2 并且 COMMAND1 || COMMAND2 或者 !COMMAND 非 如: [ -e FILE ] && [ -r FILE ] EXPRESSION -a EXPRESSION 并且 EXPRESSION -o EXPRESSION 或者 !EXPRESSION 必须使用测试命令进行: # [ -z “$HOSTNAME” -o $HOSTNAME "==\ "localhost.localdomain" ] && hostname www.magedu.com # [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
原创文章,作者:dxkboke,如若转载,请注明出处:http://www.178linux.com/34257
评论列表(1条)
整体思路清晰,分类明确,层次感强,变量=左右不允许有空格,