改动时间
2020-03-12 21:51:24
Shell
Shell概述
- 把命令翻译为内核可以识别的语言
- 强大的编程语言,脚本语言,可以直接调用Linux系统命令
- Bash就是一种Shell,是Linux默认的一种Shell。
echo命令
echo 'hello world!'
有空格需要用引号,带有感叹号需要用单引号
-e
支持\
反斜杠控制的字符转换\\
输出\
本身\b
向左删除一个字符\t
制表符,也就是按了一下Tab键\f
换页\n
换行\r
回车echo -e '\e[1;31m hello world\e[0m'
颜色输出- 这里的前面
\e[1;
后面\e[0m
中间31m=红色 后面hello world
输出内容 - 30=黑 31=红 32=绿 33=黄 34=蓝 35=洋红 36=青 37=白
编写第一个脚本
最好写
.sh
扩展名#!/bin/bash
所有Shell都要写这句话,不写的话有些语句会出错
vi hello.sh
写入内容
1
2
3#!/bin/bash
#taopanfeng(www.taopanfeng.top)
echo 'TaoPanfeng is good man!'执行脚本
使用
bash 脚本
执行,没有执行权限也可以如果遇到不能执行的Shell脚本,例如Windows编写的放入Linux就会执行不了
需要安装yum -y install dos2unix
来转换,执行转换dos2unix 文件
因为Windows换行符是M$
结尾,而Linux是$
结尾
可以使用cat -A 脚本文件
来查看Shell隐藏内容
Bash的基本功能
历史命令与补全
历史命令
history
-c
清空历史命令(不建议使用)-w
把历史命令保存到文件~/.bash_history
修改默认保存条数
在~/.bash_history
中默认保存1000条命令,先进先出vi /etc/profile
进入配置文件,修改生效需重新登录
历史命令调用
上下箭头
!n
执行第几条!!
重复上一条!字符串
重复最后一条以该字符串开头的命令
命令补全
Tab
单击对1个补全Tab
双击对多个可补全的进行列出
命令别名与常用快捷键
命令别名
alias 别名='原命令'
定义别名alias
查询所有别名unalias 别名
删除别名
命令执行顺序
- 绝对路径,相对路径执行的命令
- 别名
- 执行Shell内置命令
- 按照$PATH环境变量定义目录从左向右查找命令
别名永久有效
vi /root/.bashrc
在里面添加就行了alias 别名='原命令'
定义别名
Bash常用快捷键
Ctrl + A
光标移到命令开头Ctrl + E
光标移到命令结尾Ctrl + C
终止当前命令Ctrl + L
清空当前命令,相当于直接输入clear
命令Ctrl + U
清空当前正在输入的命令Ctrl + K
删除光标后的所有内容,包括光标所在位置Ctrl + Y
粘贴Ctrl + U
或Ctrl + K
的内容Ctrl + R
进入搜索命令模式,回车执行,上下箭头退出搜索命令模式Ctrl + D
退出当前终端Ctrl + Z
暂停,放入后台Ctrl + S
暂停屏幕输出Ctrl + Q
恢复屏幕输出
输入输出重定向
标注输入,输出
设备 | 设备文件名 | 文件描述符 | 类型 |
---|---|---|---|
键盘 | /dev/stdin | 0 | 标准输入 |
显示器 | /dev/sdtout | 1 | 标准输出 |
显示器 | /dev/sdterr | 2 | 标准错误输出 |
输出重定向
把命令结果不直接显示,而是输出到文件中,比如
日志
文件不存在会创建,没有目录会报错
类型 | 符号 | 作用 | 示例 |
---|---|---|---|
标准输出重定向 | 命令 > 文件 |
覆盖,命令正确则会覆盖,命令错误则清空内容 | |
标准输出重定向 | 命令 >> 文件 |
追加,正确会追加,错误则输出执行结果,原文件不动 | |
标准错误输出重定向 | 错误命令 2> 文件 |
覆盖,命令正确则会覆盖,命令错误则直接输出执行结果并清空文件内容 | |
标准错误输出重定向 | 错误命令 2>> 文件 |
追加,错误会追加,正确则输出执行结果,原文件不动 | |
正确输出和错误输出同时保存 | 命令 > 文件 2>&1 或命令 &> 文件 |
覆盖,不论正确还是错误 | |
正确输出和错误输出同时保存 | 命令 >> 文件 2>&1 或命令 &>> 文件 |
追加,不论正确还是错误 | |
正确输出和错误输出同时保存 | 命令 >> 文件1 2>>文件2 |
正确追加到文件1 ,错误追加到文件2 |
输入重定向
wc
-l
只统计行数-w
只统计单词数-c
只统计字符数输入
wc
回车就可以输入内容了,Ctrl + D
结束Ctrl + D
执行的行不计入行的统计空格和换行分割单词
空格和换行都记作1个单词
对文件操作
wc < 文件
多命令执行逻辑与管道符
多命令顺序执行
多命令执行符 | 格式 | 作用 | 示例 |
---|---|---|---|
; |
命令1 ; 命令2 |
无逻辑,从左往右依次执行 | |
&& |
命令1 && 命令2 |
逻辑与and,1执行正确,2才执行;1执行执行,2也不执行 | |
|| |
命令1 || 命令2 |
逻辑或or,1执行错误,2才执行;1执行正确,2不执行 |
管道符
命令1 | 命令2
命令1正确输出作为命令2的操作对象
例如
netstat -taplun | grep -in 'establ'
表示在所有监听TCP,UDP协议,显示IP地址,端口号,进程号,进程名称
并筛选只查找有字符串establ
的行,忽略大小写,并显示行号
通配符与其他特殊符号
通配符
通配符 | 作用 | 示例 |
---|---|---|
? |
匹配一个字符 | |
* |
匹配0个或多个,也就是可以匹配任何内容 | |
[] |
匹配括号中任意一个字符,例如[abc] 匹配a 或b 或c |
|
[-] |
匹配括号中任意一个字符,例如[a-z] 代表匹配一个小写字母 |
|
[^] |
逻辑非,匹配不是括号中的任意一个字符,例如[^0-9] 代表匹配一个不是数字的字符 |
特殊符号
符号 | 作用 | 示例 |
---|---|---|
'' |
单引号,在单引号中,如$ ` (反引号)都没有特殊含义 |
|
"" |
双引号,在双引号中所有特殊符号都没特殊含义,但除了$ (调用变量的值) ` (引用命令) \ (转义符) |
|
`` |
反引号,作用与$() 相同,引用系统命令,推荐使用$() ,因为` 反引号经常被看错为' 单引号 |
|
$() |
和`` 作用一样,引用系列命令 |
|
# |
在Shell脚本中,# 开头的行代表注释 |
|
$ |
用于调用变量的值 | |
\ |
转义符,在\ 后面跟的特殊符号将做为普通符号处理,如\$ 将作为字符串$ 输出,而不是引用变量 |
Bash的变量
用户自定义变量
什么是变量
计算机内存的单元,可以改变存放的值.
变量定义规则
- 名称,可以是字母,数字,下划线组成;不能以数字开头,例如
2age
是错误的 - 类型,默认字符串类型,如果要进行数值运算,需要指定为数值类型
- 赋值,使用
=
,而且=
两侧不能有空格 - 变量值若有空格,使用
''
单引号或""
双引号包括 - 变量的值可以使用
\
进行转义 - 【追加变量】可以进行变量追加.不过需
"$变量名"
或${变量名}
【注意:第一种需要双引号】 - 命令结果赋值给变量,使用
``
反引号或$()
包含命令 - 环境变量名建议大写,便于区分
变量分类
自定义变量
环境变量
保存和系统操作相关的数据位置参数变量
想脚本传参,传数据的,变量名固定,作用固定,值可以改预定义变量
bash中定义好的变量,变量名固定,作用也固定,值可以改
设置用户自定义变量
- 变量定义
name="tao pan feng"
- 变量叠加
aa=123
aa="$aa"456
aa=${aa}7890
- 变量调用
echo $变量名
- 变量查看
set
可以查看系统所有变量
- 变量删除
unset 变量名
环境变量
环境变量是什么
自定义变量
只会对当前Shell生效,环境变量
可以对当前Shell包括子Shell生效.- 如果把
环境变量
写入相应配置文件,所有Shell都生效
设置环境变量
- 声明变量
export 变量名=变量值
- 查询变量
env
只能查看环境变量
- 调用变量
echo $变量名
- 删除变量
unset 变量名
系统提示符变量PS1
- 定义系统提示符的变量,严格说不算是系统变量
env
不能查看需要set
查看\d
显示日期,格式星期 月 日
\h
主机名,默认localhost
\t
24小时制时间,格式HH:MM:SS
\T
12小时制时间,格式HH:MM:SS
\A
24小时制时间,格式HH:MM
\u
显示当前用户名\w
显示目录完整名称\W
当前所在目录的最后一个目录\#
显示当前执行的第几个命令\$
提示符,如果是root为#,如果为普通用户为$
- 修改要使用
''
单引号括起来
系统环境变量PATH
可
env
或set
查看PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
使用
:
分割多个路径例如我们输入命令
ls
就会去第1个路径去找,找不到就去第2个路径去找,都找不到的话就会报错查找路径
echo $PATH
变量叠加
PATH=${PATH}:/root/sh
或PATH="$PATH":/root/sh
位置参数变量
也是
预定义变量
$n
$*
$@
$#
位置参数变量 | 作用 |
---|---|
$n |
其中n 为数字,$0 代表命令本身,$1~9 代表第1到9个参数,大于9的需要使用{} 大括号,如${10} |
$* |
代表命令行中所有参数,$* 把所有参数看为一个整体 |
$@ |
也表示命令行所有参数,不过$@ 把所有参数区分对待 |
$# |
代表命令行中所有参数的个数 |
$n
示例
$*
$@
$#
示例
$*
与$@
区别
- 作为循环时,无论输入多少参数
$*
都只会循环一次,因为它把参数看为整体 $@
根据你输入参数个数来确定循环次数
预定义变量
$?
$$
$!
预定义变量 | 作用 |
---|---|
$? |
判断上一条命令是否正确执行,正确执行返回0 否则都不正确 |
$$ |
当前进程的PID 进程号 |
$! |
后台运行的最后一个进程的PID 进程号 |
$?
示例
$$
$!
示例
接收键盘输入read
-p
提示信息,等待输入时输出提示信息-t
秒数,等待用户输入的时间,单位秒
,默认一直等待-n
字符数,如果指定一个字符,输入一个字符就会直接执行,不用回车,默认回车执行-s
隐藏输入数据
Bash的运算符
数值运算与运算符
declare声明变量类型
declare [+/-] [选项] 变量名
-
给变量设置类型属性+
给变量取消类型属性-p
显示指定变量的被声明的类型-i
将变量声明为integer
整数类型-x
将变量声明为环境变量
数值运算 方法1
用
declare -i
声明数值类型
数值运算 方法2
调用expr数值运算工具
cc=$(expr $aa + $bb)
加号+
两边需要有空格
这里是把expr $aa + $bb
命令结果赋值给变量cc
所以要使用$()
括起来
数值运算 方法3
$((运算式))
或$[运算式]
常用$((运算式))
运算符
优先级值越大越优先
优先级 | 运算符 | 说明 |
---|---|---|
13 | -,+ | 单目负,单目正 |
12 | !,~ | 逻辑非,按位取反或补码 |
11 | *,/,% | 乘,除,取模 |
10 | +,- | 加,减 |
9 | <<,>> | 按位左移,按位右移 |
8 | <=,>=,<,> | 小于或等于,大于或等于,小于,大于 |
7 | ==,!= | 等于,不等于 |
6 | & | 按位与 |
5 | ^ | 按位异或 |
4 | | | 按位或 |
3 | && | 逻辑与 |
2 | | | 逻辑或 |
1 | =,+=,-=,*=,/=,%=,&=,^=,|=,<<=,>>= | 赋值,运算且赋值 |
运算符示例
全部写在$((运算式))
或$[运算式]
变量测试与内容替换
变量置换方式 | 变量y没有设置 | 变量y为空值 | 变量y设置值 |
---|---|---|---|
x=${y-新值} | x=新值 | x为空 | x=$y |
x=${y:-新值} | x=新值 | x=新值 | x=$y |
x=${y+新值} | x为空 | x新值 | x=新值 |
x=${y:+新值} | x为空 | x为空 | x=新值 |
x=${y=新值} | x=新值,y=新值 | x为空,y值不变 | x=$y,y值不变 |
x=${y:=新值} | x=新值,y=新值 | x=新值,y=新值 | x=$y,y值不变 |
x=${y?新值} | 新值输出到标准错误输出(就是屏幕) | x为空 | x=$y |
x=${y:?新值} | 新值输出到标准错误输出 | 新值输出到标准错误输出 | x=$y |
- 示例
x=${y-新值}
x=${y-新值}
与x=${y:-新值}
区别
环境变量配置文件
- 环境变量可在父Shell,子Shell任何地方执行
- 环境变量设置重启之后就不会再起作用
- 永久有效需写入配置文件
source命令
环境变量配置文件更改后需重启生效
可以使用source
命令使其直接生效
source 配置文件
或. 配置文件
简介
环境变量配置文件中主要定义对
系统的操作环境生效的系统默认环境变量
比如PATH
路径PS1
提示符HISTSIZE
历史记录保持数HOSTNAME
主机名等默认环境变量
- 对所有用户都生效
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
- 对用户自己生效 如果是root用户~就为
/root
否则/home/用户名
~/.bash_profile
~/.bashrc
作用
流程图
已登录,未登录
- 已登录
- 需输入
用户名
密码
- 流程1 2 3 4 5 6 7 8
- 需输入
- 未登录
- 无需输入
用户名
密码
- 7 2 3 4 8
- 无需输入
流程分析
USER
LOGNAME
MAIL
PATH
HOSTNAME
HISTSIZE
umask
调用文件
/etc/profile.d/*.sh
和/etc/profile.d/sh.local
执行完毕
会执行
~/.bash_profile
文件
其他配置文件和登录信息
注销是生效的环境变量配置文件
~/.bash_logout
其他配置文件
~/.bash_history
历史命令配置文件,注销之后才会写入
系统出问题进行排查错误会用到
Shell登录信息
/etc/issue
本地终端
欢迎信息(例如VMware登录)
转义符 | 作用 |
---|---|
\d |
当前系统日期 |
\s |
操作系统名称 |
\l |
登录的终端号,这个比较常用 |
\m |
显示硬件体系结构,如i386 i686 |
\n |
主机名 |
\o |
域名 |
\r |
内核版本 |
\t |
当前系统时间 |
\u |
当前登录用户的序列号 |
/etc/issue.net
远程终端
欢迎信息(例如Xshell6登录)
- 在
/etc/issue.net
中不能使用转义符 - 显示欢迎信息生效
- 默认显示
- 修改配置文件
- 重启服务
- 修改之后
- 默认显示
/etc/motd
登录后的欢迎信息
不管是本地还是远程登录,都可以显示此欢迎信息
Shell编程
正则表达式
正则表达式与通配符
正则表达式
- 在文件中匹配符合条件的字符串
grep
awk
sed
等支持正则- 包含匹配
通配符
- 匹配符合条件的文件名
*
(0个或多个)?
(一个字符)[]
(其中写的任何一个字符)ls
find
cp
不支持正则,所以需要使用Shell自己的通配符来匹配- 完全匹配
测试正则
原内容
a*
匹配所有内容,包括空白行
boo*
b.*t
^$
^[^a-zA-Z]
表示不以字母开头的行
字符截取命令
cut
提取列
-f
列号,提取第几列-d
分隔符,安装指定分隔符分割列结合
grep
printf
输出不换行,可配合awk使用
输出类型
%ns
输出字符串,n表示输出几个字符%ni
输出整数,n表示输出几个数字%m.nf
输出浮点数,m和n是数字,表示输出的整数位数和小数位数- 例如
%8.2f
代表输出8位数,其中6位整数,2位小数
- 例如
输出格式
\a
输出警告声音\b
输出退格键,也就是Backspace键\f
清除屏幕\n
换行\r
回车,也就是Enter键\t
水平输出退格键,也就是Tab键\v
数值输出退格键,也就是Tab键
示例
awk
列截取
注意点
- awk支持print与printf
- print输出会自动加换行符,Linux默认无print命令
- printf输出不会加入换行符,要换行需手动加
- cut命令不能按空格分隔,awk可以,awk包含cut功能
语法
awk '条件1{动作1} 条件2{动作2} ...' 文件名
默认分隔符 空格或制表符
表示符合条件1执行动作1,符号条件2执行动作2…
条件 > 例如x>10
x>=10
x<=10
动作 > 格式化输出,流程控制语句
基本用法
$0代表一行,$1 $2 …代表第1 2列
BEGIN
执行之前执行
指定分隔符的时候使用,因为第一行不会使用指定的分隔符
END
所有执行之后执行
条件运算符
sed
是一种轻量级流编辑器,可用来数据选取,替换,删除,新增的目录
一般要把cat查询的内容写入文件要使用>或>>写入重定向的方式,再对文件进行vi修改其内容
sed可以直接对cat结果进行修改
sed 选项 '动作' 文件名
- 注意:动作要使用
'
单引号,只有使用-i
选项才会改变原文件内容 - \反斜杠表示追加,命令未结束
- 选项
-n
不加会把数据和sed处理的数据一起输出,加了会只输出sed命令处理的数据-e
允许对输入数据应用多行sed命令-i
用sed的修改结果自己修改读取数据的文件,而不是由屏幕输出
示例:把文件中的no改为yessed -i 's/PermitRootLogin no/PermitRootLogin yes/g' /etc/ssh/sshd_config
- 动作
a
追加,在当前行后添加一行或多行,添加多行时,除最后一行,每行尾都要用\反斜杠代表数据未完结c
行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行,每行尾都要用\反斜杠代表数据未完结i
插入,在当前行前插入一行或多行,插入多行时,除最后一行,每行尾都要用\反斜杠代表数据未完结d
删除,删除指定行p
打印,输出指定行s
字符串替换,用一个字符串替换另一个字符串,格式为s/旧串/新串/g
字符处理命令
排序命令sort
sort 选项 文件名
-f
忽略大小写-r
反向排序-t
指定分隔符,默认制表符-k n[,m]
按照指定字段范围排序,从第n字段开始,m字段接收(默认到行尾)-n
以数值进行排序,默认按照字符串排序
统计命令wc
wc 选项 文件名
-l
只统计行数-w
只统计单词数-m
只统计字符数
条件判断
按照文件类型判断
测试选项 | 作用 |
---|---|
-b | 判断文件是否存在,并判断是否为块设备文件,是块设备文件为真 |
-c | 判断文件是否存在,并且是否为字符设备文件,是字符设备文件为真 |
-d |
判断文件是否存在,并且是否为目录文件,是目录为真 |
-e |
判断文件是否存在,存在为真 |
-f |
判断文件是否存在,并且是否为普通文件,是普通文件为真 |
-L | 判断文件是否存在,并且是否为符号链接文件,是符号链接文件为真 |
-p | 判断文件是否存在,并且是否为管道文件,是管道文件为真 |
-s | 判断文件是否存在,并且是否为非空,非空为真 |
-S | 判断文件是否存在,并且是否为套接字文件,是套接字文件为真 |
判断格式
test -e /root/anaconda-ks.cfg
- 常用
[ -e /root/anaconda-ks.cfg ]
按照文件权限判断
测试选项 | 作用 |
---|---|
-r |
判断该文件是否存在,并且该文件是否拥有读权限(ugo任何一个有读权限为真) |
-w |
判断该文件是否存在,并且该文件是否拥有写权限(ugo任何一个有写权限为真) |
-x |
判断该文件是否存在,并且该文件是否拥有执行权限(ugo任何一个有执行权限为真) |
-u | 判断该文件是否存在,并且该文件是否拥有SUID权限(ugo任何一个有SUID权限为真) |
-g | 判断该文件是否存在,并且该文件是否拥有SGID权限(ugo任何一个有SGID权限为真) |
-k | 判断该文件是否存在,并且该文件是否拥有SBit权限(ugo任何一个有SBit权限为真) |
两个文件进行比较
测试选项 | 作用 |
---|---|
文件1 -nt 文件2 |
判断文件1的修改时间是否比文件2的新(如果新为真) |
文件1 -ot 文件2 |
判断文件1的修改时间是否比文件2的旧(如果旧为真) |
文件1 -ef 文件2 |
判断文件1和文件2的i节点(ls -i)是否一致,可以判断是否为同一个文件,用来判断硬链接 |
两个整数进比较
测试选项 | 作用 |
---|---|
整数1 -eq 整数2 |
整数1 == 整数2 |
整数1 -ne 整数2 |
整数1 != 整数2 |
整数1 -gt 整数2 |
整数1 > 整数2 |
整数1 -ge 整数2 |
整数1 >= 整数2 |
整数1 -lt 整数2 |
整数1 < 整数2 |
整数1 -le 整数2 |
整数1 <= 整数2 |
字符串的判断
测试选项 | 作用 | 示例 |
---|---|---|
-z 字符串 |
判断是否为空(为空返回真) | |
-n 字符串 |
判断是否不为空(不为空返回真) | |
字符串1 == 字符串2 |
判断字符串1是否和字符串2相等(相等返回真) | |
字符串1 != 字符串2 |
判断字符串1是否和字符串2不相等(不相等返回真) |
多重条件判断
测试选项 | 作用 | 示例 |
---|---|---|
判断1 -a 判断2 | 逻辑与,1 2 都成立才为真 | |
判断1 -o 判断2 | 逻辑或,1 2 一个成立就为真 | |
! 判断 | 逻辑非,使原始的判断取反 |
流程控制
if语句
单分支if条件语句
- 写法1,常用
1
2
3if [ 条件判断式 ];then
程序
fi - 写法2
1
2
3
4if [ 条件判断式 ]
then
程序
fi - 注意事项
- 开头是if 结尾是fi
- 条件判断式和中括号两边有空格
- 两种写法
双分支if条件语句
1 | if [ 条件判断式 ] |
- 示例1
- 示例2
多分支if条件语句
1 | if [ 条件判断式1 ] |
case语句
1 | case $变量名 in |
for循环
语法1
1 | for 变量 in 值1 值2 值3 ... |
- 示例1
- 示例2
语法2
1 | for((初始值;循环控制条件;变量变化)) |
- 示例1
- 示例2
while循环
1 | while [ 条件判断式 ] |
until循环
与while相反,表示不满足才循环