硬链接相当于给磁盘中的那个文件新添加一个引用对象,类似在给变量赋值的时候变量名这个标识符引用了内存中的一块数据然后又那个变量名引用了同样的一块数据
软链接相当于新创建了一个文件,这个文件关联到了被链接到的文件名
硬链接和软链接的区别
1,硬链接相当于同一个文件,软链接不是同一个文件
2,硬链接不能跨分区和磁盘,软链接可以
3,硬链接不能链接目录,软链接可以
4,硬链接删除源文件对链接文件没有影响,软链接删除源文件后链接文件就无法访问了
linux发行版中创建用户的一些默认设置都在/etc/default/useradd,创建用户后在用户的家目录下自动生成的一些数据都是源于/etc/skel/下
rhel linux发行版系列的rpm软件包在安装时执行的脚本可以通过rpm -q --scripts 软件名 来查询
newgrp 临时切换用户的主组
chsh 设置用户的shell
finger 查看用户的一些信息
chfn 修改用户的描述信息
stat 查看文件的一些meta data信息
cat -E 显示行结束符
-A 显示所有控制符
-n 显示行号
-b 显示非空行号
-x 压缩连续的空行为一行
tac 逆向显示内容
nl 查看文本对非空行显示行号(相当于cat -b)
rev 对文本中的行做逆序显示
hexdump -C -n 512 /dev/sda 以16进制的方式去显示/dev/sda这个块文件的前512字节
od 和xxd都可以
more 分页查看文本,回车一行行翻,空格整页翻
less 分页查看文本,回车一行行翻,空格整页翻,Pgup往前翻页,Pgdn往后翻页
head 显示文件前n行 -n指定行号,-c指定字节
例如取随机数的前10个字节:cat /dev/urandom|tr -dc '[:alnum:]'|head -c 10
tail 显示文件的后几行 -n指定行号,-c指定字节
-f实时追踪显示文件新追加的内容,以文件的fd为目标追踪,相当于--follow=descriptor,文件删除后将无法跟踪
-F追踪文件名,以文件名为目标,相当于--follow=name --retry,文件删除后再创建同路径同名的文件可以继续跟踪
tailf 相当于tail -f
cut 按列抽取文本 -d delimiter:指定列的分隔符,默认为空格
-f fileds:抽取第几列,例如1,2取出1和2列,1-3取1到3列
-c 按字符取
--output-delimiter=string 指定输出分隔符
paste 横向合并同行号的多个文件
-d 指定输出分隔符
-s 所有行显示成一行,如果合并就成纵向合并了
wc 统计行号,单词数(空格隔开),字节等
-l 行号
-m 字符数
-w 单词数
-c 字节数
-L 长度最长的行
sort 排序
-n 按数字排序(默认按字符)
-r 倒序排序
-R 随机排序
-t 指定分隔符,一般和-k搭档
-k 指定排序的列字段,一般与-t搭档
-u 删除输出中的重复行(去重)
uniq 去重(连续的相同行)
-c 显示连续重复行出现的次数
-d 仅显示连续重复过的行
-u 仅显示连续不曾重复过的行
diff file1 file2... 比较文件区别
-u 输出"统一的(unified)"diff格式文件,最适用于补丁文件
patch 复制在其他文件中进行的改变(通过diff比较2个文件最终的区别文件来得到其中一个文件)
-b 备份
cmp 比较二进制文件的区别(不同)
set +C 禁止文件覆盖
特殊权限
SUID
在一个可执行二进制程序的所有者权限位上设置则代表任意用户(前提是对此二进制程序有执行权限)去执行这个程序的时候的进程的所有者则是该二进制程序的所有者,
例如passwd这个二进制可执行程序是用来修改用户密码的,就是改了/etc/shadow文件,普通用户也能通过这个命令修改自己的密码,但是普通用户对shadow文件没有写权限,
他是怎么能修改的呢,就是因为这个passwd命令有suid权限,所以普通用户在执行这个命令来修改密码的时候所启的进程所有者是这个命令的所有者,也就是root,而root对这个文件有修改的权限,
简单来说就是设置了这个权限的命令,任何对这个命令有执行权限的用户去执行他,进程的运行用户就是这个命令的所有者,如果一般不设置,运行这个程序使他启的`进程的所有者一般都是执行者
Usage:
chmod u+s file
用8进制数字表达就是4,例如二进制程序原来的权限是755,给他设置suid就是
chmod 4755 file
SGID
给二进制程序设置:执行这个二进制程序所启动的进程的用户组则是二进制程序的所有组
给目录设置:任何用户在这个目录里面创建的所有文件或目录的所属组都是此目录的属组
Usage:
chmod g+s file or directory
chmod 2755 file or directory
Sticky
即使用户对目录有写权限,任何用户在这个目录里面创建的文件或目录都只能是自己删除,root除外
Usage:
chmod o+s directory
chmod 1777 directory
特殊属性
chattr +i file or directory
给文件设置i属性件将不能够修改,改名等(root也不例外)
给目录设置i属性或目录都不能被删除(文件能修改数据,只是不能被删,这个目录下的子目录下的文件能删)
chattr -i file or directory 取消属性
chattr +a file or directory
给文件设置a属性后这个文件只能被追加数据,不能删除或修改
给目录设置a属性后可在个目录下创建文件或目录
chattr -a file or directory 取消属性
acl(Access Control List)
可以对用户和组单独设置权限,不限制与属主属组其他人的三种权限
setfacl -m u:username:mode file|irectory
setfacl -m g:groupname:mode file|irectory
setfacl -Rm u|g:username|groupname:mode file|irectory #-R是递归
例如给用户itovz设置对/etc/shadow有读写权限
setfacl -m user:itovz:rw /etc/shadow
取消权限
setfacl -m user:itovz:- /etc/shadow 或把权限位设置为0
getfacl file or directory
备份acl属性
getfacl -R file or directory >file
还原
setfacle -R --set-file=file(指定备份acl属性的文件) file or directory
locate 搜索文件
locate维护的有一个文件索引数据库,记录着硬盘里面所有文件的路径,updatedb手动生成这个数据库文件(不手动生成,一段时间后会自动创建)
查找速度快
模糊搜索
非实时搜索
常用选项:
-i 不区分大小写
-n N只列举前N个匹配项目
-r 使用基本正则表达式
find 实时查找,遍历指定目录来完成文件查找
查找速度略慢
vim
命令行模式中的快捷键
h 左移
j 下移
k 上移
l 右移
ZZ 保存退出
ZQ 不保存退出
w 下一个单词的词首
^ 整行的非空位置
0 整行的行首位置
$ 整行的行尾位置
gg 跳转到第一行
G|1G 跳转到最后一行
~ 转换大小写
x 删除光标处的字符
yy 复制当前光标所在行
#yy 复制多行
dd 剪切光标处的行
#dd 多行剪切
d$ 剪切光标处到行尾的位置
d^ 剪切光标处到前面非空的位置
d0 剪切光标处到行首的位置
dG 删除当前行到末尾行
p 粘贴
/string 向下搜索string
?string 向上搜索string
u 撤销之前做的修改操作
U 对当前行的所有操作做撤销
ctrl+r 对前一次的撤销做恢复
di" 删除双引号中的数据
扩展命令模式
地址定界
:1,3d 删除1-3行
:%d 删除全文 %代表全文
:1,3y 复制1-3行的数据
:3r xyz 在第三行后读入xyz这个文件
:3r! ls 将ls命令的结果读入到第三行后
:地址定界s/查找的内容/替换的内容/修饰符
/可替换成#,@等特殊符号
修饰符
i 忽略大小写
g 全局替换,默认情况下,每一行只替换首次出现的
c 替换前询问是否替换
可视化选择
v 面向字符选择
V 面向整行
ctrl+v 面向块
可视化可用于移动键结合使用
突出显示的文字可复制,删除,搜索,替换等
在文件行首插入
输入ctrl+v 进入可视化模式
选择到需要在哪些行插入
输入I进入插入模式
输入想插入的字符,例如#
再按ESC
多文件模式
vim file file2...
:next 下一个
:first 第一个
:prev 前一个
:last 最后一个
:wall 保存所有
:qll 不保存所以并退出
:wqall 保存所有并退出
多窗口模式
vim -o file 水平分割
vim -O file 垂直分割
窗口间切换:ctrl+w 方向键
单窗口模式
ctrl+w,s:split,水平分割
ctrl+w,v:vertical,垂直分割
ctrl+w,q:取消相邻窗口
ctrl+w,o:取消全部窗口
vim的寄存器(剪切板)
26个命名寄存器和一个无名寄存器,可以不同会话键共享
寄存器名称a-z,格式"寄存器名称 放在数字和命令之前
例如:3"ayy 复制三行到a寄存器里面,粘贴就是"ap
如果未指定,使用的则是无名寄存器,也就是默认的
10个数字寄存器,0-9,0存放最近复制的内容,1存放最近删除的内容.当性的文本变更和删除时,1转存到2,2转存到3,以此类推,数字寄存器不能在不同会话间共享
标记和宏(macro)
ma 将当前位置标记为a,26个字母均可作为标记名,mb.mc等
'a 跳转到a标记的位置
qa 录制宏a,a为宏的名称
q 停止录制
@a 执行宏a
@@ 重新执行上次执行的宏
编辑二进制文件
vim -b binaryfile 二进制方式打开
:%!xxd 将全文转换成十六进制
:%!xxd -r 转换回二进制
定制vim的工作特性
配置文件:永久生效
全局:/etc/vimrc
个人:~/.vimrc
显示行号:set number,简写set nu
取消显示行号:set nonumber,简写set nonu
忽略字符大小写:set ignorecase,简写set ic
不忽略:set noignorecase,简写set noic
自动缩进:set autoindent,简写set ai
禁用:set noautoindent,简写set noai
复制保留格式:set paste
禁用:set nopaste
显示tab(^I)和换行符($):set list
取消显示:set nolist
高亮搜索:set hlsearch
取消:set nohlsearch
语法高亮:syntax on
取消:syntax off
启用Windows文件格式:set fileformat=dos
启用Unix格式:set fileformat=unix
简写:set ff=unix|dos
设置文本宽度:set textwidth=65(vim only)
set warpmargin=15
设置光标所在行的下划线:set cursorline,简写set cul
禁用:set nocursorline
正则
REGEXP:Regular Expressions,由一些特殊字符及文本字符所编写的模式,
其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能
正则表达式分两类:
基本正则:BRE
扩展正则:ERE
表达式引擎:
采用不同的算法,检查处理正则表达式的软件模块,如:PCRE(Perl Complatible Regular Expressions)
正则表达式的元字符分类:字符匹配,匹配次数,位置锚定,分组
字符匹配
. 匹配任意单个字符
[] 匹配指定范围内的单个字符,示例:[abc],[0-9],[a-z],[a-zA-Z]
[^]匹配指定范围外的单个字符
[:lower:] 小写字母,相当于a-z
[:upper:] 大写字母
[:alpha:] 大小写字母
[:digit:] 十进制数字
[:xdigit:] 十六进制数字
[:alnum:] 字母和数字
[:blank:] 空白字符(空格和制表符)
[:spache:] 水平和垂直的空白字符(比[:blank:]包含得更广)
[:cntrl:] 不可打印的控制字符(退格,删除,警铃...)
[:graph:] 可打印的非空白字符
[:print:] 可打印的字符
[:punct:] 标点符号
匹配次数
用于指定次数的字符后面,指定前面的字符出现的次数
* 代表前面的字符匹配任意次(>=0),贪婪匹配:尽可能长的匹配
.* .和*组合起来就是匹配任意长度的任意字符
\?匹配其前面的字符0次或1次(>=0 &&=2),如果使用扩展正则\可以不加
\+匹配其前面的字符1次或多次(>=1),使用扩展正则\可不加
\{n\}匹配其前面的字符n次(=n),使用扩展正则\可不加
\{n,\}匹配其前面的字符至少n次(>=n),使用扩展正则\可不加
\{,n\}匹配其前面的字符至多n次(<=n),使用扩展正则\可不加
\{m,n\}匹配其前面的字符至少m次,至多n次(>=m && <=n),使用扩展正则\可不加
位置锚定
位置锚定可以用于定位string出现的位置
^ 行首锚定,用于模式的最左侧,例如^a,a一定在行首
$ 行尾锚定,用于模式的最右侧,例如b$,b一定出现在行尾
^$ 空行
^[[:space:]]*$ 空白行
\<或\b 词首锚定,用于单词模式的左侧
\>或\b 词尾锚定,用于单词模式的右侧
\<PATTREN\> 匹配整个单词
分组\(\),扩展正则可省略\
\(\)将一个或多个字符捆绑在一起,当做一个整体处理,如:\(root\)+,就是root这个整体字符串出现1次或多次
分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1,\2,\3...
\1表示从左侧第一个左括号与之匹配右括号之前的模式所匹配到的字符,可用&代替
Usage:
\(string1\)
\1匹配到的就是string1
后向引用:引用前面的分组括号中的所匹配到的字符,而非模式本身
或者:\|(扩展正则可省略\)
Usage:
a\|b 匹配到的是a或b
^\(a\|b\) 匹配开头为a或b,a和b在分组里面,之前隔着\|代表或,这个分组里面的内容就是a或b,然后和前面的^结合就是^a\|^b了
\(l\|L\)inux 匹配到的是Linux或者linux,我们先把l和L放在了分组里面,代表他们是一组,但是用|隔开了,代表这个分组里面匹配到的是l或者是L,
然后和后面的inux结合
零宽断言(pcre)
...
grep 主要对文件的(正则表达式)行基于模式进行过滤
grep:Global search Regular expression and print out the line
作用:文本搜索工具,根据用户指定的"模式"对目标文件逐行进行匹配检查;打印匹配到的行
模式:由正则表达式及文本字符所编写的过滤条件
grep [options] pattern [file]...
-m n匹配到了n行就不匹配了
-v 显示不被pattern匹配的行
-i 忽略大小写
-n 显示匹配到的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串
-q 静默默认(不输出任何信息)
-A n after,后n行
-B n before,前n行
-C n context,前后各n行
-w 匹配整个单词(相当于词首尾锚定了)
-E 使用ERE扩展正则,相当于egrep
-F 相当于fgrep,不支持正则
-f file 根据模式文件处理,例egrep -f patternfile file
-r 递归搜索目录下的每个文件里面的内容,不处理软链接
-R 递归搜索目录下的每个文件里面的内容,处理软链接
-l 仅打印匹配项的文件名称,目标是多个文件时使用
-e 多个选项间的逻辑or关系,如:grep -e 'cat' -e 'dog' file
shell编程(过程式,解释执行)
面向过程:以指令为中心,数据服务于指令
面向对象:以数据为中心,指令服务于数据,例如java,python等
低级编程语言:
机器:0or1
汇编:接近于自然语言
高级编程语言:
编译:源代码-->编译器-->机器代码-->执行
解释:源代码-->执行-->解释器-->机器码,例如:shell,python,perl等
程序处理的流程:
顺序执行
按条件执行(选择执行,流程控制,分支)
循环执行
shell编写
开头
#!/bin/bash
指定shebang机制(必须在文件的第一行)
/bin/bash是shell的解释器,解释性语言都可以指定这个,这样程序在执行的时候就是以这个解释器执行
#号代表注释,除了第一行中的shebang里面的#
执行,加上执行权限
chmod +x script
./script
或直接指定解释器执行(优先级比shebang指定的解释器高)
bash script
bash -n script 仅检查脚本语法错误
bash -x script 调试执行脚本
变量
变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据
变量类型:
内置变量:PS1,UID,PATH,SHELL...
用户自定义变量
不同的变量的数据不同,决定了
1.数据存储方式
2.参与的运算
3.表示的数据范围
变量数据类型:
字符
数值:整型,浮点型(shell默认不支持)
静态和动态语言
静态编译语言:使用变量前<先声明变量类型
动态编译语言:不用事先声明,可随时改变类型
强类型和弱类型
强类型:不同类型数据操作,必须经过强制转换同一类型才能运算,如java,python...
Python: print('a'+1) 报错,a是string,1是integer
print('a'+'1') or print('a'+str(1)) 结果为a1,1已经被显式转换成string了
弱类型:语言的运行时会隐式做数据类型转换,无需指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无需事先定义可直接调用,如php,javascript,bash...
JavaScript: console.log('a'+1) 结果为a1,无需显式转换
shell变量命名规则
不能使用程序中的保留关键词,例如:function,if,else,for,while等
只能使用数字,字母,下划线,且不能以数字开头,尽量不要使用下划线开头
见名知意
驼峰命名
环境变量名大写
普通变量小写
函数名小写
变量定义和引用
变量的生效范围等标准划分变量类型
普通变量:生效范围为当前shell进程
环境变量:生效范围为当前shell进程以及其下面的所有shell进程(shell子进程设置的环境变量其父进程不能生效)
本地变量:生效范围为当前shell进程中某代码片段,通常指函数
变量赋值
variable_name=value
value可是普通字符串,也可是命令替换得到的结果,还可以引用其他变量的value
变量引用
$name
${name} 加了大括号和不加大括号的结果是没有区别的,但是在环境比较复杂的情况下,比如输出一段文字,
echo "$namexyz" 我们想输出$name的value加上xyz这个string,但是在处理变量的时候,会把$namexyz这个变量做替换,
而不是$name,所以我们现在需要echo "${name}xyz",这样才正确,我们把变量name的位置启停给扩起来了,内部做变量替换的时候只会替换name
弱引用和强引用
"$name" 弱引用,其中的变量可被替换成变量值
'$name' 强引用,其中的变量不会被替换,被当成普通字符串处理
set 显示所有变量和函数...
export|env|printenv|declare -x 显示环境变量
unset name 删除变量或函数
环境变量
export name or export name=value
declare -x name or declare -x name=value
特殊环境变量:
$_ 前一个命令的最后一个参数
只读变量(只能读)
readonly only_env=value
系统中的只读变量:$UID...
显示只读变量:declare -r|readonly
位置变量
在bash shell中内置的变量(不止bash),在脚本代码中调用通过命令行传递给脚本的参数
$1,$2,...对应第一个,第二个...参数,shift [n]换位置
例如有一个脚本args.sh,脚本内容为
#!/bin/bash
echo $1
这就是打印第一个参数
执行就是bash args.sh argument1 or ./args.sh argument1
打印的结果就是argument1
$0 命令,程序名本身
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数
注意: $*,$@只在被双引号包起来循环的时候才会有差异
清空所有位置变量: set --
退出状态码变量
进程执行后,将使用变量$?保存状态码的相关数字,不同的值反应成功或失败,$?取值为0-255
$?的值为0 代表成功(一般情况下)
$?的值>=1 代表失败(一般情况下)
注意:
脚本中一旦遇到了exit [n],脚本会立即停止;终止退出状态取决于exit后面的数字
如果为给定脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
展开命令行
命令执行顺序
把命令行分成单个命令词
展开别名
展开大括号的声明{}
展开波浪号声明~
命令替换$()和``
再次把命令行展开为命令词
展开文件通配符(*,?,[abc]...)
准备i/o重定向>,<
运行命令
防止扩展
反斜线\使随后的字符串按原意解释
例如打印$xyz这个string,默认前面加$就会当做变量处理,我们现在可以
echo '$xyz' 等同于 echo "\$xyz"
set:可用来定制shell环境
$-变量
h:hashall,打开选项后,shell会将命令所在的路径hash下来,避免每次都要查询,通过set +h将h选项关闭
i:interactive-comments,包含这个选项说明当前的shell是一个交互式的shell,在脚本中,i选项是关闭的
m:monitor,打开监控模式,就可以通过job contro;来控制进程的停止,继续,后台或者前台执行等
B:braceexpand,大括号扩展
H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如'!!'返回上最近的一个历史命令,"ln"返回第n个历史命令
set命令实现脚本安全
-u 再扩展一个没有设置的变量时,显示错误信息,等同于set -o nounset
-e 如果一个命令返回一个非0退出状态值(失败)就退出,等同set -o errexit
-o options显示,打开或关闭选项
显示选项:set -o
打开选项:set -o option
关闭选项:set +o option
-x 执行命令时,打印命令及其参数,跟踪执行过程
算术运算
+,-,*,/,%取模(取余),**乘方
实现算术运算
let var=算术表达式
var=$[算术表达式]
var=$((算术表达式))
var=$(expr arg1 arg2 ...)
declare -i var=算术表达式
echo '算术表达式'|bc
简单说下加减法在cpu中运算
计算机中存储的都是二进制,存储的是补码,正整数和负数都有一个标记位,正数最高位为0,负数为1
计算机中有原码,反码和补码
原码
5 --> 0b101,1 --> 0b1,-1 --> -0b1
反码
正数的反码就是原码,负数的反码符号位不变,其他位取反
补码
正数的补码就是原码,负数的反码符号位不变,其他位按位取反+1
负数的表示法
早期数字电路cpu中的运算器实现了加法器,但没有减法器,要实现减法就要转换成加法
例如:
3-1=3+(-1)
例:
加法:+3
把2和3分别先转换成二进制的原码就是
2 --> 0000 0010 由于内存中存储的最小单位是字节,一字节是8位,所以我们这里直接凑成8位,最高位是0,因为是正整数
3 --> 0000 0011
我们这计算应该用的是补码,由于我们这都是正数,正数的原码就是补码,所以我们现在就可以直接运算
00000010
00000011
00000101
=5
所以2+3=5
减法:5-2
转换成加法 5+(-2)
5 --> 00000101
-2 --> 10000010 由于我们这是负数所以最高位为1
-2还需要转换一下,现在还只是原码,我们再转化成补码
10000010
11111110 符号位不变,其他按位取反后加1
现在5的补码是00000101,-2的补码是11111110,相加
00000101
11111110
100000011 计算后的结果,还有个溢出位1,去掉溢出位就是结果了
00000011
=3
最终的结果就是3
内建的随机数生成变量:$RANDOM(范围在0-32767)
增强型算术运算赋值
+=
-=
/=
*=
自增,自减
i++ or ++i 相当于i=i+1
i-- or --i 相当于i=i-1
先++或--和后++或--是有区别的
例如:
i=0
echo $((i++))
第一次echo返回的结果是0,也就是还没有运算前的结果,然后打印i这个变量才是1
i=1
echo $((++i))
第一次就返回2,先进行运算后再返回结果
简单来说就是++在后先赋值后运算,在前就是先运算后赋值
逻辑运算
布尔值:true(1),false(0)
与:&(shell中用&&表示)
1 & 1=1
0 & 1=0(可形成短路与)
0 & 0=0(短路与)
或:|(shell中用||表示)
1 & 0=1(可形成短路或)
0 & 1=1
0 & 1=1
非:!
!1=0
!0=1
异或:^
异或的两个值,相同为假,不同为真
例如两变量的值就可利用这一特性做互换
a=1;b=2
a b
0001 0010
0001
0010
0011
现在0011就是他们互与等到的结果(差值)
这个差值再和a|b与就能得到b|a
a=1;b=2;a=$((a^b));b=$((a^b));a=$((a^b));echo $a,$b
解析一下:
先给a,b两个变量分别赋值为1,2
再把a与b的结果赋给a变量,现在a变量就拥有了a与b的差值,这个差值和b与就能得到a,所以这里b=$((a^b))
现在b的结果是a之前的了,现在a变量的数据还是那个差值,现在我们想求出之前的b值,就需要a=$((a^b)),
因为在上面的表达式a^b中,b已经是之前a的内容了,所以差值再和b与就能得到b的初始值
短路运算
短路与
第一个为0,结果必为0
第一个为1,第二个也需要参与运算
短路或
第一个为1,结果必为1
第一个为0,第二个必须参与运算
位与
数值转换成二进制按位运算,都为1为1,有0则0
位或
数值转换成二进制按位运算,有1则为1,无1则为0
条件测试命令
判断某条提案是否成立
评估布尔值声明
若真,则状态码变量$?返回0(true)
若假,则状态码变量$?返回!0(false)
注意:这里的状态码不是布尔值,而是shell里面自己的属性,返回0则相当于true成立,非0则相当于false
test expression
[ expression ]
前两者基本上除了格式以外没什么区别
[[ expression ]]
上面这种支持更强大的功能,必须正则
注意:expression前后必须带有空格
变量测试
-v var 测试变量是否存在
test -v var
数值测试
-lt 小于
-le 小于等于
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于
例如: test 1 -lt 2 or [ 1 -lt 2 ]
字符串测试
-z 'string' 字符串是否为空,空为真
-n 'string' 字符串是否非空,非空为真,默认就是-n
'string' = 'string' 是否等于
'string' > 'string' ascii码是否大于
'string' < 'string' 是否小于
'string' == pattern 左侧字符串是否符合右侧pattern(pattern为通配符,用于[[]])
'string' != pattern 左侧字符串是否不符合右侧pattern(用于[[]])
'string' =~ pattern 左侧字符串是否不符合右侧pattern(pattern为扩展正则表达式,用于[[]])
注意:这里的pattern不要加引号
例如:
[[ 'a.txt' == *.txt ]]
[[ 'a.txt' =~ \.txt$ ]]
文件测试
-a file 如果存在则为真,同-e
-e file 存在则为真,同-a
-b file 存在且为块设备文件则为真
-c file 存在且为字符设备文件则为真
-d file 存在且为目录文件则为真
-f file 存在并且是一个普通文件
-h file 存在且为符号链接文件则为真,同-L
-L file 存在且为符号链接文件则为真,同-h
-p file 存在且为命名管道文件则为真
-S file 存在且为套接字文件则为真
文件权限测试
-r file 存在并且可读为真
-w file 存在且可写为真
-x file 存在且可执行为真
-u file 存在且拥有suid权限则真
-g file 存在且拥有sgid权限则真
-k file 存在且拥有sticky权限则真
文件属性测试
-s file 存在且非空
-t fd 文件描述符是否在某终端已打开
-N file 文件自上次被读取后是否被修改
-O file 当前有效用户是否为属主
-G file 当前有效用户组是否为属组
file1 -ef file2 file1是否为file2的硬链接
file1 -nt file2 file1是否新于file2 (mtime)
file1 -ot file2 file1是否旧于file2
组合测试条件
第一种方式:
[ expression1 -a expression2 ] 并且
[ expression1 -o expression2 ] 或者
[ ! expression ] 取反
第二种方式:
[[ expression1 && expression2 ]] 并且,短路与,代表条件性的AND THEN
[[ expression1 || expression2 ]] 或者,短路或,代表条件性的OR THEN
[[ ! expression ]] 取反
第三种方式:
[ expression1 ] && [ expressin2 ]
[ expression1 ] || [ expressin2 ]
上述的也可替换成[[]]
()和{}
在小括号内的命令会开启子shell去执行
在花括号内的还在当前shell
read命令可以接受用户键盘标准输入的数据并赋给变量(没有指定变量,默认赋给$REPLY)
read [options] [name...]
-p 指定要显示的内容
-s 静默输入显示,一般用于密码
-n N 指定输入的字符长度为N
-d 'string' 输入结束符
-t N TIMEOUT为N秒
错误示例:
echo 'test' | read var
打印出的变量var为空,按常理,read是支持标准输入的,但是为什么没有值呢,
那是因为他们之前用管道了,管道两侧的命令其实都运行在一个子进程里面,他们赋完值后回到父进程当然看不到了
echo test | { read var;echo $var;}
这样就能正常输出结果,我们用花括号把read和echo放在了一起
bash的配置文件
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:
~/.bash_profile
~/.bashrc
shell登录两种方式分类
交互式登录:
直接通过终端输入账号密码登录
使用su - username 登录
配置文件执行顺序:
/etc/profile --> /etc/profile.d/*/sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登录:
su username
图形环境下打开terminal
执行脚本
任何的其他的bash实例
配置文件执行顺序
/etc/profile.d/*.sh --> /etc/bashrc --> ~/.bashrc
. 或 source 将脚本里的指令在当前shell执行
~/.bash_logout 正常推出的情况下会执行这个配置里的数据(例如执行exit)
流程控制
条件判断
格式:
单分支
if condition;then
code...
fi
双分支
if condition;then
code...
else
code...
fi
多分支
if codition1;then
code...
elif codeition2;then
code...
elif codition3;then
code...
...
else
code...
fi
多个条件时,顺序进行条件判断,第一次遇到'真'时,执行其分支语句,而后结束整个if语句
if语句可嵌套
条件判断case语句
格式:
case variable in
PAT1)
code...
;;
PAT2)
code...
;;
...
*)
code...
;;
esac
打包压缩
compress
uncompress
gzip
-d 解压缩,等同于gunzip
-c 配合-d实现把解压后的内容输出到屏幕再结合>可输出到别的文件,这样就会保留之前的压缩文件,默认不加解压会删除压缩文件
-n n是压缩比,1-9,数字越大,压缩比越高
gunzip 解压gzip压缩文件
zcat 查看gzip压缩文件内容
bzip2
-d 解压压缩文件
-k 解压的时候不要删除原文
-n n是压缩比,1-9,数字越大,压缩比越高
bunzip2 解压bzip2压缩文件
bzcat 查看bzip2压缩文件内容
xz
-d 解压缩
-k 保留压缩文件
-n n是压缩比,1-9,数字越大,压缩比越高
上面几种只能压缩单个文件
zip
-r 压缩目录时加上此选项递归压缩文件
unzip 解压缩
tar
-c 打包
-x 解包
-v verbose
-f 指定打包后的文件
-t 预览打包文件里面的内容
结合压缩
-z gzip
-j bzip2
-J xz
Example:
tar -cvf etc.tar /etc
将/etc打包
tar -zcvf etc.tar.gz /etc
将/etc打包并使用gzip压缩
tar -xvf etc.tar.gz 将etc.tar.gz解压到当前路径
tar -xvf etc.tar.gz -C /tmp 解压到/tmp下