一、初识shell
文件描述符与重定向
0:标准输入
1:标准正确输出
2:标准错误输出
1>a.txt 与 >a.txt 一样,不写默认前面为1,省略,把标准输出重定向到a.txt中
2>a.txt 将错误输出重定向到a.txt中
&>a.txt 混合输出,将正确和错误的都输出到a.txt文件
注意:当使用>时,会判断右边的文件存不存在,如果存在的话就先删除,然后创建一个新的文件,不存在的话则直接创建。但是当使用
>>
进行追加时,则不会删除原来已经存在的文件。一般来说, "1>" 通常可以省略成 ">".
1>&2 正确返回值传递给2输出通道 &2表示2输出通道,之前如果有定义标准错误重定向到某log文件,那么标准输出也重 定向到这个log文件,如果此处错写成 1>2, 就表示把1输出重定向到文件2中.
2>&1 错误返回值传递给1输出通道, 同样&1表示1输出通道. nginx -V
例子. 当前目录下只有a.txt,没有b.txt[root@redhat box]# ls a.txt b.txt 1>file.out 2>&1 [root@redhat box]# cat file.out ls: b.txt: No such file or directory a.txt
现在, 正确的输出和错误的输出都定向到了file.out这个文件中, 而不显示在前端 =================================
[root@redhat tmp]# cat >> b.txt <<! > ni hao a hahafvs >! [root@redhat tmp]# cat b.txt ni hao a haha
补全
bash-completion #增加补全
//这个需要下载 yum -y install bash-completion
历史命令
history
查看历史命令:
Ctrl +r 搜索关键字
向上箭头
esc+. 调用上一条历史命令的最后一个参数
给历史命令前面加上时间:
1.vim /etc/profile //配置文件
HISTIMEFORMAT=“%Y-%m-%d %H:%M:%S”
2.再次执行history查看结果
source /etc/profile
别名
alias 别名=‘df-h’ //临时修改,重启后失效
永久生效:
vim /root/.bashrc //配置文件,将要修改的别名写进去
前后台作业
1.将前台作业改为后台作业
(1)# sleep 3000
Ctrl+z //暂停
bg % 加工作号
(2)
sleep 1000 &
(3)
nohup sleep 1000 &
2.后台调到前台
fg % 工作号
3.查看当前终端上有多少挂在后台的作业
jobs //终端断掉则不能查看
4.进程管理
ps -ef //列出所有进程
快捷键
Ctrl+a 光标会回到行首
Ctrl +e 光标回到行尾
Ctrl+u 删除光标前面内容
Ctrl+k 删除光标后面内容
Ctrl+c 终止
Ctrl+l 清屏
Ctrl+d 登出
date时间
date +%F 年月日
date +%T 时间
date+%u 星期
date+%d 日
date+%m 月份
date+%-m/^+%-d 9/9 去掉09的0
管道 |
例如:查看本主机ip 3种方式都用到管道
#ifconfig | awk 'NR==2{print $2}'
# ip a | grep inet |grep brd |cut -d ' ' -f6|cut -d '/' -f1
# ip -f inet a show dev ens33 |awk 'NR==3 print{$2}'
命令排序执行
; 分隔开,互不影响
&& 上一条命令执行成功,才能执行下一条命令
|| 上一条命令执行失败,才能执行下一条命令
二、shell 脚本规范
[root@newrain ~]# vim helloworld.sh ---.sh代表这个文件是个shell脚本,第一个原因,让别人认的这个是shell脚本,sh后缀有高亮显示。
拓展名后缀,如果省略.sh则不易判断该文件是否为shell脚本1. #!/usr/bin/env bash ---shebang蛇棒, 解释器, 翻译 2. # 3. # 3. # Author: newrain 4. # Email: newrain@163.com ---这就是注释, 你没看错 5. # Github: https://github.com/newrain001 6. # Date: 2019/**/** 7. printf "hello world\n" 功能说明:打印hello world [root@newrain ~]# sh helloworld.sh hello world [root@newrain ~]# chmod +x helloworld.sh [root@newrain ~]# ./helloworld.sh [root@newrain tmp]# /tmp/helloworld.sh hello world
# 执行脚本方式
1、 sh 脚本.sh
2、 bash 脚本.sh
3、 ./脚本.sh # 需要执行权限
4、 . 脚本.sh
5、 source 脚本.sh
第一行: “#!/usr/bin/env bash”叫做shebang, shell语法规定shell脚本文件第一行为整个文件的解释器
第二行: 为“#”开头的行为注释行默认不会被程序所读取, 用来说明文件及标定所属人员使用, 也可用来解释程序 第七行: 为格式化打印语句printf, printf可以把后面的“hello world”打印到指定的终端中, \n 为换行符
三、变量的类型
变量
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
自定义变量
定义:变量名称=值
变量名称:只能以字母,数字,下划线组成,不能以数字开头;
注意:应该让变量名称有意义;
= 赋值符号 前后不能有空格 ;
值: 所有的字符串和数字都可以;引用变量:$变量名 或者 ${ 变量名 }
示例:
[root@newrain ~]# a=100
[root@newrain ~]# echo $a
100
[root@newrain ~]# echo $aa
# 这里输出为空,因为解释器认为$aa是变量
[root@newrain ~]# echo ${a}a
100a查看变量:echo $变量名 set (所有变量:包括自定义变量和环境变量)
取消变量:unset 变量名 仅在当前shell有效
作用范围:仅在当前shell有效
环境变量
env 查看所有环境变量
set 查看所有变量
环境变量拥有可继承性:export之后就拥有继承性
export 导出变量(作用范围)
临时生效
[root@newrain ~]# IPADDR=192.168.1.1
[root@newrain ~]# echo $IPADDR
192.168.1.1
永久生效
写到4个登陆脚本中 ~/.bashrc ~/profile 更好放在/etc/profile.d/* 下建立独立的环境变量配置文件
常用环境变量:USER UID HOME HOSTNAME PWD PS1 PATH
PATH:存储所有命令所在的路径
练习1
编写一个shell脚本,用于搜集其执行主机的信息,打印结果如下:
[root@tiger tmp]# ./test.sh
2012年 05月 24日 星期四 17:07:45 CST
当前的用户为 root
当前用户的宿主目录为 /root 用户的标识为 0
主机名称为 newrain
网卡的IP地址为 192.168.1.106#脚本源码
#!/bin/bash
获取主机的基本信息
time=`date +%y年%m月%d日-%H:%M:%S`
ip=`ifconfig eth0|grep inet|awk '{print $2}'` echo "现在的时间是:" $time
echo "当前的用户为:"$USER
echo "当前的用户标识:" $UID
echo "当前的主机名称是:" $HOSTNAME
echo "当前可用网卡IP是:" $ip取根分区的剩余空间:df -h | awk 'NR==6{print $3}
取当前系统剩余内存:free -m | awk 'NR==2{print $4}
取当前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
练习二
位置变量
$1 $2 $3 $...
#/test.sh start
#/test.sh 2 3 5 hello
start是第1个位置参数
2 是第1个位置参数
3 是第2个 依次类推
例子:
[root@newrain shell]# cat weizhi.sh
#!/bin/bash
#...
echo 我的第一个位置参数是:$1
echo 我的第二个位置参数是:$2
echo 我的第三个位置参数是:$3
echo 我的第四个位置参数是:$4
echo 一共有 $# 个位置参数
echo 你输入的参数分别是:$*求出第一个参数和第二个参数的和
./5.sh 4 5
9
./5.sh 10 20 30
#!/bin/bash
# 求 $1 $2 的和
x=${1:-0}
y=${2:-0}
echo $(($x+$y))