bash特性及bash脚本编程初步 终端,附着在终端的接口程序; GUI: KDE,GNome,Xfce CLI: /etc/shells bash的特性: 命令行展开: ~,{} 命令别名: alias,unalias 命令历史: history 文件名通配: glob 快捷键:ctrl + a ,e,u,k,l 命令补全:$PATH 路径补全: bash特性之: 命令hash 缓存此前命令的查找结果: key-value key : 搜索键 value : 值 hash命令 : hash: 列出 hash -d cmd: 删除 hash -r : 清空 bash的特性之一: 变量 程序: 指令+数据 指令:由程序文件提供; 数据:IO设备,文件,管道,变量 程序: 算法+数据 变量名+指向的内存空间 变量赋值: name=value 变量类型: 存储格式,表示数据范围,参与的运算 编程语言: 强类型变量: 弱类型变量:bash把所有变量统统视为字符型;bash中的变量无需事先声明; 变量替换:把变量名出现的位置替换为其所指向的内存空间中数据; 变量引用:${var_name},$var_name 变量名:包含字母,数字和下划线(开头不能是数字) 变量名:见名知义,命令机制遵循某种法则,以便区分,理解;不能使用程序的保留字,例如:if,else,while等 bash变量类型: 本地变量:作用域仅为当前shell进程 环境变量:作用域为当前shell进程及其子进程 局部变量:作用域仅为某代码片段(函数上下文) 位置参数变量:当执行脚本的shell进程传递的参数; 特殊变量:shell内置的有特殊功用的变量; $?: 0:成功 1-255: 失败 本地变量: 变量赋值:name=value 变量引用:${name},$name "":变量名会替换为其值; '':变量名不会替换为其值; 查看变量:set 撤销变量:unset name 注意:此处非变量引用; 环境变量: 变量赋值: (1) export name=value (2) name=value export name (3) delcare -x name=value (4) name=value declare -x name 变量引用:${name},$name 注意: bash内嵌了许多环境变量(通常为全大写字符),用于定义bash工作环境 PATH,HISTSIZE,HISTFILE,SHELL,HOME,UID,PWD... 查看环境变量:export,declare -x,env,printenv 撤销环境变量:unset name 只读变量: (1) declare -r name (2) readonly name 只读变量无法重新赋值,并且不支持撤销;存活时间为当前shell进程的生命周期,随shell进程进程终止而终止; bash特性之一多命令执行: # cmd1 ; cmd2 ; cmd3 ; ... 逻辑运算: 运算数: 真(true,yes,on,1) 假(false,no,off,0) 与: 1 && 0 = 0 或: 1 || 0 = 1 非: ! 1 = 0 异或:判断是否相同,相同为0,相异为1; 短路法则: 示例:# id $username || useradd $username shell脚本编程: 编程语言分类:根据运行方式 编译运行:源代码-->编译器(编译)-->程序文件 解释运行:源代码-->运行时启动解释器,由解释器边解释边运行; 根据其编程中功能的实现是调用库还是调用外部的程序文件; shell脚本编程: 利用系统上的命令及编程组件进行编程; 完整编程: 利用库或编程组件进行编程; 编程模型:过程式编程语言,面向对象的编程语言 过程式:以指令为中心来组织代码,数据服务于代码; 顺序执行 选择执行 循环执行 如:c,bash 对象式:以数据为中心来组织代码,围绕数据来组织指令; 类(class): 实例化对象,method; 如:Java,c++,Python shell脚本编程:过程式编程,解释运行,依赖外部程序文件运行 如何写shell脚本: 脚本文件的第一行,定格:给出shebang,解释器路径,用于指明解释器当前脚本的解释器程序文件 常见的解释器: #!/bin/bash #!/usr/bin/python 文本编辑器:nano 行编辑器:sed 全屏编辑器:nano,vi,vim shell脚本是什么? 命令的堆积; 但很多命令不具幂等性,需要用程序逻辑来判断运行条件是否满足,以避免其运行中发生错误; 运行脚本: (1)赋予执行权限,并直接运行行命令参数传递给解释器程序; chmod +x /PATH /PATH (2) 直接运行解释器,将脚本以命令行参数传递给解释器程序; bash /PATH 注意: 脚本中的空白行会被解释器忽略; 脚本中,除了shebang,余下所有以#开头的行,都会被视作注释行被忽略; shell脚本的运行是通过运行一个子shell进程实现的; 练习:写脚本 (1) 显示/etc目录下所有以大写p或小写p开头的文件或目录本身; (2) 显示/var 目录下的所有文件或目录本身,并将显示结果中的小写转换为大写后显示; (3) 创建临时文件/tmp/myfile.xxxx; bash的配置文件: 两类: profile类:为交互式登录的shell进程提供配置 bashrc类:为非交互式登录的shell进程配置 登录类型: 交互式登录shell进程: 直接通过某终端输入账号和密码后登录打开的shell进程; 使用su - username 或者 su -l username执行的登录切换; 非交互式登录shell进程: su username执行的登录切换; 图形界面下打开的终端; 运行脚本 profile类: 全局:对所有用户都有效; /etc/profile /etc/profile.d/*.sh 用户个人:仅对当前用户有效; ~/.bash_profile 功用: 1.用于定义环境变量; 2.用于运行命令和脚本; bashrc类: 全局: /etc/bashrc 用户个人: ~/.bashrc 功用: 1.定义本地变量; 2.定义命令别名; 注意:仅管理员可修改全局配置文件; 交互式登录shell进程: /etc/profile-->/etc/profile.d/*-->/.bash_profile-->~/.bashrc-->/etc/bashrc 非交互式登录shell进程: ~/.bash rc-->/etc/bashrc-->/etc/profile.d/* 命令行中定义的特性,例如变量和别名作用域为当前shell进程的生命周期 配置文件定义的特性,只对随后新启动的shell进程有效 让通过配置文件定义的特性立即生效: (1) 通过命令行重复定义一次; (2) 让shell进程重新读配置文件; ~]# source /PATH ~]# . /PATH 问题一:定义对所有用户生效的命令别名,例如 cls='clear'? 问题二:让centos用户登录是,提供其已经登录,并显示当前系统时间?
bash脚本编程运算: +,-,*,/,**,% 算术运算表达式: (1)let VAR=算术运算表达式 (2)VAR=$[算术运算表达式] (3)VAR=$((算术运算表达式)) (4)VAR=$(exor $arg1 $op $arg2) 如: [root@localhost ~]# n1=3 [root@localhost ~]# n2=3 [root@localhost ~]# echo "$n1+$n2" 3+3 [root@localhost ~]# echo "$((n1+$n2))" 6 [root@localhost ~]# echo "$[n1+$n2]" 6 [root@localhost ~]# echo "$(expr $n1 + $n2)" 6 注意:乘法符号在有些场景中需要使用转义符; 练习: 写一个脚本,完成如下功能; 添加三个用户; 求此三个用户的UID之和;
1 bash的基础特性: 2 globbing:文件名通配(整体文件名匹配,而非部分); 3 匹配模式:元字符 4 *:匹配任意长度的任意字符.例如:pa*,*pa,*pa*,*p*a* 5 ?:匹配任意单个字符.例如:pa?,??pa,p?a,p?a?, 6 []:匹配指定范围内的单个字符. 7 [a-z],[A-Z],[0-9],[a-z0-9] 8 [[:upper:]]:所有大写字母 9 [[:lower:]]:所有小写字母 10 [[:alpha:]]:所有写字母 11 [[:digit:]]:所有数字 12 [[:alnum:]]:所有字母和数字 13 [[:space:]]:所有空白字符 14 [[:punct:]]:所有标点符号 15 例如:pa[0-9][0-9],2[0-9][0-9],[abcd].... 16 [^]:匹配指定范围外的任意单个字符 17 [^[:upper:]] 18 [^0-9] 19 [^[:alnum:]] 20 21 IO重定向及管道 22 程序:数据+指令 23 输入数据流:<--标准输入(stdin),键盘; 24 输出数据流:-->标准输出(stdout),键盘; 25 错误输出: -->错误输出(stderr),显示器; 26 27 fd:file description,文件描述符 28 标准输入:0 29 标准输出:1 30 错误输出:2 31 32 IO重定向: 33 输出重定向: > 34 特性: 覆盖输出 35 输出重定向:>> 36 特性:追加输出 37 38 # set -C 39 禁止覆盖输出重定向至已存在文件; 40 此时可使用强制覆盖输出:> 41 # set +C 42 关闭上述特性 43 44 错误输出流重定向: 2> , 2>> 45 46 合并正常输出流和错误输出流: 47 (1) &> ,&>> 48 (2) cmd > /PATH 2>&1 49 cmd >> /PATH 2>&1 50 51 输入重定向: < 52 53 tr命令: 54 tr [option] ... set1 [set2] 55 把输入的数据当中的字符,凡是在set1定义范围内出现的,通过对位转换为set2出现的字符 56 用法1: tr set1 set2 < /PATH 57 用法2: tr -d set1 < /PATH (不输出set1范围字符) 58 注意:不修改原文件 59 60 here document: << 61 62 cat << EOF 63 cat > /PATH << EOF 64 65 管道|:连接程序,实现将前一个命令的输出直接定向后一个程序当做输入数据流 66 cmd | cmd | cmd |... 67 68 tee命令: (从标准输入读入,输出并写入文件) 69 cmd | tee /PATH 70