shell编程
1 初识shell
1.1 文件描述符与输出重定向
FD (file descriptor)
FD值 | 英文 | 含义 |
---|---|---|
0 | Standard Input | 正确输入,并返回在前端 |
1 | Standard Output | 正确返回值 |
2 | Standard Error Output | 错误返回值 |
常见格式
a.txt
1>a.txt
标准正确输出到a.txt
2>a.txt
准错误输出到a.txt
&>a.txt
混合输出重定向
1>&2
正确返回值传递给2输出通道,&2表示2输出通道
2>&1
错误返回值传递给1输出通道,&1表示1输出通道
2>1
表示把2输出重定向到文件1中
例1:nginx -V
目的:筛选出nginx的版本号
使用命令nginx -V |grep version
判断命令nginx -V |grep version
执行是否正确
echo $?
输出为1,表示以上输出是标准错误输出,应使用重定向输出管道2
将标准错误输出管道2的值传递给标准正确输出1管道,标准正确输出的内容才可被grep过滤
nginx -V 2>&1 |grep version
例2:当前目录下只有a.txt,没有b.txt
- 1 通道
- 2 通道
1and2通道:2通道错误返回值传递给1输出通道,转为正确输出。正确的输出和错误的输出都定向到了file.out这个文件中
1.2 cat输入重定向
格式:cat >> file.txt << 111
content
111
1.3 历史命令
补全 bash-completion # 增加补全
历史 history
别名 alias
快捷键
前后台作业
管道
命令排序执行
; && ||
; 命令分割,在一行中执行多条语句
&& 一行中执行多条语句,前成功后面再执行
|| 一行中执行多条语句,前面不成功,后面再执行
通配符
{} ?*
正则表达式 脚本
-
历史命令
1 查看历史命令 history # /etc/profile 下的historysize 可以修改 2 调用历史命令 上下健 esc . 上一条命令的最后一个参数 Ctrl+r 在历史命令中查找,输入关键字调出之前的命令 3 别名 查看别名 alias 设置别名 临时设置 # alias aa='df -Th' # aa 永久设置 # vim /root/.bashrc 4 小小技巧:显示历史命令执行时间 1.设置变量: HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S" 2.再次执行history查看结果
2 shell 脚本规范
helloworld.sh
.sh
代表这个文件是个shell脚本,第一个原因,让别人认的这个是shell脚本,sh后缀有高亮显示。
-
shell文件head
#!/usr/bin/env bash ---shebang蛇棒, 解释器, 翻译 拓展名后缀,如果省略.sh则不易判断该文件是否为shell脚本 1. 2. # 3. # 3. # Author: newrain 4. # Email: newrain@163.com ---这就是注释, 你没看错 5. # Github: https://github.com/newrain001 6. # Date: 2019/**/** 7. printf "hello world\n"
-
执行脚本方式
1 sh 脚本.sh 2 bash 脚本.sh 3 ./脚本.sh # 需要执行权限 4 . 脚本.sh 5 source 脚本.sh
3 变量的类型
-
变量
- bash作为程序设计语言和其它高级语言一样也提供使用和定义变量的功能
-
预定义变量、环境变量、自定义变量、位置变量
-
预定义变量
变量 变量含义 $? 最后一次执行的命令的返回状态。如果这个变量的值为 0,则证明上一条命令正确执行;如果这个变量的值为非 0 ,则 证明上一条命令执行错误 $$ 当前进程的进程号(PID) $! 后台运行的最后一个进程的进程号(PID) [root@newrain sh]# ls count.sh hello.sh parameter2.sh parameter.sh #ls命令正确执行 [root@newrain sh]# echo $? 0 #预定义变量"$?"的值是0,证明上一条命令正确执 [root@newrain sh]# vim variable.sh #!/bin/bash echo "The current process is $$" #输出当前进程的PID #这个PID就是variable.sh脚本执行时生成的进程的PID [root@newrain sh]# sleep 3000 & [1] 12165 #符号"&"的意思是把命令放入后台执行 [root@newrain sh]# echo $! 12165
-
环境变量
-
shell在开始执行时已经定义好的
-
env 查看所有环境变量
-
set 查看所有变量
-
环境变量拥有可继承性:export之后就拥有继承性
-
export 导出变量(作用范围)
-
临时生效
[root@newrain ~]# IPADDR=192.168.1.1 [root@newrain ~]# echo $IPADDR 192.168.1.1
-
永久生效
写到以下环境变量配置文件中: 系统级别的文件,配置之后所有用户都会生效 /etc/profile # 配置环境变量的文件 /etc/bashrc 用户级别的文件,配置完成之后只针对当前用户生效 $HOME_DIR .profile .bashrc 常用环境变量:USER UID HOME HOSTNAME PWD PS1 PATH PATH:存储所有命令所在的路径
-
-
自定义变量
变量名称=值
变量名称: 只能由字母,数字,下划线组成,不能以数字开头; 注意:应该让变量名称有意义; = 赋值符号 前后不能有空格 ; 值: 所有的字符串和数字都可以; 引用变量: $变量名 或 ${变量名}。 查看变量: echo $变量名 set(所有变量:包括自定义变量和环境变量) 取消变量: unset 变量名 仅在当前shell中有效 作用范围: 仅在当前shell中生效
-
-
常用命令
bg %num
# 将前台进程放到后台执行jobs
# 查看任务fg %num
# 将后台进程放到前台执行 -
awk
awk '{print $1}'
# 默认以空为分隔符,打印第一列-F':'
# 指定冒号分隔符awk -F':' '{print $1}'
# 以:为分割符,打印第一列awk 'NR==2{print $2}'
# 以空格为分隔符,打印第二行(NR==2)的第二列将命令的结果当做字符串赋予给变量 time=`date +%Y年%m月%d日-%H:%M:%S-%A` time=$(date +%Y年%m月%d日-%H:%M:%S-%A) 这两种赋值效果一样
练习1
编写一个shell脚本,用于搜集其执行主机的信息,打印结果如下:
[root@tiger tmp]# ./test.sh
2012年 05月 24日 星期四 17:07:45 CST
当前的用户为 root
当前用户的宿主目录为 /root 用户的标识为 0
主机名称为 newrain
网卡的IP地址为 192.168.1.106
##脚本源码如下
#!/usr/bin/bash
# 获取主机基本信息
time=`date +%y年%m月%d日-%H:%M`
ip=`ifconfig eth0|grep inet|awk '{print $2}'` echo "现在的时间是:" $time
echo "当前的用户是:" $USER
echo "当前的用户标识:" $UID
echo "当前的主机名称是:" $HOSTNAME
echo "当前可用网卡IP是:" $ip
取根分区剩余空间:
# df -h /dev/sda2 |awk 'NR==2{print $4}' 371G
取当前系统剩余内存:
# echo "现在的剩余内存是:"`free -m |awk 'NR==2{print $4}'`
现在的剩余内存是:12813M
取当前cpu平均负载:
# echo 现在cpu的`uptime |cut -d, -f3-` //-d指定分隔符,-f指定显示区域,3-第三列以后(包括第三列)
现在cpu的 load average: 0.07, 0.12, 0.11
# echo 现在cpu的`uptime |awk -F"," '{print $4,$5,$6}'`
现在cpu的 load average: 0.00 0.04 0.10