Linux云计算
Linux云计算
1.Linux基础
1.1 用户类型
root用户:一个特殊的管理账户,也被称为超级用户,root已接近完整的系统控制,对系统损害几乎有无限的能力,除非必要,不要登录为root
普通用户:(非特权)用户,权限有限,造成损害的能力比较有限。
1.2 终端
设备终端:键盘、鼠标、显示器。
1.2.1终端类型
- 控制台终端:/dev/console
- 串行终端:/dev/ttyS#
- 虚拟终端:tty:teletypewriters,/dev/tty#,tty可以有n个,Ctrl+Alt+F#
- 图形终端:startx,xwindows
- CentOS6:Ctrl+Alt+F7
- CentOS7:在哪个终端启动,即位于哪个虚拟终端
- 伪终端:pty:pseudo-tty,/dev/pts/#如:SSH远程登录
- 查看当前终端设备
\# tty
/dev/pts/0 #代表第一个图形终端
1.3 交互式接口
交互式接口:启动终端后,在终端设备附加一个交互式应用程序
1.3.1 交互式接口类型
- GUI:Graphic User Interface(图形用户界面)
- x protocol,window manager,desktop
- Desktop:
- GNOME(C,图形库gtk)
- KDE(C++,图形库qt)
- XFCE(轻量级桌面) - CLI:Command Line Interface(命令界面)
- Shell程序
1.4 什么Shell?

Shell是Linux系统的用户界面,提供了用户与内核进行交互的一种接口。它接收用户输入的命令并把它送入内核去执行
Shell也被称为LINUX的命令解析器(command interpreter)
Shell是一种高级程序设计语言
1.4.1 各种shell
-
sh:Steve Bourne
-
bash:Bourne-Again Shell,GPL,CentOS和Ubuntu默认使用
-
csh:c shell,C语言风格
-
tcsh
-
ksh:Korn Shell,AIX默认 shell
-
zsh:MacOS默认shell
-
bash shell
GNU Bourne-Again Shell(bash)是GNU计划中重要的工具软件之一,目前也是linux标准的shell,与sh兼容显示当前使用的shell
- 显示当前使用的shell
# echo $SHELL
/bin/bash
# echo ${SHELL}
/bin/bash
- 显示当前系统使用的所有shell
# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
- 设置主机名
hostname NAME
- 范例
注意:主机名不要使用下划线,因为不支持
# hostname 100.magedu.com
- 查看CPU
# lscpu
- 查看内存
free -h
- init命令
# init 3 #关闭图形界面
# init 0 #关机
# init 6 #重启
- 查看操作系统版本
# cat /etc/redhat-release #红帽或者centos都能用这个命令看系统
# cat /etc/os-release #查看系统版本,6以下就看不了
- 查看内核版本
# uname -r
1.5 命令提示符
命令提示符:prompt
- 范例:
[root@localhost ~]# #号代表管理员 $代表普通用户 ~代表所在文件夹
- 显示提示符
# echo $PS1
[\u@\h \W]\$
1.5.1 提示符格式说明:
\e控制符\033
\u当前用户
\h主机名简称
\H主机名
\w当前工作目录
\t 24小时时间格式
\T12小时时间格式
!命令历史数
\#开机后命令历史数
- 范例:永久保持PS1
# echo 'PS1="xxx"' > /etc/profile.d/env.sh
# exit #就是重新登录不失效
1.6 执行命令
- shell中可执行的两类命令
- 内部命令:由shell自带的,而且通过某命令形式提供(存储在内存中,运行更快)
- 外部命令:在文件系统路径下有对应的可执行程序文件(存储在外存中,就是磁盘运行相对内部命令更慢点)
- 区别指定的命令式内部或外部命令
# type COMMAND
- 范例:查看是否存在对应内部和外部命令
# type -a echo #列出所有
1.6.1 内部命令相关
help内部命令列表 (会列出所有内部命令及帮助)
enable管理内部命令(会列出所有内部命令)
enable cmd 启用内部命令
enable -n cmd 禁用内部命令
enable -n 查看所有禁用的内部命令
1.6.2 执行外部命令
专门存储外部命令的路径
# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
1.6.3 查看外部命令路径
# which -a | --skip-alias
# whereis
1.7 Hash缓存表
系统初始hash表为空,当外部命令执行时,默认会从PATH路径下寻找该命令,找到后会将这条命令的路径记录到hash表中,当再次使用该命令时,shell解释器首先会查看hash表,存在将执行之,将会去PATH路径下寻找,利用hash缓存表可大大提高命令的调用速率。
1.7.1 hash命令常见用法:
| hash | 显示hash缓存 | |
|---|---|---|
| hash | -l | 显示hash缓存,可作为输入使用 |
| hash | -p | path name 将命令全路径path起别名为name |
| hash | -t | name打印缓存中name的路径 |
| hash | -d | name 清除name缓存 |
| hash | -r | 清除缓存 |
1.8 命令别名
对于经常执行的较长的命令,可以将其定义成较短的别名,以方便执行
- 显示当前shell进程所有可用的命令别名
# alias
- 定义别名name,相当于执行命令value
# alias NAME='VALUE'
- 撤销别名:unalias
# unalias [-a] name [name ...]
# unalias -a #取消所有别名
注意:在命令中定义的别名,仅对当前shell进程有效
如果想永久有效;要定义在配置文件中
- 仅对当前用户:~/.bashrc
- 对所有用户有效:/etc/bashrc
编辑配置给出的新配置不会立即生效,bash进程重新读取配置文件
source /path/to/config_file
. /path/to/config_file
如果别名同原命令同名,如果要执行原命令,可使用
\ALIASNAME
"ALIASNAME"
'ALIASNAME'
command ALISANAME
/path/command
1.9 命令格式
COMMAND [OPTIONS...][ARGUMENTS...]
选项:用于启用或关闭命令的某个或某些功能
- 短选项:UNIX风格选项,-c例如:-l,-h
- 长选项:GUN风格,--word例如:--all,--human
- BSD风格选项:一个字母,例如:ps aux
参数:命令的作用对象,比如文件名,用户名等
范例:
id -u wang #查看wang用户的id值
注意:
- 多个选项以及多参数和命令之间使用空白字符分隔
- 取消和结束执行:Ctrl+c,Ctrl+d
范例:
ping 127.0.0.1 #回环地址ping的话会永不停息
Ctrl +c #强行终止
yum -y install bc #linux中的计算器
bc #进入计算模式
Ctrl +d #退出计算模式
- 多个命令可以用;符号分开
- 一个命令可以用\分成多行
2. 常见命令
2.1 日期和时间
linux的两种时钟
- 系统时钟:由Linux内核通过CPU的工作频率进行的
- 硬件时钟:主板
相关命令
- date显示和设置系统时间,范例如下
date +%s
date -d @1509536033
-
clock,hwclock:显示硬件时钟
-
-s,--hctosys以硬件时钟为准,校正系统时钟
-
-w,--systohc以系统时钟为准,校正硬件时钟
-
时区:
ll /etc/localtime
lrwxrwxrwx. 1 root root 38 Dec 10 2019 /etc/localtime -> ../usr/share/zoneinfo/America/New_York
- 显示日历:
cat -y
- 范例:
cal 9 1752
September 1752
Su Mo Tu We Th Fr Sa
1 2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
2.2 关机和重启
- 关机:
- halt
- poweroff
- 重启:
- reboot
- -f:强制,不调用shutdown
- -p:切断电源 - 关机或重启:shutdown
shutdown [OPTION]... [TIME] [MESSAGE]
shutdown -r #reboot
shutdown -h #halt
shutdown -c #cancel
- TIME:无指定,默认相当于+1(CentOS7)
- now:立刻,相当于+0
- +#:相对时间表示,几分钟后;例如+3
- hh:mm:绝对时间表示,指明具体时间
- 查看系统运行时间
uptime
2.3 用户登录信息查看命令
- whoami:显示当前登录有效用户
- who:系统当前所有的登录会话
- w:系统当前所有的登录会话及所做的操作
2.4 文本编辑
- nano:比较简单的文本编辑命令
2.5 会话管理
2.5.1 screen
| screen | -S | 创建新screen会话 |
|---|---|---|
| screen | -x | 加入screen会话 |
| exit | 退出并关闭screen会话 | |
| Ctrl a,b | 剥离当前screen会话 | |
| screen | -ls | 显示所有已经打开的screen会话 |
| screen | -r [SESSION] | 恢复某screen会话 |
2.5.2 tmux
Tmux是一个终端复用器(terminal multiplexer),类似screen,但是更易用,也更强大
2.5.2.1 安装
yum -y install tmux
2.5.2.2 启动与退出
tmux
exit
tmux窗口有大量的快捷键,所有快捷键都要通过前缀键唤起。默认的前缀键是Ctrl+b,即先按下Ctrl+b,快捷键才会生效。帮助命令的快捷键是Ctrl+b?然后,按下q键,就可以退出帮助
2.5.2.3 新建会话
第一个启动的Tmux窗口,编号是0,第二个窗口的编号是1,以此类推,这些窗口对应的会话,就是0号会话、1号会话。使用编号分区会话,不太直观,更好的方法是为会话起名。下面命令新建一个指定名称的会话。
tmux new -s <session-name>
tmux ls 或Ctrl +b,s可以查看当前所有的Tmux会话
tmux ls
tmux list-session
2.5.2.4 分离会话
在Tmux窗口中,按下Ctrl+b d或输入tmux detach命令,就会将当前会话与窗口分离。
tmux detach
2.5.2.5 接入会话
tmux attach 命令用于重新接入某个已存在的会话
tmux attach -t <session-name>
范例:
tmux attach -t 0
2.5.2.6 杀死会话
tmux kill-session 命令用于杀死某个会话
tmux kill-sesion -t <session-name>
2.5.2.7 切换会话
tmux switch 命令用于切换会话
tmux switch -t <session-name>
可以将窗口分成多个窗格(pane),每个窗格运行不同命令
2.5.2.8 上下窗格
tmux split-windows
ctrl+b,"
2.5.2.9 左右分窗格
tmux split-windows -h
ctrl+b,%
2.5.2.10 窗格快捷键
| Ctrl+b % | 划分左右两个窗格 |
|---|---|
| Ctrl+b | 划分上下两个窗格 |
| Ctrl+b |
光标切换到其他窗格。 |
| Ctrl+b ; | 光标切换到上一个窗格 |
| Ctrl+b { | 当前窗格左移 |
| Ctrl+b Ctrl+o | 当前窗格上移 |
| Ctrl+b Alt+o | 当前窗格下移 |
| Ctrl+b x | 关闭当前窗格 |
| Ctrl+b ! | 将当前窗格拆分为一个独立窗口 |
| Ctrl+b z | 当前窗格全屏显示,在使用一次会变回原来大小 |
| Ctrl+b Ctrl+ |
按箭头方向调整窗格大小 |
| Ctrl+b q | 显示窗格编号 |
2.5.2.11 窗口管理
除了将一个窗口划分成多个窗口,Tmux也允许新建多个窗口
- 新建窗口
tmux new-windows命令来新建窗口
tmux new-windows
- 新建一个指定名称的窗口
tmux new-windows -n <window-name>
- 切换窗口
tmux select-window命令用来切换窗口
tmux select-window -t <window-number> #切换到指定窗口
2.6 输出信息
2.6.1 echo命令(回显,返回显示)
功能:显示字符,echo会将输入的字符串送往标准输出。输出的字符串以空白字符隔开,并在最后加上换行号
语法:
echo [-neE][字符串]
选项:
-E (默认)不支持\解释功能
-n 不自动换行
-e 启动\字符的解释功能
显示变量
echo "$VAR_NAME" #变量会替换,弱引用
echo "$VAR_NAME" #变量不会替换,强引用
2.6.1.1 echo -e 字符详解
启用命令选项-e,若字符中出现一下字符,则特别加以处理,而不会将它当成一般文字输出
| \a | 发出警告声 |
|---|---|
| \b | 退格键 |
| \c | 最后不加上换行符号 |
| \e | escape,相当于\033 |
| \n | 换行且光标移至行首 |
| \r | 换行且光标移至行首,但不换行 |
| \t | 插入tab |
| \ | 插入\字符 |
| \0nnn | 插入nnn(八进制)所代表的的ASCII字符 |
| \xHH | 插入HH(十六进制)所代表的ASCII数字(man 7 ascii) |
- 范例:
echo -e '\033[43;31;5mmagede\e[0m'
3. 字符集和编码
3.1 ASCII码
计算机内部,所有信息最终都是一个二进制值。上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制之间的关系,做了统一规定,即ASCII(American Standard Code for Information Interchange)码
ASCII码一共规定了128个字符的编码,占用了一个字节的后面7位,最前面的一位统一规定为0

- 范例:查看文件十六进制
echo abc > abc.txt
hexdump -C abc.txt
00000000 61 62 63 0a |abc.|
00000004
3.2 Unicode
用于表示世界上所有语言中的所有字符。每个字符都给予一个独一无二的编码数字,UniCode是一个很大的集合,现在的规模可以容纳100多万个符号。Unicode仅仅只是一个字符集,规定了每个字符对应的二进制编码,至于这个二进制编码如何存储则没有规定
UTF-8:变长,1到4个字节
UTF-16:变长,2或4个字节
UTF-32:固定长度,4个字节
UTF-8是目前互联网上使用最广泛的一种Unicode编码方式,可变长存储。使用1-4个字节表示一个字符,根据字符的不同变换长度。编码规则如下:
对于单个字节的字符,第一位设为0,后面的7位对应这个字符的Unicode编码。因此,对于英文中的0-127号字符,与ASCII码完全相同。这意味着ASCII码的文档可用UTF-8编码打开
对于需要使用N个字节来表示的字符(N>1),第一个字节的前N位都设为1,第N+1位设为0,剩余的N-1个字节的前两位都设位10,剩下的二进制则使用这个字符的Unicode码来填充
编码转换和查询:
http://www.chi2ko.com/tool/CJK.htm
https://javawind.net/tools/native2ascii.jsp?action=transform
http://tool.oschina.net/encode
Unicode和UTF-8
| Unicode符号范围(十六进制) | (UTF-8编码方式二进制) |
|---|---|
| 0000 0000-0000 007F | 0xxxxxxx |
| 0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
| 0000 0800-0000 07FF | 1110xxxx 10xxxxxx 10xxxxxx |
| 0001 0000-0010 FFFF | 1110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
范例:
”汉“的Unicode编码0x6C49(110 110001 001001),需要三个字节存储,格式为:110xxxx 10xxxxxx 10xxxxxx,从后往前依次填充对应格式中的x,多出的x用0补,得出UTF-8编码为11100110 10110001 10001001
”马“的Unicode码0x9A6C(1001 101001 101100),需要三个字节存储,格式为:1110xxxx 10xxxxxx 10xxxxxx,从后向前依次填充对应格式中的x,多出的x用0补,得出UTF-8编码11101001 10101001 10101100
查看系统编码
echo $LANG
en_US.UTF-8
3.3 命令行扩展和被括起来的集合
3.3.1 命令行扩展:$()、反向单引号
把一个命令的执行结果打印给另外一个命令的参数
$(CMD) 或 `CMD`
范例:
echo "This system's name is $(hostname)"
touch `date +%F`.log
touch $(date +%F).txt
3.3.2 括号扩展:{}
{}可以实现打印重复字符串的简化形式
范例:
echo file{1,3,5} #结果为file1 file3 file5
rm -f file{1,3,5}
echo {1..10}
1 2 3 4 5 6 7 8 9 10
echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
echo {000..20..2} #000为显示位数的格式,20..2是范围
000 002 004 006 008 010 012 014 016 018 020
3.4 tab键补全
3.4.1 命令补全:
内部命令:
外部命令:bash根据PATH环境变量定义的路径,自左往右在每个路径搜寻以给定命令命名的文件,第一次找到的命令即为要执行的命令
注意:用户给定的字符串只有一条唯一对应的命令,直接补全,否则,再次Tab会给出列表
3.4.2 路径补全
把用户给出的字符串当作路径开头,并在其指定上级目录下搜索以指定的字符串开头的文件名如果唯一:则直接补全否则:再次Tab给出列表
3.4.3 双击Tab键
command 2Tab 所有子命令或文件补全
string2Tab以String开头命令
/2Tab显示所有根目录下一级目录,包括隐藏目录
./2Tab当前目录下子目录,包括隐藏目录
*2Tab当前目录下子目录,不包括隐藏目录
~2Tab所有用户列表
@2Tab /etc/hosts记录(centos7不支持)
=2Tab 相当于ls -A (centos7不支持)
3.5 命令行历史
保存你输入的命令历史。可以用他来重复执行命令登录shell时,会读取命令历史文件中记录的命令~/.bash_history登录进shell后新执行的命令只会记录在缓存中;这些命令会用户退出时”追加“至命令历史文件中。
命令:history
history [-c] [-d offset] [n]
history -anrw [filename]
history -ps arg [arg...]
选项解析
| -c | 清空命令历史 |
|---|---|
| -d offset | 删除历史命令中指定的第offset个命令 |
| n | 显示最近的n条命令 |
| -a | 追加本次会话新执行的命令历史列表至新文件 |
| -r | 读历史文件附加到历史列表 |
| -w | 保存历史列表到为指定的历史文件 |
| -n | 读历史文件中未读过的行到历史列表 |
| -p | 展开历史参数成多行,但不存在历史列表中 |
| -s | 展开历史参数成一行,附加在历史列表后 |
历史命令相关环境变量
| HISTSIZE | 命令历史记录的条数 |
|---|---|
| HISTFILE | 指定历史文件,默认为~/.bash_history |
| HISTFILESIZE | 命令历史文件记录历史的条数 |
| HISTIMEFORMAT=”%F %T“ | 显示时间 |
| HISTGNORE=”str1:str2*....“ | 忽略str1命令,str2开头的历史 |
| HISTCONTROL | 控制命令历史的记录方式ignoredups是默认值,可忽略重复的命令,连续且相同为”重复“ignorespace忽略有以空白开头的命令ignoreboth相当于ignoredups,ignorespace的组合erasedups删除重复命令 |
范例:查看历史命令的保存的条数,当超过1000条就会把最初始的删除
echo $HISTSIZE
1000
持久保存变量
以上变量可以export变量名=‘值’形式存放在/etc/profile在~/.bash_profile
范例:
cat .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
3.6 调用命令行历史
| !!,Ctrl +p,!-1 | 重复前一个命令 |
|---|---|
| !:0 | 执行钱一条命令(去除参数) |
| !n | 执行history命令输出对应序号n的命令 |
| !-n | 执行history历史中倒数第n个命令 |
| !string | 重复前一个以”string“开头的命令 |
| !?string | 重复前一个包含string的命令 |
| !string:p | 仅打印命令历史,而不执行 |
| !$ | 打印输出(上一条命令的最后一个参数) |
| !$:p | 打印输出!$(上一条命令的最后一个参数)的内容,只打印 |
| !*:p | 打印输出!*(上一条命令的所有参数的内容),只打印 |
| ^string | 删除上一条命令中的第一个string |
| string1string2 | 将上一条命令中的第一个string1替换为string2 |
| !:gs/string1/string2 | 将上一条命令中所有string1都替换为string2 |
| up,down | 来上下浏览从前输入的命令 |
| ctrl r | 来在命令历史中搜索命令 |
| ctrl g | 从命令历史模式搜索命令 |
| !$表示 | 重新调用前一个命令中的最后一个参数的快捷键 |
| Alt+. | 点击Alt键的同时点击.键 |
| Esc,. | 点击Esc键后松开,然后点击.键 |
3.7 bash快捷键
| Ctrl + l | 清屏,相当于clear命令 |
|---|---|
| Ctrl + o | 执行当前命令,并重新显示本命令 |
| Ctrl + s | 阻止屏幕输出,锁定 |
| Ctrl + q | 允许屏幕输出 |
| Ctrl + c | 终止命令 |
| Ctrl + z | 挂起命令 |
| Ctrl + a | 光标移到到命令行首,相当于Home |
| Ctrl + e | 光标移到到命令行尾,相当于End |
| Ctrl + f | 光标向右移动一个字符 |
| Ctrl + b | 光标向做移动一个字符 |
| Ctrl + xx | 光标在命令行首和光标之间移动 |
| Ctrl + u | 从光标出删除至命令行首 |
| Ctrl + k | 从光标处删除至命令行尾 |
| Alt + r | 删除当前整行 |
| Ctrl + w | 从光标处向左删除至单词首 |
| Alt + d | 从光标处向右删除至单词尾 |
| Ctrl + d | 删除光标处的一个字符 |
| Ctrl + h | 删除光标前的一个字符 |
| Ctrl + y | 将删除的字符粘贴至光标后 |
| Alt + c | 从光标处开始,将右边一个单词更改为大写 |
| Alt + l | 从交换光标处和之前的字符位置 |
| Alt + # | 提示输入指定字符后,重复显示该字符#次 |
注意:Alt组合快捷键经常和其它软件冲突
4. 获得帮助
4.1 whatis
whatis使用数据库来显示命令的简短描述刚安装后不可立即使用,需要制作数据库
# CentOS7 版本以后
mandb
# CentOS 6版本之前
makewhatis
范例:
whatis cal
man -f cal
4.2 查看命令的帮助
范例:
date --help
Usage: date [OPTION]... [+FORMAT]
or: date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]] #设置时间 月天时分年.秒
Display the current time in the given FORMAT, or set the system date.
格式说明:
[]表示可选项
CAPS或<>表示变化的数据
...表示一个列表
x|y|z的意思是”x“或y或”z“
-abc的意思是-a-b-c
{}表示分组
范例:
1、显示当前时间,格式:2016-06 10:20:30
date "+%Y %m %T"
2021-09 16:27:50
2、显示前天是星期几
date -d "-1 day" +%u
6
3、设置当前日期为2019-08-06 06:05:10
date "2019-08-06 06:05:10"
date
2019-08-06 06:05:10
4.3 --help或-h选项
范例:查看内置命令帮助
type echo
echo is a shell builtin
help echo #help [command]
范例:查看外部命令帮助
type hostname
hostname is hashed (/usr/bin/hostname)
hostname --help #[command] --help | -h
4.4 man命令
man提供命令帮助的文件,手册页存放在/usr/share/man,几乎每个命令都有man的”页面“,中文man需安装包man-pages-zh-CN,man页面分组为不同的”章节“,统称为Linux手册,man 1 man (默认查看第一章手册)
1:用户命令
2:系统调研
3:C库调用
4:设备文件格式
5:配置文件格式
6:游戏
7:杂项
8:管理类的命令
9:Linux内核API
man命令的配置文件:
# CentOS6之前版man手册 ,下面的是CentOS7版man手册路径
whereis man
/etc/man.config
/etc/man_db.conf
格式:
MANPATH /PATH/TO/SOMEWHERE #指明man文件搜索位置
也可以指定位置下搜索COMMAND命令的手册并显示
man -M /PATH/TO/SOMEWHERE COMMAND
查看man手册页
man [章节] keyword
man帮助段落说明
NAME 名称及简要说明
SYNOPSIS用法格式说明
[]可选内容
{}分组
... 同一内容可出现多次
DESCRIPTION 详细说明
OPTIONS 选项说明
EXAMPLES 示例
FILES 相关文件
AUTHOR 作者
COPYRIGHT 版本信息
REPORTING BUGS bug 信息
SEE ALSO其它帮助参考
列出所有帮助
man -a keyword
搜索man手册
man -k keyword #列出所有匹配的页面,使用whatis 数据库
相当于whatis
man -f keyword
打印man帮助文件的路径
man -w [章节] keyword
man命令的操作方法:使用less命令实现
space,v,f,^F:向文件尾翻屏
b,^b:向文件首部翻屏
d,^d:向文件尾部翻半屏
u,^u:向文件首部翻半屏
RETURN,^N, e,^E or j or ^J:向文件尾部翻一行
y or ^Y or ^P or k or ^K:向文件首部翻一行
q:退出
#:跳转至文件首部
1G:回到文件首部
G:翻至文件尾部
/KEYWORD
以KEYWORD指定的字符串为关键字,从当前位置向文件尾部搜索;不区分字符大小写
n:下一个
N:上一个
?KEYWORD
以KEYWORD指定的字符串为关键字,从当前位置向文件首部搜索;不区分字符大小写
n:跟搜索命令同方向,下一个
N:跟搜索命令反方向,上一个
范例:
1、在本机字符终端登录时,除显示原有信息外,再显示当前登录终端号,主机名和当前时间
echo who am i > /etc/profile.d/abc.sh #/etc/profile.d/目录下的脚本登录时会去执行
ctrl +d
2、今天18:30自动关键,并提示用户
shutdown -h 18:30 "Estimated shutdown time 18:30" #默认-P --poweroff关机,shutdown -c取消
存储登录显示的字符文件
cat /etc/motd
4.5 info
man常用于命令参考,GNU工具info适合通用文档参考,没有参数,列出所有的页面,info页面的结构就像一个网站,每一页分为”节点“,链接节点之前*
info命令格式
info [命令]
导航info页
方向键,PgUp,PgDn导航
Tab键,移动到下一个链接
d显示主题目录
Home显示主题首部
Enter进入选定链接
n/p/u/I进入下/前/上一层/最后一个链接
s文字文本搜索
4.6 Linux安装提供的本地文档获取帮助
Applications-> documentation-> help(centos7)
System-> help (centos6)
4.7 命令自身提供的官方使用指南
/usr/share/doc目录
多数安装了的软件包的子目录,包括了这些软件的相关原理说明,常见文档:README INSTALL CHANGES ,不适合其他地方的文档的位置,配置文件范例,HTML/PDF/PS格式的文档,授权书详情
4.8 系统及第三方应用官方文档
4.8.1 通过在线文档获取帮助
4.8.2 红帽知识库和官方在线文档
通过发行版官方的文档光盘或网站可以获得安装指南、部署指南、虚拟化指南等
https://help.ubuntu.com/lts/serverguide/index.html
4.8.3 红帽全球技术支持服务
rhn.redhat.com或者本地卫星服务器/代理服务器,RHN账户为及其注册和基于网络管理的RHN用户sosreport收集所有系统上的日志信息的工具,并自动打成压缩包,方便技术人员和红帽全球支持提供分析问题依据
4.9 网站和搜索
Openstack filetype:pdf
rhca site:redhat.com/docs
5. 文件系统与目录结构

5.1 文件系统的目录结构
文件和目录被组织成一个单根倒置树结构
文件系统从根目录下开始,用”/“表示
根文件系统(rootfs):root filesystem
标准Linux文件系统(如ext4),文件名称大小写敏感,例如:MAIL,Mail,mail,mAiL
以.开头的文件为隐藏文件
路径分隔的/
文件名最长255个字节
包括路径在文件名称最长4095个字节
蓝色-->目录 绿色-->可执行文件 红色-->压缩文件 浅蓝色-->链接文件 灰色-->其他文件(定义所有目录及文件颜色的文件 /etc/DIR_COLORS)
除了斜杠和NUL,所有字符都有效.但是用特殊字符目录名和文件不推荐使用,有些字符需要用引号来引用
每个文件都有两类相关数据:
元数据:metadata
数据:data
Linux文件系统分层结构:FHS Filesystem Hierarchy Standard
参考文档:http://www.pathname.com/fhs/
5.2 常见的文件系统目录的功能
目录解析
| /bin | 所有用户使用的基本命令:不能关联至独立分区,OS启动即会调用到的程序 |
|---|---|
| /boot | 引导文件文件存放目录,内核文件(VMlinuz)、引导加载器(BootLoader,grub)都存放在此目录 |
| /dev | 设备文件及特殊文件存储位置(b:block device ,随机访问(块文件),c:character device,线性访问) |
| /etc | 配置文件目录 |
| /home | 普通用户用户加目录 |
| /root | 管理员的家目录 |
| /run | 存放运行文件,临时使用 |
| /sbin | 管理类的基本命令;不能关联至独立分区,OS启动即会用到的程序 |
| /tmp | 存放临时文件 |
| /usr | universal shared,read-only data(相当于第二级根目录) |
| /var | 存放变化文件的目录(数据不是固定的) |
| /lib | 启动时程序依赖的基本共享库文件以及内核模块文件(/lib/modules) |
| /lib64 | 专用于x86_64系统上的辅助共享文件存放位置 |
| /media | 便携式移动设备挂载点 |
| /proc | 用于输出内核与进程信息相关的虚拟文件系统 |
| /sys | 用于输出当前系统上的硬件设备相关信息虚拟文件系统 |
| /selinux | security enhanced Linux,selinux 相关的安全策略等安装信息的存储文件 |
CentOS7以后版本目录机构变化
/bin/和/usr/bin
/sbin/和/usr/lib
/lib和/usr/lib
/lib64和/usr/lib64
范例:
ls /bin /sbin /lib /lib64 -ld
lrwxrwxrwx. 1 root root 7 Dec 10 2019 /bin -> usr/bin
lrwxrwxrwx. 1 root root 7 Dec 10 2019 /lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Dec 10 2019 /lib64 -> usr/lib64
lrwxrwxrwx. 1 root root 8 Dec 10 2019 /sbin -> usr/sbin
5.3 应用程序的组成部分
二进制程序:
/bin,/sbin
/usr/bin
/usr/sbin
/usr/local/bin
/usr/local/sbin
库文件:
/lib
/lib64
/usr/lib64
/usr/local/lib
/usr/local/lib64
配置文件:
/etc
/etc/DIRECTORY
/usr/local/etc
帮助文件:
/usr/share
/man
/usr/share/doc
/usr/local/share/man
/usrlocal/share/doc
5.4 Linux 下的文件类型
- 普通文件
d 目录文件
b 块设备
c 字符设备
l 符号链接文件
p 管道文件pipe
s 套接字文件socket
范例:
ls -l /run/
total 28
-rw-r--r--. 1 root root 4 Aug 30 06:09 auditd.pid
drwxr-xr-x. 2 root root 60 Aug 30 06:09 blkid
drwxr-xr-x. 2 root root 40 Aug 30 06:09 console
drwx--x--x. 5 root root 140 Aug 30 11:49 containerd
-rw-r--r--. 1 root root 4 Aug 30 06:09 crond.pid
----------. 1 root root 0 Aug 30 06:09 cron.reboot
drwx------. 2 root root 40 Aug 30 06:09 cryptsetup
drwxr-xr-x. 2 root root 60 Aug 30 06:09 dbus
prw-------. 1 root root 0 Aug 30 06:09 dmeventd-client
prw-------. 1 root root 0 Aug 30 06:09 dmeventd-server
drwx------. 8 root root 180 Aug 30 11:49 docker
-rw-r--r--. 1 root root 4 Aug 30 06:09 docker.pid
srw-rw----. 1 root docker 0 Aug 30 06:09 docker.sock
drwxr-xr-x. 2 root root 40 Aug 30 06:09 faillock
drwxr-xr-x. 4 root root 120 Aug 30 06:09 initramfs
drwxr-xr-x. 6 root root 140 Sep 6 03:49 lock
drwxr-xr-x. 3 root root 60 Aug 30 06:09 log
drwx------. 2 root root 80 Aug 30 06:09 lvm
-rw-r--r--. 1 root root 4 Aug 30 06:09 lvmetad.pid
drwxr-xr-x. 2 root root 60 Aug 30 06:09 mount
drwxrwxr-x. 2 root root 40 Aug 30 06:09 netreport
drwxr-xr-x. 2 root root 80 Aug 30 06:09 NetworkManager
drwxr-xr-x. 2 root root 40 Aug 30 06:09 plymouth
drwxr-xr-x. 2 root root 40 Aug 30 06:09 ppp
drwxrwxr-x. 2 root screen 40 Mar 9 10:26 screen
drwxr-xr-x. 2 root root 40 Aug 30 06:09 sepermit
drwxr-xr-x. 2 root root 40 Aug 30 06:09 setrans
-rw-r--r--. 1 root root 5 Aug 30 06:09 sshd.pid
-rw-------. 1 root root 4 Aug 30 06:09 syslogd.pid
drwxr-xr-x. 19 root root 460 Aug 30 06:10 systemd
drwxr-xr-x. 2 root root 60 Aug 30 06:09 tmpfiles.d
drwxr-xr-x. 2 root root 60 Aug 30 06:09 tuned
drwxr-xr-x. 7 root root 160 Aug 31 11:37 udev
drwxr-xr-x. 3 root root 60 Aug 30 06:10 user
-rw-rw-r--. 1 root utmp 2688 Sep 5 18:15 utmp
-rw-------. 1 root root 0 Aug 30 06:09 xtables.lock
6. 文件操作命令
6.1 显示当前工作目录
每个shell和系统进程都有一个当前的工作目录CWD:current work directory 显示当前shell CWD的绝对路径,pwd命令:printing working directory
-P显示真实物理路径
范例:
cd /bin/
pwd -P #因为bin目录是/usr/bin的软件连接目录
/usr/bin
-L显示链接路径(默认)
范例:
pwd
/root
type pwd
pwd is a shell builtin
6.2 绝对路径和相对路径
绝对路径
以正斜杠开始
完整的文件的文件路径
可用于任何想指定一个文件名的时候
相对路径
不以斜线开始
指定相对于当前工作目录或某个目录的位置
可以作为一个简短形式指定一个文件名
基名:basename,只取文件名而不要路径
目录名:dirname,只取路径,不要文件名
范例:
basename /etc/sysconfig/network
network
dirname /etc/sysconfig/network
/etc/sysconfig
6.3 更改目录
命令cd:change directory改变目录
选项:-P切换至物理路径,而非软连接目录
可以使用绝对或相对路径
切换至父目录: cd ..
切换至当前用户主目录:cd
切换至以前的工作目录:cd -
范例:
cd /etc/sysconfig
pwd
/etc/sysconfig
cd ../../data
pwd
data
cd /bin
pwd
/bin
cd -P /bin
pwd
/usr/bin
相关的环境变量:
PWD:当前目录路径
OLDPWD:上一次目录路径
范例:
echo $PWD
/bin
echo $OLDPWD
/usr/bin
6.4 列出目录内容
ls命令可以列出当前目录的内容或指定目录
用法:
ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
常见选项:
| -a | 包含隐藏文件 |
|---|---|
| -l | 显示额外的信息 |
| -R | 目录递归 |
| -r | 倒序递归 |
| -ld | 目录和符号链接信息 |
| -1 | 文件分行显示 |
| -S | 按从大到小排序 |
| -t | 按mtime排序 |
| -u | 配合-t选项,显示并按atime从新到旧排序 |
| -U | 按目录存放顺序显示 |
| -X | 按文件后缀排序 |
6.5 查看文件状态stat
文件相关信息:metadata,data
每个文件有三个时间戳:
access time 访问时间,atime,读取文件内容
modify time 修改时间,mtime,改变文件内容(数据,默认情况显示这个)
change time 改变时间,ctime,元数据发生改变
范例:
stat http.tar.gz
File: ‘http.tar.gz’
Size: 2443829511 Blocks: 4773120 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 394270 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-06-07 23:56:52.345594171 +0800
Modify: 2021-06-07 23:17:45.308600888 +0800
Change: 2021-09-03 11:38:24.206119552 +0800
Birth: -
6.6 确定文件内容
文件可以包含多种类型的数据,使用file命令检查文件的类型,然后确定适当的打开命令或应用程序使用
格式:
file --help
Usage: file [OPTION...] [FILE...]
Determine type of FILEs.
常用选项:
| -b | 列出文件辨识结果时,不显示文件名称 |
|---|---|
| -f | filelist列出文件filelist文件名的文件类型 |
| -F | 使用指定分隔符号替换输出文件名后默认的”:“分隔符 |
| -L | 查看对应软链接对应文件的文件类型 |
| --help | 显示命令在线帮助 |
linux与windows中一些区别
注意:windows中的txt会把换行符也写入底层,但是linux不会
范例:转换回车换行命令
dos2unix filename #把这个Windows文件底层数据去掉回车换行符号
unix2dos filename #把这个linux文件地城数据加上回车换行符号
hexdump filename #会看到多了回车换行符号
范例:linux中文件不在乎后缀
mv /usr/sbin/cat /usr/sbin/cat.txt
cat.txt a #还是可以正常使用的
6.7 文件通配符模式wild-card pattern
文件通配符可以用来匹配符合条件的多个文件,方便批量管理文件,通配符采用特定的符号,表示特定的含义,此特符号称为元字符,常见的通配符号如下:
| ? | 匹配任何单个字符 |
|---|---|
| ~ | 当前用户家目录 |
| ~mage | 用户mage家目录 |
| ~+ | 当前工作目录 |
| ~- | 前一个工作目录 |
| [0-9] | 匹配数字范围,只能正序写,不能倒 |
| [a-z] | 字母,排序是小字母,大字母a-z,选的范围是小a-小z这样会少一个大A |
| [A-z] | 字母,排序是小字母,大字母a-z,选的范围是大A-小z这样会少显示一个大Z |
| [wang] | 匹配列表中的任何的一个字符 |
| [^wang] | 匹配列表的所有字符以外的字符 |
别外还有在Linux系统中预定义的字符类:man 7 glob(查看通配符手册)
| [:digit:] | 任意数字,相当于0-9 |
|---|---|
| [:lower:] | 任意小写字母,表示a-z |
| [:upper:] | 任意大写字母 |
| [:alpha:] | 任意大小写字母 |
| [:blank:] | 水平空白字符 |
| [:space:] | 水平或垂直空白字符 |
| [:punct:] | 标点符号 |
| [:print:] | 可打印字符 |
| [:cntrl:] | 控制(非打印)字符 |
| [:graph:] | 图形字符 |
| [:xdigit:] | 十六进制字符 |
范例:
1、显示/etc目录下所有以l开头,以一个小写字母结尾,且中间出现至少一位数字的文件或目录
ll /etc/l*[[:digit:]]*[[:lower:]] #预定义字符类一定要用[]括起来,否则就是匹配[]中的字符
-rw-r--r--. 1 root root 0 Sep 6 10:47 /etc/ldsg12335zvsd.txt
2、显示/etc目录下以任意一位数字开头,且以非数字结尾的文件或目录
ll /etc/[[:digit:]]*[^[:digit:]]
3、显示/etc目录下非字母开头,后面跟了一个字母及其它任意长度字符的文件或目录
ll /etc/[^[:alpha:]]*?[A-Z]*
4、显示/etc目录下所有以rc开头,并后面是0-6之间的数字,其它为任意字符的文件或目录
ll /etc/rc*[0-6]
5、显示/etc目录下,所有.conf结尾,且以m,n,r,p开头的文件或目录
ll /etc/[mnrp]*.conf
6、只显示/root下的隐藏文件和目录
ll -a /root/
7、只显示/etc下的非隐藏目录
ll /etc/
6.8 创建空文件和刷新时间
touch命令可以用来创建空文件或刷新文件的时间(当文件存在时,再次创建同名文件则会刷新时间戳)
格式:
touch --help
Usage: touch [OPTION]... FILE...
选项说明:
| -a | 仅改变atime和ctime |
|---|---|
| -m | 仅改变mtime和ctime |
| -t | [[CC][YY]MMDDhhmm][.ss] 指定atime和mtime的时间戳 |
| -c | 如果文件不存在,则不予创建 |
范例:创建一个名为昨天日期加年月日加分时秒
touch $(date -d '-1 day' +%F_%T).log
ls
2021-09-05_11:14:27.log
6.9 复制文件和目录
利用cp(copy)命令可以实现文件或目录的复制
格式:
cp --help
Usage: cp [OPTION]... [-T] SOURCE DEST
or: cp [OPTION]... SOURCE... DIRECTORY
or: cp [OPTION]... -t DIRECTORY SOURCE...
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
常用选项:
| -i | 覆盖前提示 |
|---|---|
| -n | 不覆盖,注意两者顺序 |
| -r,-R | 递归复制目录及内部的所有内容 |
| -a | 归档,相当于-dR--preserv=all(保留所有属性再加上递归) |
| -d | --no-dereference --preserv=links |
| -p | 等同--preserv=mode,ownership,timestamp |
| -v | --verbose,显示拷贝过程 |
| -f | --force |
| -u | --update只复制源比目标更新文件或目标不存在的文件 |
| -b | 目标存在,覆盖前先备份,形式为filename~(只能备份一次) |
| --backup=numbered | 目标存在,覆盖前先备份加数字后缀(可以多次备份) |
--preserv[=ATTR_LIST]
mode权限
ownership:属主属组
timestamp
links
xattr
context
all
| 源\目标 | 不存在 | 存在且为文件 | 存在且为目录 |
|---|---|---|---|
| 一个文件 | 新建DEST,并将SRC中内容填充至DEST中 | 将SRC中的内容覆盖至DEST中注意数据丢失风险!建议用-i选项 | 在DEST下新建与原文件同名的文件,并将SRC中内容填充至新文件中 |
| 多个文件 | 提示错误 | 提示错误 | 载DEST下新建与原文件同名的文件,并将原文件内容复制进新文件中 |
| 目录须使用-r选项 | 创建指定DEST同名目录,复制SRC目录中所有文件至DEST下 | 提示错误 | 在DEST下新建与原目录同名的目录,并将SRC中内容复制至新目录中 |
练习:
1、每天将/etc/目录下所有文件,备份到/data独立的子目录下,并要求子目录格式为backupYYY-mm-dd,备份过程可见
cp -av /etc/ /data/backup$(date +%F) #a选项吗是有递归加保留权限的
2、创建/data/rootdir目录,并复制/root/下所有文件到该目录内,要求保留原有权限
mkdir /data/rootdir/
cp -a /root/ /data/rootdir/
6.10 移动和重命名文件
mv(move简写)命令可以实现文件或目录的移动和改名(不能批量改)
同一个分区移动数据速度很快(数据位置没有发生变化),不同分区移动数据,速度相对慢(数据位置发生了变化)
格式:
mv --help #也是系统默认设置了别名(加了一个-i提示)
Usage: mv [OPTION]... [-T] SOURCE DEST
or: mv [OPTION]... SOURCE... DIRECTORY
or: mv [OPTION]... -t DIRECTORY SOURCE...
Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.
常用选项:
| -i | 交互式 |
|---|---|
| -f | 强制 |
| -b | 目标存在,覆盖前先备份 |
利用rename可以批量修改文件名
格式:
rename --help
Usage:
rename [options] expression replacement file... #rename 文件名中的字符串 替换成什么 文件后缀
范例:
#为所有的conf文件加上.bak后缀
rename 'conf' 'conf.bak'
#去掉所有的bak后缀:
rename '.bak' '' *.bak
6.11 删除文件
使用rm命令可以删除文件(也是被别名过,多了一个-i提示选项)
格式:
rm --help
Usage: rm [OPTION]... FILE...
Remove (unlink) the FILE(s).
常用选项:
| -i | 交互式 |
|---|---|
| -f | 强制删除 |
| -r | 递归 |
| --no-preserver-root | 删除/ |
范例:
rm -rf /* #会把外部命令全部删除(存在硬盘的命令),内部命令(存储在内存中命令)不会被删除
范例:删除特殊文件
rm -f -f #这样会删除不了,因为会把-f判断为选项
rm -- -f #这样删除才行
rm ./-f #相对路径,或者绝对路径都可以
rm虽然删除了文件,但是被删除的文件仍然可能被恢复,在安全要求较高的场景下,可以使用share安全删除文件
格式:
shred [OPTION]... FILE...
常见选项:
| -z | 最后一次覆盖添加0,以隐藏覆盖操作 |
|---|---|
| -v | 能够显示操作进度 |
| -u | 覆盖后阶段并删除文件 |
| -n | 指定覆盖文件内容的次数(默认值是3次) |
范例:
shred -zvun 5 passwords.txt
6.12 目录操作
6.12.1显示目录树tree
常见选项:
| -d | 只显示目录 |
|---|---|
| -L level | 指定显示的层级目数 |
| -P pattern | 只显示由指定wild-card pattern匹配到的路径 |
6.12.2创建目录mkdir
常见选项:
| -p | 递归删除父空目录 |
|---|---|
| -v | 显示详细信息 |
| -m MODE | 创建目录时直接指定权限 |
注意:rmdir只能删除空目录,如果想删除非空目录,可以使用rm -r命令,递归删除目录树
6.12.3 删除空目录rmdir
常见选项:
| -p | 递归删除父空目录 |
|---|---|
| -v | 显示详细信息 |
注意:rmdir只能删除空目录,如果想删除非空目录,可以使用rm -r命令,递归删除目录
范例:mv代替rm删除
alias rm='DIR=/data/backup$(date +%_%T; mkdir $DIR; mv -t $DIR)' #-t是 路径-->文件,和之前相反
练习:
1、如果创建/testdir/dir1/x,/testdir/dir1/y,/testdir/dir1/x/a,/test/dir1/x/b,/testdir/dir1/y/a,/testdir/dir1/y/b
mkdir -p /testdir/dir1/{x,y}/{a,b}
tree /testdir/
/testdir/
└── dir1
├── x
│ ├── a
│ └── b
└── y
├── a
└── b
2、如何创建/testdir/dir2/x,/testdir/dir2/y,/testdir/dir2/x/a,/testdir/dir2/x/b
mkdir -p /testdir/dir2/{x/{a,b},y} #使用嵌套{{}}
tree /testdir/
/testdir/
└── dir2
├── x
│ ├── a
│ └── b
└── y
3、如何创建/testdir/dir3,/testdir/dir4,/testdir/dir5,/testdir/dir5/dir6,/testdir/dir5/dir7
mkdir -p /testdir/dir{3,4,5/dir{6,7}} #使用嵌套{{}}
tree /testdir/
/testdir/
├── dir3
├── dir4
└── dir5
├── dir6
└── dir7
7. 文件元数据和节点表结构
7.1 inode表结构
每个文件的属性信息,比如:文件的大小,时间,类型等,称为文件的元数据。这些数据时存放在node(index node)表中。node表中有多条记录组成,第一条记录对应的存放了一个文件的元数据信息第一个node表记录的保存了一下信息:
inode number节点号
文件类型
权限
UID
GID
链接数(指向这个文件名路径称个数)
该文件的大小和不同的时间戳
指向磁盘上文件的数据块指针
有关文件的其他数据
7.1.1 cp和inode
cp命令:
分配一个空闲的inode号,在inode表中生成新条目
在目录中创建一个目录项,将名称与inode编号关联
拷贝数据生成新的文件
7.1.2 rm和inode
rm命令:
链接数递减,从而释放的inode号可以被重用
把数据快放在空闲列表中
删除目录项
数据实际上不会马上被删除,但当另外一个文件使用数据块时将被覆盖
7.1.3 mv和inode
如果mv命令的目标和源在相同的文件系统,作为mv命令
用新的文件名创建对应新的目录项
删除旧目录条目对应的旧的文件名
不影响inode表(除时间戳)或磁盘上的数据位置:没有数据被移动!
如果目标和源在一个不同的文件系统,mv相当于cp和rm
范例:当提示空间不足了,但是空间使用率才10,为什么呢?
trouch new.txt
touch: cannot touch 'new.txt': No space left on device
df /boot
Filesystem 1k-blocks Used Available Use% Mounted on
/dev/sda1 999320 1338800 796708 15% /boot
df -i /boot
Filesystem Inodes IUsed IFree Use% Mounted on #可以看到是i节点号被占满了,每个文件都会被占用一个i节点号
/dev/sda1 65536 65536 0 100% /boot
7.2 硬链接ln
硬链接本质上就是给文件起一个新的名称,实质是同一个文件
硬连接特性:
创建硬链接会增加额外的记录项以引用文件
对应于同一文件系统上一个物理文件
每个目录引用相同的inode号
创建时链接数递增
删除文件时:rm命令递减计数的链接,文件要存在,至少有一个链接数,当链接数为零时,该文件被删除
不能跨越驱动器或分区
不支持对目录创建硬链接
格式:
ln filename [linkname] #会占用同一个i node号,而且由于节点号一样,数据空间不变(其实就重命名了一个文件,链接数增加)
7.3 符号(或软)链接
软链接基于旧文件进行访问的,当旧文件不存在那么软链接将无法访问,反之可以访问
注意点:
删除软件链接时,不能在名称后加/,否则会删除旧文件中的所有文件
创建软链接时,要写相对于旧文件的相对路径(或者都是绝对路径),否则会找不到
一个符号链接指向另一个文件,就像windows中快捷方式,软链接文件和原文件本质上不是一个同一个文件软链接特点:
一个符号链接的内容是它引用文件的名称
可以对目录创建软链接
可以跨分区的文件实现
指向的是另一个文件的路径;其大小为指向的路径字符串的长度;不增加或减少目标文件inode的引用计数
软链接如果使用相对路径,是相对源文件的路径,而非相对于当前目录
格式:
ln -s filename [linkname]
范例:
#绝对路径
ln -s /data/dir /data/dirlink
#相对路径
ln -s ../data/dir /root/dirlink
rm -rf /data/dirlink #删除软链接本身,不会删除源目录内容
rm -rf /data/dirlink/ #删除源目录的文件,不会删除链接文件
7.4 硬链接和软链接区别总结
1、本质:
硬:本质是同一个文件
软:本质不是同一个文件
2、跨设备
硬:不支持
软:支持
3、inode
硬:相同
软:不同
4、链接数
硬:创建增加,删除会减少
软:无论创建或删除都不增加
5、文件夹
硬:不支持
软:支持
6、相对路径
硬:可以指定原始文件的相对路径(原始文件路径相对于当前工作目录)
软:原始文件相对路径是相对于链接文件的相对路径
7、删除源文件
硬:只是链接数减一,但链接文件的访问不受影响
软:链接文件将无法访问
8、文件类型
硬:和源文件相同
软:链接文件和源文件无关
8. 标准的I/O和管道
内容概述
三种I/O设备
把I/O重定向至文件
使用管道
8.1 标准输入和输出
程序:指令+数据
读入数据:Input
输出数据:Output
打开的文件都会有一个fd:file descriptor(文件描述符)
Linux给程序提供三种I/O设备
| 标准输入(STDIN) | 0 | 默认接收来自终端窗口的输入 |
|---|---|---|
| 标准输出(STDOUT) | 1 | 默认输出到终端窗口 |
| 标准错误(STDERR) | 2 | 默认输出到终端窗口 |
范例:
ll /dev/std*
lrwxrwxrwx. 1 root root 15 Aug 30 06:09 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx. 1 root root 15 Aug 30 06:09 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx. 1 root root 15 Aug 30 06:09 /dev/stdout -> /proc/self/fd/1
ll /proc/self/fd/* #可以看到标准输出、错误、输入,都是在当前的终端窗口实现的
lrwx------. 1 root root 64 Sep 7 04:58 /proc/self/fd/0 -> /dev/pts/0
lrwx------. 1 root root 64 Sep 7 04:58 /proc/self/fd/1 -> /dev/pts/0
lrwx------. 1 root root 64 Sep 7 04:58 /proc/self/fd/2 -> /dev/pts/0
8.2 I/O重定向
读音(redirect)
i/O重定向:将默认的输入,输出或错误对应的设备改变,指向新的目录
8.2.1 标准输出和错误重新定向
STDOUT和STDERR可以被重定向到文件
格式:
命令 操作符号 文件名
支持的操作符号包括:
| 1>或> | 把STDOUT重定向到文件 |
|---|---|
| >| | 强制覆盖 |
| 2> | 把STDERR重定向到文件 |
| &> | 把所有输出重定向到文件 |
注意:如以上文件已存在,文件内容会被覆盖
set -C 禁止将内容覆盖已有文件,但可追加
set +C 允许覆盖
>> 可以在原有的内容基础上,追加内容
范例:
who am i | tty #查看自己的终端号,然后往另外一个终端输出信息
ls 1> /dev/pts1
ls /data > /dev/pts1
把输出和错误重新定向到文件
>> 追加标准输出重定向至文件
passwd > abc.log #这样不会被重定向,因为passwd不是标准输出
wall warning2 > abc.log #这样不会被重定向,因为wall不是标准输出
2>> 追加标准错误重定向至文件
标准输出和错误输出各自定向至不同位置
COMMAD > /path/to/file.out 2> /path/to/error.out
合并标准输出和错误输出为同一个数据流进行重定向
& 读音(而特)
&> 覆盖重定向 #&代表所有标准输出和标准错误
&>> 追加重定向
COMMAND > /path/to/file.out 2>&1 #表示 先把标准输出发放入file.out文件 再把标准错误重定向到标准输入(顺序很重要,因为命令式默认从左到有执行)
COMMAND >> /path/to/file.out 2>&1
()合并多个执行结果的STDOUT
范例:
(ls;hostname) >> | > abc.log
范例:清除大文件
cat > /dev/null > /data/file.log #如果使用rm,不会把文件数据立刻删除,只是把i节点号删除了,数据区设置为空闲,但是当文件被使用时,空间还是会被占用。所以用空设备文件重定向可以直接解决这个问题
范例:将标准输出和错误都重定向到同一个文件
ls /data /xxx > /data/all.log 2>&1
ls /data /xxx 2> /data/all.log 1>&2
ls /data /xxx &> /data/all.log
ls /data /xxx 2>&1 /data/all.log
范例:隐藏屏幕中显示的执行结果(默默执行了,不显示)
passwd wang &> /dev/null #/dev/null是空设备文件,相当于垃圾箱
8.3 标准输入重定向
从文件中导入STDIN,代替当前终端的输入设备,使用<来重定向标准输入某些命令能够接受从文件中导入的STDIN
8.3.1 tr命令
tr转换和删除字符
tr [OPTION]... SET1_[SET2]
选项:
| -c -C --complement | 取字符集的补集 |
|---|---|
| -d --delete | 删除所有属于第一字符集的字符 |
| -s --squeeze-repeats | 把连续重复的字符以单独一个字符表示,即去重(只能去重连续字符) |
| -t --truncate-set1 | 将第一个字符集对应字符转化为第二个字符集对应的字符 |
| [:alnum:] | 字母和数字 |
| [:alpha:] | 字母 |
| [:digit:] | 数字 |
| [:lower:] | 小写字母 |
| [:upper:] | 大写字母 |
| [:space:] | 空白字符 |
| [:print:] | 可打印字符 |
| [:punct:] | 标点字符 |
| [:graph:] | 图形字符 |
| [:cntrl:] | 控制(非打印)字符 |
| [:xdigit:] | 十六进制字符 |
范例:把连续的字符去重,再进行转换,通过标准输入重定向(对文件内容的操作)
df > df.log
tr -s ' ' : < df.log
范例:把window文件去掉回车符
tr -d '\r' < windows.txt > windows2.txt
8.3.2 标准输入重定向
passwd < 用户 密码(将标准输入到passwd)
利用”<“可以将标准输入重定向
比如:
cat > file
mage
wangxiaochun
按Ctrl +d离开,可以使用文件来代替键盘的输入
范例:
cat < file1 > file2 #标准输入利用cat把file1内容 标准输出重定向到file2文件
cat < file1 >> file2 #跟上面一样,重定向变成追加
范例:计算器标准输入(传参)直接返回结果
bc < 2*3
6
范例:单行重定向
cat > cat.log #每回车一次,重定向一次到cat.log文件中
line1
line2
line3
8.3.3 多行重定向
使用”<<终止词“ 命令从键盘把多行重导向STDIN,直到终止词之前的所有文本都发送给STDIN,有时被称为就地文本(here documents)
其中终止词可以是任何一个或多个符号,比如:!,@,$,EOF(End Of File),magedu等,其中EOF比较常用
范例:
mail -s "Please Call" admin@magedu.com <<EOF
Hi Wang
Please give me a call when you get in. We may need
to do some maintenance on server1.
Details when you're on-site
Zhang
EOF
8.4 管道
管道(使用符号”|“表示)用来连接多个命令
格式
命令1 | 命令2 | 命令3 | ...
功能说明:
将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
所有命令会在当前shell进程的子shell进程中执行
组合多种工具的功能
注意:STDERR默认不能通过管道转发,可利用2>&1或|&实现,格式如下:
命令1 2>&1 | 命令2
名1 |& 命令2
范例:命令1 标准输出 | 命令2 标准输入
df | tr -s ' '
范例:标准错误使用管道符号传给tr
ls /data /xxx | tr 'a-z' 'A-Z' #这种写法不行
ls /data /xxx 2>&1 | tr 'a-z' 'A-Z' #把标准错误重定向给标准输出 再把参数通过管道符传给 tr命令进行标准输入
ls /data /xxx |& tr 'a-z' 'A-Z'
范例:非交互修改口令
cat p.txt
centos
cat p.txt | passwd --stdin wang #--stdin 标准输入
echo magedu | passwd --stdin wang
echo magedu | passwd --stdin wang &> /dev/null #非交互式修改口令,并且没有任何提示
范例:
ls | tr 'a-z' 'A-Z'
#less实现分页地查看输入
ls -l /etc/ |less
#mail通过电子邮件发送输入
8.5 管道中的-符号
管道中有时会使用-符号
示例:
将/home里面的文件打包,但打包的数据不是记录到文件,而是传送到stdout,经过管道后,将tar -cvf - /home 传送给后面的tar -xvf -,后面的这个- 则是取前面一个命令的stdout,因此,就不需要使用临时file了。
tar -cvf - /home | tar -xvf -
8.6 tee命令
利用tee命令可以重定向到多个目录
格式
命令1 | tee [-a] 文件名 | 命令2
以上可以把命令1的STDOUT保存在文件中,作为命令2的输入
选项:
| -a, --append | 追加 |
|---|
功能:
保存不同阶段的输出
复杂管道的故障排除
同时查看和记录输出
8.7 练习
1、将/etc/issue/文件中的内容转换为大写后保存至/tmp/issue.out文件中
cat /etc/issue | tr 'a-z' 'A-Z' > /tmp/issue.out
2、将当前系统登录用户的信息转换为大写后保存至/tmp/who.out文件中
w | tr 'a-z' 'A-Z' > /tmp/who.out
3、一个linux用户给root发邮件,要求邮件标题为”help“,邮件正文如下:Hello, I am 用户名,The system version is here,please help me to check it,thanks!
mail -s "help" root << EOF
The system version is here,please help me to check it,thanks!
EOF
4、将/root/下文件列表,显示成一行,并文件名之间用空格隔开
ls -m /root | tr -d ',''' #m选项代表以,号分隔
5、计算1+2+3+...+99+100的总和
上一个命令的标准输出通过|标准输入到下一个命令
echo {1..100} | tr ' ' + | bc #echo为标准输出(命令1),tr为(命令1的标准输出到命令2的输入),bc为标准输入(命令2输出到bc中为命令3的标准输入)
5050
seq -s + 1 100 | bc
6、删除Windows文本文件中的回车字符,即”\r“
tr -d '\r' < windows.txt > windows2.txt
7、处理字符串”xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4“,只保留其中的数字和空格
tr "xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4" "[:digit:][:print:]"
8、将PATH变量每个目录显示的独立的一行
echo $PATH |tr ':' '\n'
9、将指定文件中0-9分别替换成a-j
echo {0..20} > abc.txt
tr '[0-9]' '[a-j]'
10、将文件/etc/centos-release中每个单词(由字母组成)显示在独立一行,并无空行
cat /etc/centos-release | tr 'a-z' '\n'
用户、组和权限
9. Linux安全模型
资源分派:
| Authentication | 认证,验证用户身份 |
|---|---|
| Authorization | 授权,不同的用户设置不同权限 |
| Accouting | Audition | 审计 |
当用户登录时,系统会自动分配令牌token,包括用户标识和组成员等信息
9.1 用户
Linux中每个用户时通过User ID (UID)来唯一标识。
管理员:root,0
普通用户:1-60000 自动分配(人为设置可以更大)
系统用户:1-499 (CentOS6以前),1-999(CentOS7以后)
对守护进程获取资源进行权限分配
登录用户:500+ (CentOS以前),1000+(CentOS7以后)
给用户进行交互式登录使用
9.2 用户组
Linux可以将一个或多个用户加入用户组中,用户组是通过Group ID(GID)来唯一标识的。
管理员组:root,0
普通组:
系统组:1-499(CentOS6以前),1-999(CentOS7以后),给守护进程获取资源进行权限分配
普通组:500+(CentOS6以前),1000+(CentOS7以后),给用户使用
9.3 用户和组的关系
用户的主要组(primary group):用户必须属于一个且只有一个主组,默认创建用户时会自动创建和用户名同名的组,作为用户的主要组,由于此组中只有一个用户,又称为私有组
用户的附加组(supplementary group):一个用户可以属于零个或多个辅助组。
范例:可以看到postfix用户有两个组,主组为postfix,附加组为mail
id postfix
uid=89(postfix) gid=89(postfix) groups=89(postfix),12(mail)
9.4 安全上下文
Linux安全上下文Context:运行中的程序,即进程(process),以进程发起者的身份运行,进程所能够访问资源的权限取决于进程的运行者的身份
比如:root身份运行/bin/cat /etc/shadow和wang的身份运行/bin/cat /etc/shadow,得到的结果时不同的,shadow能否能被访问是由运行者的身份决定,非程序本身
10. 用户和组的配置文件
10.1 Linux用户和组的主要配置文件
/etc/passwd:用户及其属性信息
/etc/shadow:用户密码及其相关属性
/etc/group:组及其属性信息
/etc/gshadow:组密码及其相关属性
10.2 passwd文件格式
解析passwd文件中root用户信息:root❌0:0:root:/root:/bin/bash
| root(login name) | 代表用户 |
|---|---|
| x (passwd) | 代表密码存储在/etc/shadow文件中 |
| 0 (UID) | 代表超级用户(UID) |
| 0 (GID) | 超级用户组(主组GID) |
| root (GECOS) | 用户全名或注释 |
| /root/ (home directory) | 家目录 |
| /bin/bash (用户默认使用shell) | 对应的shell |
10.3 shadow文件格式
解析shadow(歇dou)中用户密码信息:root:$6$Zu7WswXtzREbo0Z2$WxlTlfh/g09EXzuXigWDH13pncvQOlchFef5u/Wsgh00KljxLzLR25BAiWhBnCWrwhO9sHKbGNzAydlb1lEcs.::0:99999:7:::
| root | 登录用户 |
|---|---|
| $6...Ecs | 登录密码:一般为sha512加密,加入该区域为!代表该账号口令被锁定,无法登录 |
| 第三段:(为空) | 该用户修改密码距离1970年的天数 |
| 0 | 密码再过几天可以被更改(0表示随时可被变更) |
| 99999 | 代表有密码有效天数 |
| 7 | 密码过期倒数提醒天数(7为倒数第7天) |
| 空 | 密码过期几天后账号会被锁定 |
| 空 | 从1970年1月1日算起,多少天后账号失效 |
更改密码加密算法:
authconfig --passalgo=sha256 --update
10.4 group文件格式
| 群组名称 | 就是群组的名称 |
|---|---|
| 群组密码 | 通常不需要设定,密码是被记录在/etc/gshadow |
| GID | 就是群组的ID |
| 第四段 | 以前组为附加组的用户列表(分隔符为逗号) |
10.5 gshadown文件格式
| 群组名称 | 就是群的名称 |
|---|---|
| 群组密码 | |
| 组管理员列表 | 组管理员的列表,更改组密码和成员 |
| 以前组为附加组的用户列表 | 多个用户用逗号分隔 |
10.6 文件操作
vipw和vigr
pwck和grpk
11. 用户和组管理命令
用户管理命令:
useradd
usermode
userdel
组账号维护命令
groupadd
groupmod
groupdel
11.1 用户创建
useradd命令可以创建新的Linux用户
格式:
useradd [options] LOGIN
常见选项:
| -u | 指定UID |
|---|---|
| -o | 配合-u选项,不检查UID的唯一性 |
| -g | GID指明用户所属基本组,可为组名,也可以GID |
| -c | ”COMMENT“ 用户的注释信息 |
| -d | HOME_DIR以指明的路径(不存在)为家目录 |
| -s | SHELL 指明用户的默认shell程序,可用列表在/etc/shells文件中 |
| -G | GROUP1[,GROUP2,...] 为用户指明附加组,组须事先存在 |
| -N | 不创建私有组做主组,使用users组做主组 |
| -r | 创建系统用户CentOS6之前:ID<500,CentOS7以后:ID< 1000 |
| -m | 创建家目录,用于系统用户 |
| -M | 不创建家目录,用于非系统用户 |
useradd命令默认值设定由/etc/default/useradd定义
cat /etc/default/useradd
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel #用户家目录中文件的模板文件存放路径
CREATE_MAIL_SPOOL=yes
范例:查看对应包的安装脚本
rpm -q --scripts httpd #rpm查询 httpd安装脚本
显示或更改默认设置
useradd -D #显示useradd默认设置
useradd -D -s SHELL
useradd -D -b BASE_DIR
useradd -D -g GROUP
新建用户的相关文件
/etc/default/useradd
/etc/skel/*
/etc/login.defs
批量创建用户
newuser passwd 格式文件
批量修改用户口令
echo username:passwd | chpasswd
11.2 用户属性修改
usermod命令可以修改用户属性
格式:
usermod [OPTION] login
常见选项:
| -u | UID新UID |
|---|---|
| -g | GID新主组 |
| -G | GROUP[,GROUP2,...[,GROUP]]新附加组,原来的附加组将会被覆盖;若保留原有,则要同时使用-a选项 |
| -s | SHELL 新的默认SHELL |
| -c | COMMENT新的注释信息 |
| -d | HOME新家目录不会自动创建;若要创建新家目录并移动原家数据,同时使用-m选项 |
| -l | login_name新名字 |
| -L | lock指定用户,在/etc/shadow密码栏的增加! |
| -U | unlock指定用户,将/etc/shadow密码栏的!拿掉 |
| -e | YYYY-MM-DD:指明用户账号过期日期 |
| -f | INACTIVE:设定非活动期限 |
11.3 删除用户
userdel可删除Linux用户
格式:
userdel [OPTION]...Login
常见选项
| -f,--force | 强制 |
|---|---|
| -r,--remove | 删除用户家目录和邮箱 |
11.4 查看用户相关的ID信息
id命令可与查看用户的UID,GID等信息
id [OPTION]... [USER]
常见选项:
| -u | 显示UID |
|---|---|
| -g | 显示GID |
| -G | 显示用户所属的组的ID |
| -n | 显示名称,需配合ugG使用 |
11.5 切换用户或以其他用户身份执行命令
su (Switch user)命令可以切换用户身份,并且以指定用户的身份执行命令
格式:
su [options...] [-] [user [args...]]
切换用户的方式:
su UserName:非登录式切换,即不会读取目标用户的配置文件,不改变当前工作目录
su - UserName:登录式切换,会读取目标用户的配置文件,切换至家目录,完全切换(相当于重新登录)
说明:root su至其他用户无须密码:非root用户切换时需要密码
换个身份执行命令:
su [-] UserName -c 'COMMAND'
选项:
-l --login su -l UserName 相当于 su - UserName
11.6 设置密码
passwd可以修改用户密码
格式:
passwd [OPTIONS] UserName
常用选项:
| -d | 删除指定用户密码 |
|---|---|
| -l | 锁定指定用户 |
| -u | 解锁指定用户 |
| -e | 强制用户下次登录修改命令 |
| -f | 强制操作 |
| -n | mindays指定最短使用期限 |
| -x | maxdays最大使用期限 |
| -w | warndays提前多少天开始警告 |
| -i | inactivedays非活动期限 |
| --stdin | 从标准输入接收用户密码 |
范例:非交互式修改密码
echo "PASSWDORD" | passwd --stdin USERNAME
11.7 修改用户密码策略
chage可以修改用户密码策略
格式:
chage [OPTION]... LOGIN
常用选项:
| -d | LAST_DAY(最后设置的天数) |
|---|---|
| -m | --mindays MIN_DAYS(最小口令有效期) |
| -M | --maxdays MAX_DAYS(最大口令有效期) |
| -W | --warndays WARN_DAYS(设定口令警报) |
| -l | --inactive INACTIVE 密码过期后的宽限期 |
| -E | --expiredate EXPIRE_DATE 用户的有效期 |
| -l | 显示密码策略 |
示例:
chage -d tom #下一次登录强制重设密码
chage -m 0 -M 42 -W 14 -I 7 tom
chage -l wang #查看用户密码信息
chage -E 2016-9-10 tom
getent shadow wang 查看wang用户的密码信息
11.8 用户相关的其他命令
chfn 指定个人信息
chsh 指定shell
finger可查看用户个人信息
范例:
chfn wang #修改用户个人信息
finger wang #查看用户个人信息
11.9 管理组
11.9.1 创建组
grouadd [OPTION]... group_name
-g GID 指明GID号;[GID_MIN,GID_MAX]
-r 创建系统组 CentOS6 之前:ID < 500,CentOS7以后:ID < 1000
范例:shell
groupadd -g 48 -r apache
11.9.2 修改组
组属性修改:groupmod
groupmod [OPTION]... group
-n group_name:新名字
-g GID:新的GID
11.9.3 组删除
groupdel | GROUP
3.10更改组密码
组密码:gpasswd
gpasswd [OPTION] GROUP
-a user 将user添加至指定组中
-d user 从指定组中移除用户user
-A user1,user2... 设置有管理权限的用户列表
范例:
#增加组成员
groupadd admins
id wang
gpasswd -a wang admins
id wang
groups wang
getent group admins
#删除组成员
gpasswd -d wang admins
groups wang
id wang
getent group admins
11.10 临时切换主组
newgrp命令
如果用户本不属于此组,则需要组密码
格式:
newgrp [-] [group]
如果使用-选项,可以初始化用户环境
范例:设置组密码,并修改用户组
gpasswd root
getent gshadow
newgrp root #修改用户主组,临时生效
id
11.11 更改和查看组成员
groupmems可以管理组成员关系
格式
groupmems [options] [action]
常见选项:
| -g,--group groupname | 更改为指定组(只有root) |
|---|---|
| actions | |
| -a --add username | 指定用户加入组 |
| -d --delete username | 从组中删除用户 |
| -p --purge | 从组中清楚所有成员 |
| -l --list | 显示组成员列表 |
groups可查看用户组关系
格式
#查看用户所属组列表
groups [OPTIONS]... [USERNAME]...
范例:
groupmems -l -g admins
groupmems -a mage -g admins
groupmems -l -g admins
groupmems -a wang -g admins
groupmems -l -g admins
groupmems -d wang -g amdins
groupmems -l -g admins
groupmems -p -g amdins
groupmems -l -g admins
3.13 练习
创建用户gentoo,附加组为bin和root,默认shell为/bin/csh,注释信息为”Gentoo Distribution“
useradd -G bin root -s /bin/csh -c "Gentoo Distribution" gentoo
finger -l gentoo #查看用户信息
创建下面的用户、组和组成员关系
名字为webs的组
groupadd webs
用户nginx,使用webs作为附加组
useradd -G webs nginx
用户varnish,使用webs作为附加组
useradd -G webs varnish
用户mysql,不可交互登录系统,且不是webs的成员,nginx,varnish,mysql密码都是magedu
useradd -s /bin/nologin ;echo magedu | passwd --stdin {nginx,varnish,mysql}
12. 文件权限管理

12.1 文件所有者和属组属性操作
12.1.1 设置文件的所有者chown
chown命令可以修改文件的属主,也可以修改文件属组
格式
chown --help
Usage: chown [OPTION]... [OWNER][:[GROUP]] FILE...
or: chown [OPTION]... --reference=RFILE FILE...
Change the owner and/or group of each FILE to OWNER and/or GROUP.
With --reference, change the owner and group of each FILE to those of RFILE.
用法说明:
| OWNER | 只修改所有者 |
|---|---|
| OWNER:GROUP | 同时修改所有者和属组 |
| :GROUP | 只修改属组,冒号也可用.替换 |
| -R | 递归 |
| --reference=RFILE | 参考指定的属性,来修改 |
范例:
chown wang f1.txt
chown :admins f1.txt
chown root.bin f1.txt
chown wang:admins f1.txt
cp /etc/issue f2.txt
chown --reference=f1txt f2.txt
ll
12.1.2 chcrp设置文件的所属组
chgrp命令可以只修改文件的属组
格式: -R递归
chgrp --help
Usage: chgrp [OPTION]... GROUP FILE...
or: chgrp [OPTION]... --reference=RFILE FILE...
Change the group of each FILE to GROUP.
范例:
chgrp admins f1.txt #只修改文件所属组
ll f1.txt
12.2 文件权限
12.2.1 文件的权限针对的三类对象
| owner | 属者 | u |
|---|---|---|
| group | 属组 | g |
| other(啊了) | 其他 | o |
12.2.2 文件的三种权限
| r | Readable(读) |
|---|---|
| w | Writable(写) |
| x | eXcutable(执行) |
12.2.3 对文件的权限
| r | 可使用文件查看类工具获取其内容 |
|---|---|
| w | 可修改其内容 |
| x | 可以把此文件提请内核启动为一个进程 |
文件的删除,跟文件本身没关系,跟父目录权限相关。
12.2.4 对目录的权限:
| r | 可以使用ls查看此目录中的文件 |
|---|---|
| w | 可在此目录中创建文件,也可删除此目录中的文件 |
| x | 可以使用ls -l查看此目录中文件元数据(必须配合r),可以cd进入此目录 |
| X | 只给目录x权限,不给没有执行权限的文件x权限 |
一般rx权限一起赋予,否则只能执行,确看不到文件名,或者只能看见文件名,却不能执行。
12.2.5 数学的权限

12.2.6 八进制数字
| --- | 000 0 |
|---|---|
| --x | 001 0 |
| -w- | 010 2 |
| -wx | 011 3 |
| r-- | 100 4 |
| rw- | 101 5 |
| rwx | 111 7 |
例如:
每一组为二进制
421 (7)——> rwx
401 (5)——> rx
401 (5)——> rx
| 640 | rw-r------ |
|---|---|
| 755 | rwxr-xr-x |
12.2.7 修改文件权限chmode
格式
hmod --help
Usage: chmod [OPTION]... MODE[,MODE]... FILE...
or: chmod [OPTION]... OCTAL-MODE FILE...
or: chmod [OPTION]... --reference=RFILE FILE...
Change the mode of each FILE to MODE.
With --reference, change the mode of each FILE to that of RFILE.
说明:
| -R | 递归修改权限 |
|---|---|
| MODE | 修改一类用户的所有权限 |
| u= g= ug= g= u= g= | 修改一类用户某位或某些位权限 |
| u+ u- g+ g- o+ o- a+ a- + - |
范例:设置X权限
ll dir
ll -d dir
chmod -R a+X dir
ll -d dir
范例:
chgrp sales testfile
chown root:admins testfile
chmod u+wx,g-r,o=rx file
chmod -R g+rwX /testdir
chown mage testfile
面试题:
执行 cp /etc/issue /data/dir 所需要的最小权限?
cp 需要x权限
/etc/ 需要x权限
issue 需要r权限
/data/ 需要x权限
/dir 需要wx权限(dir是目录)
12.3 新建文件和目录的默认权限
umask的值可以用来保留在创建文件权限
实现方式:
新建文件的默认权限:666-umask值,如果所得结果某位存在执行(奇数)权限,则将其权限+1,偶数保持不变
新建目录的默认权限:777-umask值
非特权用户umask默认是002
root的umask默认是022
查看umask
umask #模式方法显示
umask -S
umask -p #输出可被调用
修改umask
umask #临时生效
echo umask 123 > .bashrc.sh #永久生效
范例:
umask 002
umask u=rw,g=r,o=
持久保持umask
全局设置(影响所有用户):/etc/bashrc
用户设置(至影响当前用户):~/.bashrc
练习
当用户docker对/testdir目录无执行权限时,意味着无法做哪些操作?
不能进该目录
当用户mongdb对/testdir目录无读写权限时,意味着无法做哪些操作?
不能写、和查看该目录 #无法使用ls /testdir,但是如果知道文件名称,还是可以使用ls命令的
当用户redis对/testdir目录无写权限时,该目录下的只读文件file1是否可修改和删除?
redis用户无法对file1文件进行修改和删除操作
当用户zabbix对/testdir目录有写和执行权限时,该目录下的只读文件file1是否可修改和删除?
zabbix用户对file1文件无法进行修改,并且无法使用ls命令,除非知道文件名称;可以对文件进行删除操作
复制/etc/fstab文件到/var/tmp/下,设置文件所有者为tomcat读写权限,所属组为apps组有读写权限,其他人无权限
cp /etc/fstab /var/tmp
chmod 660 fstab
误删除了用户git的家目录,请重建并恢复该用户家目录及相应的权限属性
useradd git ; cd /home/; mkdir /home/git; cp -a /etc/skel/. /home/git/; chmod 700 /home/git; chown git.git git
12.4 LInux文件系统上的特殊权限
前面介绍了三种常见的权限:r,w,x还有三种特殊权限:SUID,SGID,Sticky
12.4.1 特殊权限SUID
安全上下文
前提:进程有属主和属组;文件有属主和属组
1、任何一个可执行文件能不能启动为进程,取决发起者对程序文件是否拥有执行权限
2、启动为进程后,其进程的属主为发起者,进程的属组为发起者所属的组
3、进程的访问文件时的权限,取决于进程的发起者
(a)进程的发起者,同文件的属主:则应用文件属主权限
(b)进程的发起者,属于文件属组;则应用文件属组权限
(c)应用文件”其它“权限
二进制可执行文件上SUID权限功能:
任何一个可执行程序文件能不能启动为进程:取决于发起者对程序文件是否拥有执行权限
启动为经常后,其进程的属主为原程序文件的属主
SUID只对二进制可执行进程有效
SUID设置在目录上无意义
SUID权限设定:
chmod u+s FILE...
chmod 6xxx FILE
chmod u-s FILE...
范例:
ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 27832 Jun 10 2014 /usr/bin/passwd #rws -->s本来是x执行权限,被s盖住了,s表示任何用户都可以执行该文件
12.4.2 特殊权限SGID
可执行文件上SGID权限功能:
任何一个可执行程序文件能不能启动为进程:取决于发起者是否拥有执行权限
启动为进之后,其进程的属组为源程序的属组
SGID权限设定:
chmod g+s FILE...
chmod 2xxx FILE
chmod g-s FILE...
目录上的SGID权限功能:
默认情况下,用户创建文件时,其属组为此文件所属的主组,一旦某目录被设定了SGID,则对目录有写权限的用户在此目录中创建的文件所属的组为此目录的属组,通常用于创建一个协作目录
SGID权限设定:
chmod g+s DIR...
chmod 2xxx DIR...
chmod g-s DIR...
12.4.3 特殊权限Sticky位
具有写权限的目录用户可以删除该用户中的任何文件,无论该文件的权限拥有权在目录设置Sticky位,只有文件的所有者或root可以删除该文件sticky设定在文件上无意义:
Sticky(sitei可rui)权限设定:
chmod o+t DIR...
chmod 1xxx DIR
chmod o-t DIR...
范例:
ll -d /tmp
12.4.4 特殊权限数字法
SUID SGID STICKY
| 000 0 |
|---|
| 001 1 |
| 010 2 |
| 011 3 |
| 100 4 |
| 101 5 |
| 110 6 |
| 111 7 |
范例:
chmod 4777 /tmp/a.txt
权限位映射:
SUID:user.占据属主的执行权限位
s:属主具有x权限
S:属主没有x权限
SGID:group,占据属组的执行权限位
s:group拥有x权限
S:group没有x权限
Sticky:other,占据other的执行权限位
t:other拥有x权限
T:other没有x权限
12.5 设定文件特殊属性
设置文件特殊属性:可以防止root用户误操作删除或修改文件
不能删除,改名,更改
chattr +i
去掉这个特殊属性
chattr -i
只能追加内容
chattr +a
显示特定属性
lsattr
范例:
chattr +i dir
lsattr dir
lsattr * #查看当前目录中文件的属性
ll
rm -rf dir
lsattr #查看当前目录下的属性
12.6 访问控制列表
12.6.1 ACL权限功能
ACL:Access Control List(访问控制列表),实现灵活的权限管理,除了文件的所有者,所属组和其它人,可以对更多的用户设置权限
CentOS7默认创建的xfs和ext4文件系统具有ACL功能
CentOS7之前版本,默认手工创建的ext4文件系统无ACL功能,需手动增加
tune2fs - acl /dev/sdb1
mount -o acl /dev/sdb1 /mnt/test
ACL生效顺序:
所有者 --> 自定义用户 --> 所属组|自定义组 --> 其它人
12.6.2 ACL相关命令
setfacl 可以设置ACL权限
getfacl 可以查看设置的ACL权限
范例:
mount -o acl /directory
getfacl file | directory
setfacl -m u:wang:rwx file|directory
setfacl -m g:admins:rw file| directory
setfacl -x u:wang file | directory
#清楚所有ACL权限
setfacl -b file1
#复制file1的acl权限给file2
getfacl file1 | setfacl --set-file=- file2
mask权限
mask只影响除所有者和other的之外的人和组的最大权限
mask需要与用户的权限进行逻辑与运算后,才能变成有限的权限(Effective Permission)
用户或组的设置必须存在于mask权限设定范围内才会生效
范例:
setfacl -m mask::rx file
--set 选项会把原有的ACL项都删除,用新的替代,需要注意的是一定要包含UGO的设置,不能像-m一样只是添加ACL就可以
范例:
setfacl --set u::rw,u:wang:rw,g::r,o::- file1
12.6.3 备份和还原ACL
主要的文件操作命令cp和mv都支持ACL,只是cp命令需要加上-p参数,但是tar等常见的备份工具是不会保存目录和文件的ACL信息
范例:
#备份ACL
getfacl -R /tmp/dir > acl.txt
#消除ACL权限
setfacl -R -b /tmp/dir
#还原ACL权限
setfacl -R --set-file=acl.txt /tmp/dir
#还原ACL权限
setfacl --restore acl.txt
#查看ACL权限
getfacl -R /tmp/dir
12.6.4 练习
1、在/testdir/dir/里面创建的新文件件自动属于webs组,组apps的成员如:tomcat能对这些新文件有读写权限,组dbs的成员如:mysql只能对新文件有读权限,其他用户(不属于webs,apps,dbs)不能访问这个文件夹
mkdir -p /testdir/dir; chgrp webs /testdir/dir; chmod g+s /test/dir; setfacl -m g:apps:rw /testdir/dir;setfacl -m g:dbs:r /testdir/dir; chmod o= /testdir/dir
2、备份/testdir/dir里面所有文件的ACL权限到/root/acl.txt中,清除/testdir/dir中所有ACL权限,最后还原ACL权限
getfacl -R /testdir/dir > /root/acl.txt; setfacl -b /testdir/dir; setfacl -R –set-file=acl.txt /testdir/dir
13. 文本处理工具和正则表达式
13.1 文本编辑工具之神VIM
13.1.1 vi和vim简介

在LInux中我们经常编辑修改文本文件,即由ASCII,Unicode或其它编码的存文件的文件。之前介绍过nano,实际工作中我们会使用更为专业,功能强大的工具
文本编辑种类:
全屏编辑器:nano(字符工具),gedit(图形化工具),vi vim
行编辑器:sed
- vi
Visual editor(可视化编辑器),文本编辑器,是Linux必备工具之一,功能强大,学习曲线较陡峭,学习难度大
- vim
Visaul editor iMproved(可视化编辑器增强版),和vi使用方法一致,但功能更为强大,不是必备软件
官网:www.vim.org
vim小抄

13.2 使用vim初步
13.2.1 vim格式
vim --help
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Dec 15 2020 16:44:08)
usage: vim [arguments] [file ..] edit specified file(s)
or: vim [arguments] - read text from stdin
or: vim [arguments] -t tag edit file where tag is defined
or: vim [arguments] -q [errorfile] edit file with first error
常用选项:
| +# | 打开文件后,让光标出于第#行的行首,+默认行尾 |
|---|---|
| +/PATTERN | 让光标处于第一个被PATTERN匹配到的行行首 |
| -b file | 二进制方式打开文件 |
| -d file1 file2... | 比较多个文件 |
| -m file | 只读打开文件 |
| -e file | 直接打开ex模式,相当于执行ex file |
说明:
如果文件不存在,文件被打开并显示内容
如果该文件不存在,当编辑后第一次存盘时创建它
13.2.2 三种主要模式和转换
vim是一模式编辑器,击键行为是依赖于vim的”模式“
三种常见模式:
命令或普通(Normal)模式:默认模式,可以实现移动光标,剪切/粘贴文本
插入(Insert)或编辑模式:用于修改文本
扩展命令(extended command)或命令行(末)模式:保存,退出等
模式转换

命令模式-->插入模式
| i | insert,在光标所在处输入 |
|---|---|
| I | 在当前光标所在行的行首输入 |
| a | append,在光标后所在处后面输入 |
| A | 在当前光标所在行的行尾输入 |
| o | 在当前光标所在行的下方打开一个新行 |
| O | 在当前光标所在行的上方打开一个新行 |
插入模式--ESC---> 命令模式
命令模式--:---> 扩展命令模式
扩展命令模式--ESC,enter---> 命令模式
13.3 扩展命令模式
按”:“进入Ex模式,创建一个命令提示符:处于底部的屏幕左侧扩展
命令(末行)模式常见命令
| w | 写(存)磁盘文件 |
|---|---|
| wq | 写入并退出 |
| x | 写入并退出 |
| q | 退出 |
| q! | 不存盘退出,即使更改都将丢失 |
| r | filename 读文件内容到当前文件中 |
| w | filename 将当前文件内容写入另一个文件 |
| ! | command 执行命令 |
| r! | command读入命令的输出 |
13.4 命令模式
命令模式功能强大,只是按键时,看不到输入,所以需要大量的记忆才能更好使用。
13.4.1 退出VIM
| ZZ | 保存退出 |
|---|---|
| ZQ | 不保存退出 |
13.4.2 光标跳转
字符间跳转:
| h | 左 |
|---|---|
| l | 右 |
| j | 下 |
| k | 上 |
#COMMAND:跳转由#指定的个数的字符
单词间跳转:
| w | 下一个单词的词首 |
|---|---|
| e | 当前或下一单词的词尾 |
| b | 当前或前一个单词的词首 |
当前页跳转:
| H | 页首 |
|---|---|
| M | 页中间行 |
| L | 页底 |
| zt | 将光标所在当前行移动到屏幕顶端 |
| zz | 将光标所在当前行移动到屏幕中间 |
| zb | 将光标所在当前行移动到屏幕底端 |
行首行尾跳转:
| ^ | 跳转至行首的第一个非空白字符 |
|---|---|
| 0 | 跳转至行首 |
| $ | 跳转至行尾 |
行间移动:
| #G | 或者扩展命令模式下 |
|---|---|
| # | 跳转至由第#行 |
| G | 最后一行 |
| 1G,gg | 第一行 |
句间移动:
| ) | 下一句 |
|---|---|
| ( | 下一句 |
| } | 下一段 |
| { | 上一段 |
命令模式翻屏操作
| Ctrl +f | 向文件尾部翻一屏 |
|---|---|
| Ctrl +b | 向文件首部翻一屏 |
| Ctrl +d | 向文件尾部翻半屏 |
| Ctrl +u | 向文件首部翻半屏 |
13.4.3 字符编辑
| x | 删除光标处的字符 |
|---|---|
| #x | 删除光标处起始的#个字符 |
| xp | 交换光标所在处的字符及其后面字符的位置 |
| ~ | 转换大小写 |
| J | 删除当前行后的换行符 |
13.4.4 替换命令(replace)
| r | 替换光标所在处的字符 |
|---|---|
| R | 切换成REPLACE模式,按ESC返回命令模式 |
13.4.5 删除命令(delete)
| d | 删除命令,可结合光标转字符,实现范围删除 |
|---|---|
| d$ | 删除到行尾 |
| d^ | 删除到非空行首 |
| d0 | 删除到行首 |
| dw | |
| de | |
| db | |
| #COMMAND | |
| dd | 删除(其实是剪切)光标所在行 |
| #dd | 多行删除 |
| D | 从当前光标位置一直删除到行尾,等同于d$ |
13.4.6 复制命令(yank)
| y | 复制,行为相似于d命令 |
|---|---|
| y$ | |
| y0 | |
| y^ | |
| ye | |
| yw | |
| yb | |
| #COMMAND | |
| yy | 复制行 |
| #yy | 复制多行 |
| Y | 复制整行 |
13.4.7 粘贴命令(paste)
| p | 缓冲区存的如果为整行,则粘贴当前光标所在行的下方;否则,粘贴至当前光标所在处的后面 |
|---|---|
| P | 缓冲区存的如果为整行,则粘贴当前光标所在行的上方;否则,则粘贴至当前光标所在处的前面 |
13.4.8 改变命令(change)
| c: | 删除后切换成插入模式 |
|---|---|
| c$ | |
| c^ | |
| c0 | |
| cb | |
| ce | |
| cw | |
| #COMMAND | |
| cc | 删除当前行并输入新内容,相当于S |
| #cc | |
| C | 删除当前光标到行尾,并切换成插入模式 |
命令模式操作文本总结

13.4.9 查找
| /PATTERN | 从当前光标所在处向文件尾部查找 |
|---|---|
| ?PATTERN | 从当前光标所在处向文件首部查找 |
| n | 与命令同方向 |
| N | 与命令反方向 |
13.4.10 撤销更改
| u | 撤销最近的更改(只要不退出文件就可以一直撤销) |
|---|---|
| #u | 撤销之前多次更改 |
| U | 撤销光标落在这行后所有此行的更改 |
| Ctrl + r | 重复做最后的”撤销“更改 |
| . | 重复前一个操作 |
| #. | 重复前一个操作#次 |
13.4.11 高级用法
常见Command:y复制、d删除、gU变大写、gu变小写
范例:
| 0y$ | 命令 |
|---|---|
| 0 | 先到行头 |
| y | 从这里开始拷贝 |
| $ | 拷贝到本行最后一个字符 |
范例:粘贴”wang“100次
100 iwang 按2次[ESC] #在命令模式直接输入
常见用法
| di" | 光标在”“之间,则删除”“之间的内容 |
|---|---|
| yi( | 光标在()之间,则复制()之间的内容 |
| vi[ | 光标在[]之间,则选中[]之间的内容 |
| dtx | 删除字符知道遇见光标之后的第一个x字符 |
| ytx | 复制字符知道遇见光标之后的第一个x字符 |
范例:
(aaaaaaaaaaaaaa)
命令模式输入di( #就会把括号中的所有内容删除
13.5 扩展命令模式
13.5.1 地址定界
格式:
:sart_pos,end_pos
常见用法
| # | 具体第#行,例如2表示第2行 |
|---|---|
| #,# | 从左侧#表示开始行,到右侧#表示结尾行 |
| #,+# | 从左侧#表示的起始行,加上右侧#表示的行数,范例:2,+3表示2到5行 |
| . | 当前行 |
| $ | 最后一行 |
| .,$-1 | 当前行到倒数第二行 |
| % | 全文,相当于1,$ |
| /pattern/ | 匹配pattern的行 |
| /pat1/,/pat2/ | 从第一次被pat1模式匹配到的行开始,一直到第一次被pat2匹配到的行结束 |
| #./pat/ | |
| /pat/,$ | |
| 地址定界后跟一个编辑命令d y | |
| w file | 将范围内的行另存指定文件中 |
| r file | 在指定位置插入指定文件中的所有内容 |
范例:删除所有内容
:.,$ #从当前行删到最后一行
:%d #%代表所有
13.5.2 查找并替换
格式
s/要查找的内容/替换为的内容/修饰符 #默认替换行首的匹配字符,除非加g修饰符全局替换
要查找的内容:可使用正则表达式模式
要替换为的内容:不能使用模式,但可以使用\1,\2,... 等后向引用符号;还可以使用”&“引用前面查找时查找到的整个内容
修饰符:
i 忽略大小写
g 全局替换,默认情况下,每一行只替换一次出现
gc 全局替换,每次替换前询问
说明:查找替换中的分隔符/可替换为其它字符,如#@
范例:
s@/etc@/var@g
s#/boot#/#i
13.6 可视化模式
允许选择的文本块,可视化键可用于移动键结合使用
| v | 面向字符 |
|---|---|
| V | 面向行 |
| ctrl v | 面向块 |
可视化键可用于与移动键结合使用
w ) }箭头等
突出显示的文字可被删除,复制,变更,过滤,搜索,替换等
范例:在文件行首插入#
输入ctrl+v 进入可视化模式
输入G 跳到最后1行,选中第一行
输入I 切换插入模式
输入#
按2次ESC键
13.7 多文件模式
vim FILE1 FILE2 FILE3...
| :next | 下一个 |
|---|---|
| :prev | 前一个 |
| :first | 第一个 |
| :last | 最后一个 |
| :wall | 保存所有 |
| :qall | 退出所有 |
| :wqall |
13.8 多窗口模式
13.8.1 多文件分割
vim -o | -O FILE1 FILE2...
| -o | 水平上下分割 |
|---|---|
| -O | 垂直左右分割 |
在窗口间切换:Ctrl+w,Arrow
13.8.2单文件窗口分割
常用选项
| Ctrl +w,s | split,水平分割 |
|---|---|
| Ctrl+w,v | vertical,垂直分割 |
| ctrl+w,q | 取消相邻窗口 |
| ctrl+w,o | 取消全部传课 |
| :wqall | 退出 |
13.9 vim的寄存器
有26个命名寄存器和1个无命名寄存器,常存放不同的剪贴版内容,可以不同会话间同享寄存器名称a,b,...z格式:”寄存器 放在数字和命令之间“
如:3”tty表示复制3行到t寄存器中
”tp 表示将t寄存器内容粘贴
未指定,将使用无命名寄存器,有10个数字寄存器,用0,1,...,9表示,0存放最近复制内容,1存放最近删除内容。当心的文本变更和删除时,1转存到2,2转存到3,以此类推。数字寄存器不能再不同会话间共享
13.10 标记和宏(macro)
常用操作
| ma | 将当前位置标记为a,26个字母均可做标记,mb、mc等等 |
|---|---|
| 'a | 跳转到a标记的位置,实用的文档内标记方法,文档中跳跃编辑时很有用 |
| qa | 录制宏a, a为宏的名称 |
| @a | 执行宏a |
| @@ | 重新执行上次执行的宏 |
13.11 编辑二进制文件
# 以二进制方式发开文件
vim -b binaryfile
#扩展命令模式下,利用xxd命令转换为可读的十六进制
:%!xxd -r
#保存退出
13.12 定制vim的工作特性
| 配置文件 | 永久有效 |
|---|---|
| 全局 | /etc/vimrc |
| 个人 | ~./vimrc |
扩展命令模式:当前vim进程有效
13.12.1行号
| 显示 | set number,简写set nu |
|---|---|
| 取消显示 | set nonumber,简写set nonu |
13.12.2忽略字符的大小写
| 启用 | set ignorecase,简写set ic |
|---|---|
| 不忽略 | set noic |
13.12.3自动缩进
| 启用 | set autoindent,简写set ai |
|---|---|
| 不忽略 | set noai |
13.12.4 复制保留格式
| 启用 | set paste |
|---|---|
| 不忽略 | set nopaste |
13.12.5 显示Tab和换行符^|和$显示
| 启用 | set list |
|---|---|
| 不忽略 | set nolist |
13.12.6 高亮搜索
| 启用 | set hlsearch |
|---|---|
| 不忽略 | set nohlsearch,简写, noh |
13.12.7语法高亮
| 启用 | syntax on |
|---|---|
| 不忽略 | syntax off |
13.12.8 文件格式
| 启用windows格式 | set fileformat=dos |
|---|---|
| 启用unix格式 | set fileformat=unix |
| 简写 | set ff=dos |unix |
13.12.9设置文本宽高
| set textwidth=65(vim only) |
|---|
| set wrapmargin=15 |
13.12.10 设置光标所在行的标识线
| 启用 | set cursorline,简写set cul |
|---|---|
| 不忽略 | set nocul |
13.12.11 了解更多
set帮助,使用vimtutor命令直接进入vim帮助页面
| :help option-list |
|---|
| :set or :set all |
| vi/vim 内置帮助 |
| :help |
| :help topic |
| Use :q to exit help |
13.12.13 练习
1、在vim中设置tab缩进的4个字符
vim
^I^I^I^I
2、复制/etc/rc.d/init.d/functions文件至/tmp目录,替换/tmp/functions文件中的/etc/sysconfig/init为/var/log
cp /etc/rc.d/init.d/functions /tmp ; vim /tmp/functions
:%s#/etc/sysconfig/init#/var/log#
3、删除/tmp/functions文件中所有以#开头,且#后面至少有一个空白字符的行的行首的#号
vim /tmp/functions
ctrl v
→
G
x
:wq
14. 文本常见处理工具
14.1 文件内容查看命令
14.1.1 查看文本文件内容
cat 可以查看文本内容
格式:
cat --help
Usage: cat [OPTION]... [FILE]...
Concatenate FILE(s), or standard input, to standard output.
常见选项:
| -E | 显示行结束符$ |
|---|---|
| -n | 对显示出的每一行进行编号 |
| -A | 显示所有控制符 |
| -b | 非空行编号 |
| -s | 压缩连续的空行成一行 |
| tac | 逆向显示文本内容 |
| nl | 显示行号,相当于cat -b |
| rev | 将同一行的内容逆向显示 |
14.1.2 查看非文本文件内容
14.1.2.1 hexdump
范例:十六进制显示内容
hexdump -C -n 512 /dev/sda #-n指定显示行数
00000000 eb 63 90 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0 |.c..............|
00000010 fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00 |...|.........!..|
00000020 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75 |....8.u........u|
hexdump shadow -C
00000000 72 6f 6f 74 3a 24 36 24 5a 75 37 57 73 77 58 74 |root:$6$Zu7WswXt|
00000010 7a 52 45 62 6f 30 5a 32 24 57 78 6c 54 6c 66 68 |zREbo0Z2$WxlTlfh|
00000020 2f 67 30 39 45 58 7a 75 58 69 67 57 44 48 31 33 |/g09EXzuXigWDH13|
00000030 70 6e 63 76 51 4f 6c 63 68 46 65 66 35 75 2f 57 |pncvQOlchFef5u/W|
echo -e "Asahi \r \n 666" | tr -d ' ' |hexdump -C #tr -d ' '删除空格
00000000 41 73 61 68 69 0d 0a 36 36 36 0a |Asahi..666.
14.1.2.2 od
od即dump files in octal(8进制) and other formats
范例:
echo {a..z} | tr -d ' '|od -t x1z #-t设置查看格式
14.1.2.3 xxd
echo {a..z} |tr -d ' ' |xxd #以十六进制查看,并删除空格
14.2 分页查看文件内容
more查看实现分页查看文件,可以配合管道实现输出信息的分页(缺点:到底自动退出)
格式
more --help
more: unknown option -help
Usage: more [options] file...
选项:
| -d | 显示翻页及退出提示 |
|---|
less 也可以实现分页查看文件或STDIN输出
查看时有用的命令包括:
| /文本 | 搜索文本 |
|---|---|
| n/N | 跳到下一个或上一个匹配 |
| less | 命令式man命令使用的分页器 |
范例:
cat /etc/init.d/functions | less
14.3 显示文本或后行内容
head 可以显示文件或标准输入的前面行
格式:
head --help
Usage: head [OPTION]... [FILE]...
Print the first 10 lines of each FILE to standard output.
With more than one FILE, precede each with a header giving the file name.
With no FILE, or when FILE is -, read standard input.
选项:
| -c# | 指定获取前#字节 |
|---|---|
| -n# | 指定获取前#行 |
| -# | 同上,-n#简写版 |
范例:使用head取10个随机字符生成口令
cat /dev/urandom | tr -dc '[:alnum:]' | head -c 10 #-c补集,-d删除,[:alnum:]数字和大小写字母,urandom随机字符设备文件
cat /dev/urandom | tr -dc '[:alnum:]' | head -c 10 | tee passwd.txt | passwd --stdin mage #把生成的密码tee输出到paaswd文件中,再通过管道传给passwd 设置成mage用户的密码
tail 和head 相反,查看文件或标准输入的倒数行
格式:
tail --help #默认查看后10行
Usage: tail [OPTION]... [FILE]...
Print the last 10 lines of each FILE to standard output.
With more than one FILE, precede each with a header giving the file name.
With no FILE, or when FILE is -, read standard input.
常用选项:
| -c # | 指定获取后#字节 |
|---|---|
| -n # | 指定获取后#行 |
| -# | 同上,简写版 |
| -f | 跟踪显示文件df新追加的内容,常用日志监控,相当于--foloow=descriptor(跟踪文件描述符),默认不退出,且查看后10行 |
| -F | 跟踪文件名,相当于--follow=name (跟踪文件名)--retry,当文件删除时,再新建同名文件可以继续跟踪,跟上面相反 |
tailf 类似tail -f,当文件不增长时并不访问文件
范例:通过head和tail过滤出ip段
ip a |cat -n
ip a |head -9 |tail -1
14.4 按列抽取文本
cut命令可以提取文本文件或STDIN数据的指定列
格式
cut --help
Usage: cut OPTION... [FILE]...
Print selected parts of lines from each FILE to standard output.
常用选项:
| -d | DELIMITER指明分隔符,默认tab |
|---|---|
| -f | FILEDS(fuyouzi,域也就是列) |
| #:第#个字段 | |
| #,#[#]:离散的多个字段,例如1,3,6 | |
| #-#:连续的多个字段,例如1-6 | |
| 混合使用:1-3,7 | |
| -c | 按字符切割 |
| --output-delimiter=STRING | 指定输出分隔符 |
范例:使用cut命令取出指定列
cut -d: -f1 /etc/passwd
cat /etc/passwd |cut -d: -f7
cut -c2-5 /usr/share/dict/words
范例:使用cut取出本机ip地址
ip a |head -9 |tail -1 |cut -d' ' -f6 #但是现在这个过滤不能每台主机都能取出对应值
192.168.5.220/24
范例:使用cut取出利用率(方法一)
df |tr -s ' '|cut -d' ' -f5|tr -d % |tr -d [A-z] #tr -s 替换重复字符 为 ' ',指定分隔符为%,刚好使用率后面有%,-d删除指定字符
57
0
0
1
0
26
0
范例:方法(二)
df | tr -s ' ' %|cut -d% -f5| tr -d '[:alpha:]'
57
0
0
1
0
26
0
14.5 合并多个文件
paste合并多个文件同行号的列到一行
格式
paste --help
Usage: paste [OPTION]... [FILE]...
Write lines consisting of the sequentially corresponding lines from
each FILE, separated by TABs, to standard output.
With no FILE, or when FILE is -, read standard input.
常用选项
| -d | 分隔符(只能写一个),指定分隔符,默认用TAB |
|---|---|
| -s | 所有行合成一行显示 |
纵向合并
cat abc.txt bac.txt >> 123.txt #会把两个文件内容纵向合并在一起
横向合并
paste abc.txt bac.txt #直接横向合并在一起
14.6 分析文本的工具
| wc | 文本数据统计 |
|---|---|
| sort | 整理文本 |
| diff和patch | 比较文件 |
14.6.1 收集文本统计数据
wc命令可用于统计文本的行总数、单词总数、字节总数、和字符总数,可以对文件或STDIN中的数据统计
范例:
wc shadow
21 21 644 shadow
行数 单词数 字节数 文件名
常用选项:
| -l | 只计数行数 |
|---|---|
| -w | 只计数单词总数 |
| -c | 只计数字节总数 |
| -m | 只统计字符数(汉字也算一个字符) |
| -L | 显示文件中最长行的长度(显示的字符数包括空格) |
范例:去除df中第一行
df |tail -$(echo $(df |wc -l)-1 |bc) #echo标准输出8-1通过管道传给bc作为tail 显示的倒行数
/dev/mapper/centos-root 37300436 21249864 16050572 57% /
devtmpfs 1923064 0 1923064 0% /dev
tmpfs 1933472 0 1933472 0% /dev/shm
tmpfs 1933472 8904 1924568 1% /run
tmpfs 1933472 0 1933472 0% /sys/fs/cgroup
/dev/sda1 508588 127568 381020 26% /boot
tmpfs 386696 0 386696 0% /run/user/0
14.6.2 文本排序sort
sort(搜而特)把整理过的文本显示在STDOUT,不改变原始文件
格式:
sort --help
Usage: sort [OPTION]... [FILE]...
or: sort [OPTION]... --files0-from=F
Write sorted concatenation of all FILE(s) to standard output.
常用选项
| -r | 执行反方向(由上至下)整理 |
|---|---|
| -R | 随机排序 |
| -n | 执行按数字大小整理 |
| -f | 选项忽略(fold)字符串中的字符大小写 |
| -u | 选项(独特,unique)删除输出中的重复行 |
| -t c | 选项使用c作为字段界定符 |
| -k # | 选项按照使用c字符分隔的#列来整理能够使用多次 |
范例:使用排序方法过滤df使用率最大值
df |tr -s ' ' %|cut -d'%' -f5|tr -d '[:alpha:]'|sort -n|tail -1 #-n按数字大小排
57
df |tr -s ' ' %|cut -d'%' -f5|tr -d '[:alpha:]'|sort -nr |head -1 #按倒序数字大小排,-s压缩重复字符为' '
57
14.6.3 去重uniq
uniq(由内可)命令从输入中删除前后相接的重复行
格式:
uniq --help
Usage: uniq [OPTION]... [INPUT [OUTPUT]]
Filter adjacent matching lines from INPUT (or standard input),
writing to OUTPUT (or standard output).
常见选项:
| -c | 显示每行重复出现的次数 |
|---|---|
| -d | 仅显示重复过的行 |
| -u | 仅显示不曾重复的行 |
uniq常和sort命令一起配合使用:
范例:
sort userlist.txt |uniq -c
范例:把两个文件中相同的行去掉、不相同的行统计出来
echo -e "aa\nbb\ncc" > f1.txt
echo -e "bb\ncc\nab" > f2.txt
cat f1.txt f2.txt | sort |uniq -c
1 aa
1 ab
2 bb
2 cc
cat f1.txt f2.txt | sort |uniq -d
bb
cc
cat f1.txt f2.txt | sort |uniq -u
aa
ab
14.6.4 比较文件
diff(di付)命令比较两个文件之间的区别
cat f1.txt
cat f2.txt
diff -u f1.txt f2.txt
复制对文件改变patch
diff命令的输出被保存在一种叫做“补丁”的文件中
使用-u选项来输出“统一”的(unified)"diff"格式文件,最适合用于补丁文件
patch 复制在其它文件中进行的改变(要谨慎使用)
使用-b选项来自动备份改变了的文件
范例:
diff -u foo.conf foo2.conf > foo.patch
patch -b foo.conf foo.patch #-b选项为备份,补丁恢复出来的之前的foo2.conf会被重命名为foo.conf,而foo.conf会被重命名为foo.orig
范例:查看二进制文件的不同
cmp /bin/dir /bin/ls
hexdump -s 730 -Cn 7 /bin/dir #-s跳过第730个字节,-n查看7个字节,-C显示ASCII码
hexdump -s 730 -Cn 7 /bin/ls
练习
1、找出ifconfig“网卡名”命令结果中本机的IPV4地址
ifconfig ens34 |head -2|tail -1|tr -s ' '|cut -d' ' -f3
192.168.5.220
2、查出分区空间使用率的最大百分比值
df |tr -s ' ' %|cut -d'%' -f5|tr -d '[:alpha:]'| sort -n |tail -1
58
3、查出用户UID最大值的用户名、UID及shell类型
sort -t: -n -k3 /etc/passwd| tail -1|cut -d: -f 1,3,7 #sort -t指定分隔符,-n按数字从小到大排序,-k选择第三列
systemd-bus-proxy:999:/sbin/nologin
4、查出/tmp的权限,以数字方式显示
stat /tmp/ |head -4|tail -1|cut -d'(' -f2|cut -d'/' -f1
1777
5、统计当前连接本机的每个远程主机IP的连接数,并按从大到小排序
w -h | tr -s " " | cut -d " " -f3 | uniq -c | sort -rn #uniq去除列表中重字符 -c统计次数
15. 正则表达式
REGEXP:Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能正则表达式被很多程序和开发语言所广泛支持:vim,less,grep,sed,awk,nginx,mysql等
正则表达式分两类:
基本正则表达式:BRE
扩展正则表达式:ERE
正则表达式引擎:
采用不同算法,检查处理正则表达式的软件模块,如:PCRE(Perl Compatible Regular EXpressions)
正则表达式的元字符分类:字符匹配、匹配次数、位置锚定、分组
帮助:man 7 regex
15.1 基本正则表达式元字符
15.1.1 字符匹配
| . | 匹配任意单个字符 |
|---|---|
| [] | 匹配指定范围内的任意单个字符,实例:[wang] [0-9] [a-z](正则表达式中代表所有字母) [a-zA-Z] |
| [^] | 匹配指定范围外的任意单个字符 |
| [:alnum:] | 字母和数字 |
| [:alpha:] | 代表任何英文大小写字符,即A-Z,a-z |
| [:lower:] | 小写字母,示例:[[:lower:]],相当于[a-z] |
| [:blank:] | 空白字符(空格和制表符) |
| [:space:] | 水平和垂直的空白字符(比[:blank:]包含的范围广) |
| [:cntrl:] | 不可打印的控制字符(退格、删除、警铃...) |
| [:digit:] | 十进制数字[:xdigit:]十六进制数字 |
| [:graph:] | 可打印的非空白字符 |
| [:print:] | 可打印字符 |
| [:punct:] | 标点字符 |
15.1.2 匹配次数
用在要指定次数的字符后面,用于指定前面的字符要出现的次数
| * | 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配 |
|---|---|
| .* | 任意长度的任意字符 |
| ? | 匹配其前面的字符0或1次,即:可有可无 |
| + | 匹配其前面的字符至少1次,即:肯定有 |
| 匹配前面的字符n次 | |
| 匹配前面的字符最少m次,最多n次 | |
| 匹配前面的字符最多n次 | |
| 匹配前面的字符最少n次 |
15.1.3 位置锚定
位置锚定可以用于定位出现的位置
| ^(托字符) | 行首锚定,用于模式的最左侧 |
|---|---|
| $ | 行尾锚定,用于模式的最右侧 |
| ^PATTERN$ | 用于模式匹配整行 |
| ^$ | 空行 |
| [1]*$ | 空白行 |
| <或\b | 词首锚定,用于单词模式的左侧 |
| >或\b | 词尾锚定,用于单词模式的右侧 |
| <PATTERN> | 匹配整个单词 |
15.1.3 分组其它
分组:()将一个或多个字符捆绑在一起,当作一个整体处理,如:(root)+
分组括号中的模式匹配的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1,\2,\3,...\1表示从左侧起第一个左括号以及只匹配右括号之间的模式所匹配到的字符
示例:
(string1\(string2)\)
\1 : string1\(string2\) #分组相当于重复利用,只需要写一次在s/中/替换内容/,\1替换值:表示替换加到后面,替换值\1,表示替换加到前面
\2 : string2
后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身
或者:\
范例:修改openrc中的指定字符
:%s@\(PASS=\)000000@\1123456@ #把原为PASS=000000,替换成PASS=123456,\1表示后向引用的值,也就是分组值
实例:
a\|b #a或b
C\|cat #C或cat
\(C\|c\)cat #Cat或cat
正则表达式练习
1、显示/proc/meminfo文件中以大小s开头的行(要求:使用两种方法)
grep -i '^s' /proc/meminfo #-i忽略大小写
grep '^[sS]' /proc/meminfo
2、显示/etc/passwd文件中不以/bin/bash结尾的行
grep -v '/bin/bash$' /etc/passwd
3、显示用户rpc默认的shell程序
grep '^rpc\>' /etc/passwd |cut -d':' -f6 #\>定义这个单词的结尾,\<rpc\>,\<定义单词的开始
4、找出/etc/passwd中的两位或三位数
grep "\<[0-9]\{2,3\}\>" /etc/passwd
5、显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面有非空字符的行
grep -E '^[[:space:]]+[^[:space:]]+' /etc/grub2.cfg
6、找出“netstat -tan”命令结果中以LISTEN后跟任意多个空白字符结尾的行
netstat -ant |grep -E 'LISTEN[[:space:]]+$'
7、显示CentOS7上所有UID小于1000内的用户名和UID
cat /etc/passwd |cut -d':' -f 1,3 |grep '\<[0-9]\{1,3\}\>'
8、添加用户bash、testbash、basher、sh、nologin(其shell为/sbin/nologin),找出/etc/passwd用户名和shell同名的行
9、利用df和grep,取出磁盘各分区利用率,并从大到小排序
15.2 扩展正则表达式
15.2.1 字符匹配元字符
| . | 匹配任意单个字符 |
|---|---|
| [] | 匹配指定范围内的任意单个字符,实例:[wang] [0-9] [a-z](正则表达式中代表所有字母) [a-zA-Z] |
| [^] | 匹配指定范围外的任意单个字符 |
| [:alnum:] | 字母和数字 |
| [:alpha:] | 代表任何英文大小写字符,即A-Z,a-z |
| [:lower:] | 小写字母,示例:[[:lower:]],相当于[a-z] |
| [:blank:] | 空白字符(空格和制表符) |
| [:space:] | 水平和垂直的空白字符(比[:blank:]包含的范围广) |
| [:cntrl:] | 不可打印的控制字符(退格、删除、警铃...) |
| [:digit:] | 十进制数字[:xdigit:]十六进制数字 |
| [:graph:] | 可打印的非空白字符 |
| [:print:] | 可打印字符 |
| [:punct:] | 标点字符 |
15.2.2 次数匹配
| * | 匹配前面字符任意次 |
|---|---|
| ? | 0或1次 |
| + | 1次或多次 |
| 匹配n次 | |
| 至少m,至多n次 |
15.2.3位置锚定
| ^ | 行首 |
|---|---|
| $ | 行尾 |
| <,\b | 语首 |
| >,\b | 语尾 |
15.2.4 分组其它
| () | 分组 |
|---|---|
| \1,\2 | 后者应用:\1,\2,... |
| | | 或者 |
| a|b | #a或b |
| C|cat | #C或cat |
| (C|c)at | #Cat或cat |
15.2.5 扩展正则表达式练习
1、显示三个用户root、mage、wang的UID和默认shell
2、找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行
3、使用egrep取出/etc/rc.d/init.d/functions中其基名
4、使用egrep取出上面路径的目录名
5、统计last命令中以root登录的每个主机IP地址登录次数
6、利用扩展正则表达式分别表示0-9、10-99、100-199、200-249、250-255
7、显示ifconfig命令结果中所有IPv4地址
8、将此字符串:welcome to magedu linux 中的每个字符去重并排序,重复次数多的排到前面
16. 文本处理三剑客
grep:命令主要对文本的(正则表达式)行基于模式进行过滤
sed:stream editor,文本编辑工具
awk:Linux上的实现gawk,文本报告生成器
16.1 文本处理三剑客之grep
grep:Global search REgular expression and Print out the line
作用:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行
模式:由正则表达式字符及文本字符所编写的过滤条件
格式:
grep --help
Usage: grep [OPTION]... PATTERN(模式) [FILE]...
Search for PATTERN in each FILE or standard input.
PATTERN is, by default, a basic regular expression (BRE).
Example: grep -i 'hello world' menu.h main.c
常见选项:
| --color=auto | 对匹配到的文本着色显示 |
|---|---|
| -m # | 匹配#次后停止 |
| -v | 显示不被pattern匹配到的行 |
| -i | 忽略字符大小写 |
| -n | 显示匹配的行号 |
| -c | 统计匹配的行数 |
| -o | 仅显示匹配到的字符串 |
| -q | 静默模式,不输出任何信息 |
| -A # | after,后#行 |
| -B # | before,前#行 |
| -C # | context,前后各#行 |
| -e | 实现多个选项间的逻辑or关系,如:grep -e 'cat' -e 'dog' file |
| -w | 匹配整个单词 |
| -E | 使用ERE,相当于egrep(扩展正则表达式) |
| -F | 相当于fgrep,不支持正则表达式 |
| -f file | 根据模式文件处理 |
| -r | 递归目录,但不处理软链接(过滤整个文件夹下的文本内容) |
| -R | 递归目录,但处理软链接 |
范例:取分区利用率
df |grep '^/dev/sd' |tr -s ' ' %|cut -d'%' -f5
26
17. SHELL脚本编程基础
17.1 编程基础
Linux:Talk is cheap,show me the code
17.1.1 程序组成
程序:算法+数据结构
数据:是程序的核心
算法:处理数据的方式
数据结构:数据在计算机中的类型和组织方式
17.1.2 程序编程风格
过程式:以指令为中心,数据服务于指令,shell脚本程序提供了编程能力,解释执行
对象式:以数据为中心,指令服务于数据,java,C#,python等
17.1.3 编程语言
计算机:运行二进制指令
编程语言:人与计算机之间交互的语言。分为两种:低级语言和高级语言
低级编程语言:
机器:二进制的0和1的序列,称为机器指令。与自然语言差异太大,难懂、难写
汇编:用一些助记符号替代机器指令,称为汇编语言
如:ADD A,B将寄存器A的数与寄存器B的数相加得到的数存放到寄存器A中
汇编语言写好的程序需要汇编程序换成机器指令
汇编语言稍微好理解,即机器指令对应的助记符,助记符更接近自然语言
高级编程语言:
编译:高级语言-->编译器-->机器代码文件-->执行,如:C,C++
解释:高级语言-->执行-->解释器-->机器代码(内存中),如shell,python,php,javascript,perl
编译和解释型语言

17.1.4 编程逻辑处理方式


顺序执行
选择执行
循环执行
18. shell脚本语言的基本结构
18.1 shell脚本的用途
自动化常用命令
执行系统管理和故障排除
创建简单的应用程序
处理文本或文件
18.2 shell脚本基本结构
shell脚本变成:是基于过程式、解释执行的语言
编程语言的基本结构:
各种系统命令的组合
数据存储:变量、数组
表达式:a+b
控制语句:if
shell脚本:包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行shebang机制(#-->sha !-->bang)
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl (poer)
18.3 创建shell脚本过程
第一步:使用文本编辑器来创建文本文件
第一行必须包括shell声明序列:#!
示例:
#!/bin/bash
添加注释,注释以#开头
第二步:运行脚本
给予执行权限,在命令行上指定脚本的绝对或相对路径
直接运行解释器,将脚本作为解释器程序的参数运行
18.4 脚本范例
1、第一行一般为调用使用的语言
2、程序名、避免更改文件名为无法找到正确的文件
3、版本号
4、更改后的时间
5、作者相关信息
6、该程序的作用,及注意事项
7、最后是个版本的更新简要说明
18.5 第一个脚本
#!/bin/bash
CONFIGURATION_VARIABLES
FUNCTION_DEFINITIONS
MAIN_CODE
shell脚本范例:
#!/bin/bash
#---------------------------
# Filename: hello.sh
# Version: 1.1
# Date: 2017/06/01
# Author: wang
# Email: wang@gmail.com
# Website: www.magedu.com
# Description: This is the first script
# Copyright: 2017 wang
# License: GPL
echo "hello world"
18.6 脚本调试
检测脚本中的语法错误
bash -n /path/to/some_script
调试(可以找逻辑错误)跟踪执行
bash -x /path/to/some_script
18.7 变量
18.7.1变量
变量表示命名的内存空间,将数据存放在内存空间中,通过变量名引用,获取数据
18.7.2 变量类型
变量类型:
内置变量,如PS1,PATH,HISTSIZE
用户自定义变量
不同的变量存放的数据不同,决定了以下
1、数据的存储方式
2、参与的运算
3、表示的数据范围
变量数据类型:
字符
数值:整型、浮点型(bash不支持)
18.7.3 编程语言分类

静态和动态语言
静态编译语言:使用变量前,先声明变量类型,之后类型不能改变,在编译时检查,如:java,c
动态编译语言:不用事先声明,可随时改变类型,如:bash,Python
强类型和弱类型语言
强类型语言:不同类型数据操作,必须警告强制转换才同一类型才能运算,如java,c#,python
如:一下python代码
print('magedu'+ 10)提示出错,不会自动转换类型
print('magedu'+str(10)) 结果为magedu10,需要显示转换类型
弱类型语言:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符类型;参与运算会自动进行隐式类型转换;变量无须先定义可直接调用
如:bash不支持浮点数,php,javascript
18.7.4 Shell中变量命名法则
不能使程序中的保留字:如:if,for
只能使用数字、字母及下划线,且不能以数字开头
见名知义,用英文名字,并体现出实际作用
统一命令规则,驼峰命名法,例如:studentname,大驼峰StudentName,小驼峰studentName
变量名大写
局部变量小写
函数名小写
18.7.5 变量定义和引用
变量的生效范围等标准划分变量类型
普通变量:生效范围为当前shell进程;对当前shell之外的其他shell进程,包括当前shell的子shell进程均无效
环境变量:生效范围为当前shell进程及其子进程
本地变量:生效范围为当前shell进程中某代码片断,通常指函数
变量赋值:
name='value' #=号前后不能有空格
value可以是一下多种形式
直接字串: name='root'
变量引用: name='$USER'
命令引用: name=`COMMAND` 或者 name=$(COMMAND)
变量引用:
${name}
$name
弱引用和强引用
”$name“ 弱引用,其中的变量引用会被替换为变量值
'$name' 强引用,其中的变量引用不会被替换为变量值,而保持源字符串
显示已定义的所有变量:
set
删除变量
unset name
练习
1、编写脚本systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核信息,CPU型号,内存大小,硬盘大小
cat systeminfo.sh
#!/bin/bash
#
#Author: Asahi
#Date: 2021-9-10
#FileName systeminfo.sh
#
COLOR="\033[1;31m" #\033八进制ESC,1;表示高亮,[31m,代表开启红色颜色,[0m,代表关闭颜色
END="\033[0m"
echo -e "\033[1;32m-----------------Host systeminfo-----------------$END"
echo -e "HOSTNAME: $COLOR$(hostname)$END"
echo -e "IPADDR: $COLOR$(ifconfig ens34 |grep "\binet\b" |tr -s ' ' |cut -d' ' -f3)$END"
echo -e "VERSION: $COLOR$(cat /etc/redhat-release )$END"
echo -e "KERNEL: $COLOR$(uname -r)$END"
echo -e "CPU: $COLOR$(lscpu |grep "Model name" |cut -d: -f2|tr -d ' ')$END"
echo -e "MEMORY: $COLOR$(free -h |grep Mem |tr -s ' ' |cut -d' ' -f2) $END"
echo -e "DISK: $COLOR$(lsblk |grep "^sd" |tr -s ' ' |cut -d' ' -f4) $END"
2、编写脚本backup.sh,可实现每日将/etc/目录备份到/backup/etc/YYYY-mm-dd中
3、编写脚本disk.sh,显示当前硬盘分区中空间利用率最大的值
4、编写脚本links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大道小排序
18.7.6 环境变量
变量声明和赋值:
export name=VALUE
declare -x name=VALUE
变量引用:
$name
${name}
显示所有环境变量:
env
printenv
export #同下
declare -x #显示环境变量,也可以定义环境变量
删除变量:
unset name
bash内建的环境变量
PATH
SHELL
USER
UID
HOME
PWD
SHLVL
LANG
MAINL
HOSTNAME
HISTSIZE
_ #下划线,表示前一命令的最后一个参数
18.7.7 只读变量
只读变量:只能声明,但不能修改和删除
声明只读变量:
readonly name #设置为常量,不能改变
declare -r name
查看只读变量:
readonly [-p]
declare -r
18.7.8 位置变量
位置变量:在bash shell中内置的变量,在脚本代码中调用通过命令传递给脚本的参数(让脚本增加参数)
| $1,$2 ... | 对应第1、第2个等参数,shift[n]换位置 |
|---|---|
| $0 | 命令本身,包括路径 |
| $* | 传递给脚本的所有参数,全部参数何为一个字符串 |
| $@ | 传递给脚本的所有参数,每个参数为独立字符串 |
| $# | 传递给脚本的参数的个数 |
注意:$@ $* 只在被双引号包起来的时候才会有差异
清空所有位置变量
set --
范例:
cat scp.sh
#!/bin/bash
COLORS="\033[1;$[RANDOM%7+31]m"
END="\033[0m"
echo -e "$COLORSSTART SCP $END"
scp $1 10.196.110.42:/mnt/data #$1表示只能传一个参数,$*表示可以传很多个
echo -e "$COLORSEND SCP $END"
18.7.9 退出状态码变量
进程执行后,将使用变量$保存状态码的相关数字,不同的值反应成功或失败,$?取值范例0-255
$?的值为0 #表示成功
$?的值是1-255 #表示失败
范例:
ping -c1 -W1 hostdown &> /dev/null #把标准输出、错误重定向进空设备文件(执行命令但是屏幕不显示过程)
echo $? #查看退出码
用户可以在脚本中使用以下命令自定义退出状态码
exit [n]
注意:
脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后的数字
如果未给脚本指定退出码状态,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
18.7.10 展开命令行
展开命令执行顺序
把命令行分成当个命令词
展开别名
展开大括号的声明({})
展开波浪符声明(~)
命令替换$()和``
再次把命令行分成命令词
展开文件通配(*、?、[abc]等等)
准备I/O重导向(<、>)
运行命令
防止扩展
反斜线(\)会使随后的字符按原意解释
范例
echo Your cost: \$5.00
Your cost: $5.00
加引号来防止扩展
单引号('')防止扩展
双引号("")也可以防止扩展,但是一下情况例外:$(美元符号)
变量扩展
``:反引号,命令替换
\:反斜线,进制单个字符扩展
!:叹号,历史命令替换
18.7.11 set命令和脚本安全
set命令:可以用来定制shell环境
$-变量(echo $-)
| h | hashall,打开选项后,Shell会将命令所在的路径hash下来,避免每次都要查询。通过set+h将h选项关闭 |
|---|---|
| i | interactive-comments,包含这个选项说明当前的shell是一个交互式的shell。所谓的交互式shell,在脚本中i选项是关闭的 |
| m | monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等 |
| B | braceexpand,大括号扩展 |
| H | history,H选项打开,可以展开历史列表中的命令,可以通过!来完成,例如"!!"返回上最近的一个历史命令,"!n"返回第n个历史命令 |
set 命令实现脚本安全
help set:查看set帮助,set(内部命令)
| -u | 在扩展一个没有设置的变量时,显示错误信息,等同set -o nounset |
|---|---|
| -e | 如果一个命令返回一个非0退出状态值(失败)就退出,等同set -o errexit |
| -o | option 显示,打开或者关闭选项 |
| 显示选项:set -o | |
| 打开选项: set -o选项 | |
| 关闭选项:set +o选项 | |
| -x | 当执行命令时,打印命令及其参数 |
范例:
set -o
18.8 算术运算
bash中的算术运算
+,-,*,/,%取模(取余),(乘方)
乘法符号有些场景中需要转义
实现算术运算:
(1) let var=算术表达式 #常用
(2) var=$[算术表达式] #常用
(3) var=$((算术表达式))
(4) var=$(expr arg1 arg2 arg3)
(5) declare -i var = 数值
(6) echo '算术表达式' | bc
内建的书籍数生成变量
$RANDOM #取值范围:0-32767,取一定范围内的随机数
范例:
#生成 0 - 49 之间随机数
echo $[$RANDOM%50] #规律就是取模数结果最大=取模数-1
范例:生成随机颜色
echo -e "\033[1;$[RANDOM%7+31]m Asahi\033[0m"
增强型赋值:
+= i+=10 相当于i=i+10
-= i-=j 相当于i=i-j
*=
/=
%=
++
\--
18.9 逻辑运算
true 1
false 0
与:&
1与1=1
1与0=0
0与1=0
0与0=0
或:|
1或1=1
1或0=1
0或1=1
0或0=0
非:!
!1=0 !true
!0=1 !false
异或:^
异或的两个值,相同为假,不同为真
范例:
true
echo $?
0
! true
echo $?
1
x=10;y=20;temp=$x;x=$y;y=$temp;echo x=$x,y=$y
x=20,y=10
x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$y
x=20,y=10
短路运算
短路与
第一个为0(假),结果必定为0
第一个为1(真),第二个必须要参与运算
短路或
第一个为1,结果必定为1
第一个为0,第二个必须要参与运算
条件测试
判断某需求是否满足,需要由测试机制来实现
专用的测试表达式需要由测试命令辅助完成测试过程
评估布尔声明,以便在条件性执行中
若真,则返回0
若假,则返回1
18.10 条件测试命令
test EXPRESSION #test内部命令,help test
[EXPRESSION]
[[ EXPRESSION ]] #一定要有空格
注意:EXPRESSION前后必须有空白字符
18.10.1 变量测试
-v VAR #变量VAR是否设置过,
示例:判断NAME变量是否定义
[-v NAME]
范例:
unset x #取消x的赋值
test -v x #检测x变量是否赋值过,一般都是用[ -v x],看着条理比较清晰
echo $? #查看退出码
1 #表示假,说明x值没有赋值过,相反为0
18.10.2 数值测试
| -gt | 是否大于 |
|---|---|
| -ge | 是否大于等于 |
| -eq | 是否等于 |
| -ne | 是否不等于 |
| -lt | 是否小于 |
| -le | 是否小于等于 |
范例:
[ 8 -lt 5 ]
echo $?
1
[ 8 -gt 5 ]
echo $?
0
[ a -gt b ]
-bash: [: a: integer expression expected #需要整数表达式
18.10.3 字符串测试
使用help test 查看下面选项的解释
使用help [ 跟test用法一样
使用help [[ 查看帮助,[[ ]]功能支持通配符和正则表达式,而[]没有
| -z | “STRING” 字符串是否为空,空为真,不空为假(判断字符串长度是否为0) |
|---|---|
| -n | “STRING” 字符串是否不空,不空为真,空为假 |
| = | 是否等于 |
| > | ascii码是否大于ascii码 |
| < | 是否小于 |
| != | 是否不等于 |
| == | 左侧字符串是否和右侧的PATTERN相同,注意:此表达式用于[[ ]]中,PATTERN为通配符 |
| =~ | 左侧字符串是否能够被右侧的PATTERN所匹配,注意:此表达式用于[[ ]]中;扩展的正则表达式 |
范例:判断ip地址格式
IP=1.2.3.4
[[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]] #左侧字符串,右侧扩展正则表达式
echo $?
0
IP=1.2.3.2145
[[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]
echo $?
1
18.10.4 文件测试
help test 有文件测试字段帮助
存在性测试
| -a FILE | 同 -e |
|---|---|
| -e FILE | 文件存在性测试,存在为真,否则为假 |
| -b FILE | 是否存在且为块设备文件 |
| -c FILE | 是否存在且为字符设备文件(链接文件) |
| -d FILE | 是否存在且为目录文件 |
| -f FILE | 是否存在且为普通文件 |
| -h FILE | 或-L FILE:存在且为符号链接文件 |
| -p FILE | 是否存在且为命名管道文件 |
| -S FILE | 是否存在且为套接字文件 |
范例:测试目录是否存在
[ -d /etc/ ]
echo $?
0
[ -d /abc ]
echo $?
1
范例:测试是否为链接文件
[ -L /bin ]
echo $?
0
[ -L /bin/ ]
echo $?
1
文件权限测试:
| -r FILE | 是否存在且可读 |
|---|---|
| -w FILE | 是否存在且可写 |
| -x FILE | 是否存在且可执行 |
| -u FILE | 是否存在且拥有suid权限 |
| -g FILE | 是否存在拥有sgid权限 |
| -k FILE | 是否存在且拥有sticky权限 |
范例:测试文件是否有执行权限
ll scp.sh
-rw-r--r--. 1 root root 203 Sep 10 12:25 scp.sh
[ -x scp.sh ]
echo $?
1
chmod +x scp.sh
[ -x scp.sh ]
echo $?
0
文件属性测试
| -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 |
18.11关于()和{}
(list)会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境,帮助查看: man bash 搜索(list)
{list;}不会开启子shell,在当前shell中运行,会影响当前shell环境,帮助查看:man bash 搜索{list;}
范例:开启shell子进程()、不开启shell子进程{}
() #把括号中的命令,开启shell子进程,有一个新的环境,执行完就退出子进程
name=a; (echo $name; name=b; echo $name;); echo $name #应用场景:需要临时环境执行命令
a
b
a
{} #不开启shell子进程,还是旧的环境
name=a; { echo $name; name=b; echo $name;}; echo $name
a
b
b
18.12组合测试条件
第一种方式:
[ EXPRESSION1 -a EXPRESSION2 ] 并且(与)
[ EXPRESSION1 -o EXPRESSION2 ] 或者(或)
[ ! EXPRESSION ] 取反(非)
说明:-a和-o需要使用测试命令进行,[[ ]] 不支持
第二种方式:
COMMADN1 && COMMAND2 #短路与,表示第一个命令执行成功(为真),才会执行第二个命令,反之,不执行
COMMAND1 || COMMAND2 #短路或,表示第一个命令执行失败(为真),才会执行第二个命令,反之,不执行
! COMMAND #非,取反
练习
1、编写脚本argsnum.sh接收一个文件路径为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数
cat argnum.sh
#!/bin/bash
[ "$#" -lt 1 ] && echo "至少应该给一个参数" || echo $(grep "^$" "$1" |wc -l) #$# -->接收参数的个数,man bash查看对应解析
chmod +x
bash argnum.sh /etc/profile
11
2、编写脚本hostping.sh,接受一个主机的IPv4地址作为参数,测试是否可连通。如果能ping通。在提示用户”该地址可访问“;如果不能ping通,则提示用户“该IP地址不可访问”
cat hostping.sh
#!/bin/bash
ping -c1 "$1" &> /dev/null; [ $(echo $?) -eq 0 ] && echo "该地址可访问" || echo "该地址不可访问" #注意echo $?是看上一条命令的执行结果,所以不能同一行执行,要在ping后面加分隔符
chmod +x hostping.sh
bash hostping.sh 10.196.110.42
该地址可访问
bash hostping.sh 1.1.1.1
该地址可访问
3、编写脚本checkdisk.sh检查磁盘分区文件和inode使用率,如果超过80%,就发广播警告空间将满
cat checkdisk.sh
#!/bin/bash
WARNING=80 #这个阈值很关键,进行判断的,否则不好成立等式
IUse=$(df -ih |grep "^/dev/sd" |tr -s ' ' % |cut -d% -f5)
Use=$(df -h |grep "^/dev/sd" |tr -s ' ' % |cut -d% -f5)
[ $IUse -ge $WARNING -o $Use -ge $WARNING ] && wall "磁盘将满" #2.11组合测试条件
chmod +x checkdisk.sh
bash checkdisk.sh #由于磁盘和节点没有到达阈值所以没有触发警告
4、编写脚本excute.sh,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件
ll /opt/scripts/scp.sh
-rw-r--r--. 1 root root 203 Sep 10 12:25 /opt/scripts/scp.sh
cat excute.sh
#!/bin/bash
#set -uex
basename $1 |egrep "^*.sh$" &> /dev/null; EXIT_ID=$(echo $?)
[ -f "$1" -o $EXIT_ID -eq 0 ] && chmod +x $1
ll /opt/scripts/scp.sh
-rwxr-xr-x. 1 root root 203 Sep 10 12:25 /opt/scripts/scp.sh
5、编写脚本nologin.sh和login.sh,实现禁止和允许普通用户登录系统
思路使用位置传参,当用户id大于1000,允许登录,小于1000,锁定不允许登录
cat /etc/passwd |cut -d: -f 1,3 |grep -E "[0-9]{4}"
Asahi:1000
xu:1001
# su - Asahi #用xu用户切换到Asahi用户时可以的
# id
uid=1000(Asahi) gid=1000(Asahi) groups=1000(Asahi) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# exit
logout
cat nologin.sh
#!/bin/bash
id $1 |cut -d' ' -f1 |grep -Eo "[0-9]{4}" &> /dev/null && usermod -L $1 && echo "$1 si disable login"
# chmod +x nologin.sh
# bash nologin.sh Asahi
Asahi si disable nologin
su - Asahi
Password:
su: Authentication failure #这就是被锁定了 usermod -U Asahi解锁即可
方法二:在/etc/下创建一个nologin文件,普通文件就不能登录
echo "user is nologin" >> /etc/nologin
18.13 使用read命令来接收输入
使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量
格式:
是一个内部命令
help read
read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
Read a line from the standard input and split it into fields.
常见选项:
| -p | 指定要显示的提示 |
|---|---|
| -s | 静默输入,一般用于密码 |
| -n N | 指定输入的字符长度N |
| -d | '字符' 输入结束符 |
| -t N | TIMEOUT为N秒 |
范例:当只使用read,会把标准输入的值放入REPLY中
read
wang
echo $REPLY
wang
范例:
read -p "Enter a filename" FILE
范例:对多个变量同时赋值(一般用的少,赋值内容多了,就会出错赋值)
read NAME TITLE
wang cto
echo $NAME
wang
echo $TITLE
范例:|管道配合{}的作用
echo magedu | read NAME
echo $NAME
\#为空,因为管道命令会开启一个子shell进程
echo magedu | { read NAME; echo $NAME; } #分隔符一定不能少
magedu
范例:鸡兔同笼
cat chicken_rabbit.sh
#!/bin/bash
read -p "请输入头的数量: " HEAD
read -p "请输入脚的数量: " FOOT
RABBIT=$[FOOT/2-HEAD]
CHOOK=$[HEAD-RABBIT]
echo "��": " $RABBIT
echo "��":" $CHOOK
chmod +x chicken_rabbit.sh
bash chicken_rabbit.sh
19. bash的配置文件
bash shell的配置文件很多,可以分成下面类别
19.1 按生效范围划分两类:
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:
~/.bash_profile
~/.bashrc
19.2 shell登录两种方式
交互式登录:
(1)直接通过终端输入账号密码登录
(2)使用“su - UserName”切换用户
配置文件执行顺序:
/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登录:
(1) su UserName
(2)图形化界面下打开的终端
(3)执行脚本
(4)任何其它bash实例
执行顺序:
/etc/profile.d/*.sh --> /etc/bashrc --> ~/.bashrc
19.3 按功能划分分类
profile类和bashrc类
19.3.1 profile类
profile类为交互式登录的shell提供配置
全局:
/etc/profile
/etc/profile.d/*.sh
个人:
~/.bash_profile
主要用途:
(1)用于定义环境变量
(2)运行命令或脚本
19.3.2 Bashrc类
bashrc类,为非交互式和交互式登录的shell提供配置(run command运行命令会生效该环境)
全局:
/etc/bashrc
个人:
~/.bashrc
主要用途:
(1)定义命令别名和函数
(2)定义本地变量
19.4 编辑配置文件生效
修改profile和bashrc文件后需生效两种方法:
1.重新启动shell进程
2.source .配置文件
范例:
. ~/.bashrc
19.5 退出任务
保存在~/.bash_logout文件中(用户),在退出登录shell时运行
功能:
创建自动备份
清楚临时文件
练习
1、让所有用户的PATH环境变量的值多出一个路径,例如/usr/local/paache/bin
思路修改当前用户bash变量文件(定义用户本地变量)
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
echo "PATH=$PATH:$HOME/bin" >> /root/bashrc.sh
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin:/root/bin
2、用户root登录时,将命令指示符变成红色,并自动启用如下别名:rm='rm -i'
cdnet='cd /etc/sysconfig/network-scirpts'
editnet='vim /etc/sysconfig/network-scripts/ifcfg-eth0'
editnet='vim /etc/sysconfig/network-scripts/ifcfg-eno16777736或者ifcfg-ens33'(如果是CentOS7)
vim /etc/profile.d/alias.sh
#!/bin/bash
PS1="\033[1;31m[\u@\h \W]\$\033[0m" #可以先echo $PS1,获取格式
alias cdnet='cd /etc/sysconfig/network-scripts'
alias editnet='vim /etc/sysconfig/network-scripts/ifcfg-eth0'
alias editnet='vim /etc/sysconfig/network-scripts/ifcfg-ens34'
ctrl +d
cdnet
[root@help network-scripts]#
3、任意用户登系统时,显示红色字体的警告提醒信息“Hi,dangerous!!”
cat <<-EOF > /etc/profile.d/env.sh
echo -e "\033[1;31m Hi,dangerous!\033[0m"
EOF
4、编写生成脚本基本格式的脚本,包括作者,练习方式版本,时间,描述等
cat .vimrc
set cursorline
set autoindent
autocmd BufNewFile *.sh exec ": call SetTitle()"
func SetTitle()
if expand("%:e") == 'sh'
call setline(1,"#!/bin/bash")
call setline(2,"")
call setline(3,"#*")
call setline(4,"#Author: Asahi")
call setline(5,"#Date: ".strftime("%F"))
call setline(6,"#FileName: ".expand("%"))
call setline(7,"#Description: The test script")
call setline(8,"#*")
call setline(9,"")
endif
endfunc
autocmd BufNewFile * normal G
5、编写用户的环境初始化脚本reset.sh,包括别名,登录提示符,vim的设置环境变量等
#!/bin/bash
#*
#Author: Asahi
#Date: 2021-09-11
#FileName: /etc/profile.d/reset.sh
#Description: The test script
#*
alias cd="救救我!!!救救我!!!救救我!!!"
PS1="\033[1;32m[\u@\h \W]#\033[0m"
cat << EOF >> ~/.vimrc
set nu
EOF
19.6 短路与、短路或复习
CMD1 && CMD2 || CMD3 #如果CMD1真,则执行CMD2,一般情况下CMD2都是为真的命令
CMD1 || CMD2 && CMD3 #假设,CMD2为真,运行结果如下
#如果CMD1为真,则不执行CMD2,但是执行CMD3
#如果CMD1为假,则执行CMD2,也执行CMD3 #得出结论,不管CMD1、CMD2是为真为假,都会执行CMD3,所以这种逻辑判断不会使用
得出结论:短路与、短路或适用于简短的命令逻辑判断,但是不适合复杂的逻辑判断
通常用法
CMD1 && CMD2
CMD1 || CMD2
CMD1 && CMD2 || CMD3
20. 流程控制
20.1 条件选择
20.1.1选择执行if语句
格式:
if是一个关键字(多个关键字组合起来的,一个关键词,不是单独的命令)
type if
if is a shell keyword
help if
if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
单分支
if 判断条件;then
条件为真的分支代码
fi
双分支
if 判断条件;then
条件为真的分支代码
else
条件为假的分支代码
fi
多分支
if 判断条件;then
条件1为真的分支代码
elif 判断条件2;then
条件2为真的分支代码
elif 判断条件3;then
条件3位真的分支代码
...
else
以上条件都为假的分支代码
fi
说明:
多个条件时,逐个条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句
if语句可嵌套
范例:探测某一台主机是否能访问
#根据命令的退出状态来执行命令
if ping -c1 -W2 station &> /dev/null; then
echo 'station1 is UP'
elif grep -q 'station1' ~/maintenance.txt; then #查看维护记事本,是否有该主机名
echo 'station1 is undergiong maintenance' #上面为真,则输出该主机在维护
else
echo 'station1 is unexpectedly DOWN!'
exit 1
fi
范例:计算BMI值判断身体状态
cat if_bmi.sh
#!/bin/bash
read -p "请输入身高(m为单位)" HIGH
if [[ ! "$HIGH" =~ ^[0-2].?[0-9]{,2}$ ]]; then echo "输入错误身高"; exit 1; fi
read -p "请输入体重(kg为单位)" WEIGHT
if [[ ! "$WEIGHT" =~ ^[0-9]{1,3}$ ]]; then echo "输入错误体重"; exit 1; fi
BMI=$(echo $WEIGHT/$HIGH^2|bc)
if [ $BMI -le 18 ];then
echo -e "\033[1;31m你太瘦了,多吃点\033[0m"
elif [ $BMI -lt 24 ];then
echo -e "\033[1;31m身材很棒!\033[0m"
else
echo "\033[1;31m你太胖了,注意绝食,加强运动\033[0m"
fi
bash if_bmi.sh
请输入身高(m为单位)1.8
请输入体重(kg为单位)72
身材很棒!
20.1.2 条件判断case语句
格式:
case(ksi)跟if类型,是一个关键字,组合其他shell命令进行判断
type case
case is a shell keyword
help case
case: case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
多行格式:
case 变量引用 in
PAT1)
分支
;;
PAT2)
分支
;;
...
*)
默认分支
;;
esac
范例:使用case判断是yes or no(方法一)
比较适合判断多个不同的值
cat yes_or_no.sh
#!/bin/bash
read -p "Do you agree(yes/no)? " INPUT
INPUT=$(echo $INPUT | tr 'A-Z' 'a-z')
case $INPUT in
y|yes)
echo "You input is YES"
;;
n|no)
echo "You input is NO"
;;
*)
echo "Input fales,Please input yes or no!"
esac
# bash yes_or_no.sh
Do you agree(yes/no)? No
You input is NO
# bash yes_or_no.sh
Do you agree(yes/no)? abc
Input fales,Please input yes or no!
# cat yes_or_no.sh
范例:使用case判断yes or no (方法二)
判断条件用通配符取缔,tr转换
cat yes_or_no2.sh
#!/bin/bash
read -p "Do you agree(yes/no)? " INPUT
case $INPUT in
[Yy]|[Yy][Ee][Ss])
echo "You input is YES"
;;
[Nn]|[Oo])
echo "You input is NO"
;;
*)
echo "Input fales,Please input yes or no!"
esac
# bash yes_or_no2.sh
Do you agree(yes/no)? YES
You input is YES
# bash yes_or_no2.sh
Do you agree(yes/no)? Yes
You input is YES
# bash yes_or_no2.sh
Do you agree(yes/no)? noyes
Input fales,Please input yes or no!
练习
1、编写脚本createuser.sh,实现如下功能:使用一个用户名作为参数,如果指定参数的用户存在,就显示其存在,否则添加;显示添加的用户id号等信息
cat createuser.sh
#!/bin/bash
read -p "请输入用户名:" USERNAME
if $(id $USERNAME &> /dev/null); then #一点要用反单引号,或者$(),把这两个命令当成一个整体,否则永远为真
echo "$USERNAME 用户存在"
else
useradd $USERNAME;id $USERNAME
fi
2、编写脚本yesorno.sh,提示用户输入yes或no,判断用户输入的是yes还是no,或是其他信息
3、编写脚本filetype.sh,判断用户输入文本路径,显示其文件类型(普通,目录,链接,其它文件类型)
#!/bin/bash
read -p "Please input file path: " path
type=$(ls -l $path |grep -o "^.")
case $type in
-)
echo "common file";;
d)
echo "directory file";;
l)
echo "linked file";;
*)
echo "other file";;
esac
# bash filetype.sh
Please input file path: /etc/hosts
common file
4、编写脚本checkint.sh,判断用户输入的参数是否为正整数
#!/bin/bash
read -p "Please input a number: " NUM
[[ $NUM =~ ^[0-9]+$ ]] && echo "$NUM is int" || { echo "Please input a number"; exit; }
# bash checkint.sh
Please input a number: -1
Please input a number
# bash checkint.sh
Please input a number: 2
2 is int
21. 文件查找和打包压缩
21.1 文件查找
文件查找:
在文件系统上查找符合条件的文件
文件查找:locate ,find
非实时查找(数据库查找):locate
实时查找:find
21.1.1 locate
locate(lokete)查询系统上预建的文件索引数据库/var/lib/mlocate/mlocate.db,索引的构建是在系统较为空闲时自动进行(周期性任务),执行updatedb可以更新数据库,索引构建过程需要遍历整个根文件系统,很消耗资源
工作特点:
查找速度快
模糊查找(不够精确)
非实时查找
搜索的是文件的全路径,不仅仅是文件名
可能只搜索用户具备读取和执行权限的目录
格式:
不存在需要安装mlocate
type locate
locate is hashed (/usr/bin/locate) #外部命令
locate --help
Usage: locate [OPTION]... [PATTERN]...
Search for entries in a mlocate database.
常用选项:
| -i | 不区分大小的搜索 |
|---|---|
| -n N | 只列举前N个匹配项目 |
| -r | 使用基本正则表达式('',""不加会出问题) |
范例:
#搜索名称或路径中包含"conf"的文件
locate conf
#使用Regex来搜索以".conf"结尾的文件
21.2 find
find是实时查找的工具,通过遍历指定路径完成文件查找
工作特点:
查找速度略慢
精确查找
实时查找
查找条件丰富
可能只搜索用户具备读取和执行权限的目录
格式:
type find
find is /usr/bin/find
type find
find is /usr/bin/find
[root@localhost scripts]# find --help
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
find [OPTION]... [查找路径] [查找条件] [处理条件]
查找路径:指定具体目标路径;默认为当前目录
查找条件:指定的查找标准,可以文件名、大小、类型、权限等标准进行;默认为找出指定路径下的所有文件
处理动作:对符合条件的文件做操作,默认输出至屏幕
21.2.1 指定搜索目录层级
| -maxdepth level | 最大搜索目录深度,指定目录下的文件为第1级目录 |
|---|---|
| -mindepth level | 最小搜索目录深度 |
21.2.2 先处理目录内的文件,再处理指定目录
-depth(从文件夹内到文件夹列出指定目录的路径)
21.2.3 根据文件名和inode查找
| -name "文件名称" | 支持使用glob,如:*,?,[],[^] |
|---|---|
| -iname "文件名称" | 不区分字母大小写 |
| -inum n | 按inode号查找 |
| -samefile name | 相同inode号的文件(硬链接关系) |
| -links n | 链接数为n的文件 |
| -regex “PATTERN” | 以PATTERN匹配整个文件路径,而非文件名称 |
范例:
find -name snow.png
find -iname snow.png
find / -name ".txt"
find /var -name "log*" #一定要引号搜索才行,''""都可以
\# find -regex ".*\.txt$"
21.2.4 根据属主、属组查找
| -user USERNAME | 查找属主为指定用户(UID)的文件 |
|---|---|
| -group GRPNAME | 查找属组为指定组(GID)的文件 |
| -uid UserID | 查找属主为指定的GID号的文件 |
| -gid GroupID | 查找属组为指定的GID号的文件 |
| -nouser | 查找没有属主的文件(属主被删除的文件) |
| -nogroup | 查找没有属组的文件(属组被删除的文件) |
21.2.5 根据文件类型查找
-type TYPE
TYPE可以是一下形式:
f:普通文件
d:目录文件
l:符号链接文件
s:套接字文件
b:块设备文件
c:字符设备文件
p:管道文件
21.2.6 空文件或目录
-empty
范例:
find /app -type d -empty
21.2.7 组合条件
与:-a
或:-o
非:-not !
德·摩根定律:
(非A)或(非B)=非(A且B)
(非A)且(非B)=非(A或B)
示例:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)
范例:
find -user joe -group joe
find -user joe -not -group joe
find -user joe -o -user jane
find -not \( -ser joe -o user jane \)
find / -user joe -o -uid 500
#找出/tmp目录下,属主不是root,且文件名不以f开头的文件
find /tmp (-not -user root -a -not -name 'f') -ls #小括号作为一个整体执行,-ls是find的子命令,以长格式显示
21.2.8 排除目录
范例:
#查找/etc/下,除/etc/sane.d目录的其他所有.conf后缀的文件
find /etc/ -path '/etc/sane.d' -a -prune -o -name "*.conf" #prune修剪, -a并且,-o 或者
#查找/etc/下,除/etc/sane.d和/etc/fonts两个目录的所有.conf后缀的文件
find /etc/ \( -path "/etc/sane.d" -o -path "/etc/fonts" \) -a prune -o -name "*.conf" #(中的命令作为一个整体)
21.2.9 根据文件大小来查找
-size [+|-] #UNIT,常用段位:K, M,G,c(byte)
#UNIT:(#-1,#],如:6k表示(5k,6k]
-#UNIT:[0,#-1],如:-6k表示[0,5k]
+#UNIT:(#,),如:+6k表示(6k,)
范例:使用find子命令 size搜索文件
find -size 2k -ls #搜索的结果是2k,及2k-1的文件
21.2.10 根据时间戳
以“天”为单位
-atime[+|-]#
#:[#,#+1]
+#:[#+1,]
-#:[0,#)
-mtime
-ctime
以“分钟为单位”
-amin
-mmin
-cmin

21.2.11 根据权限查找
-perm [/|-]MODE
| MODE | 精确权限匹配 |
|---|---|
| /MODE | 任何一类(u,g,o)对象的权限中只要能以为匹配即可,或关系,+从centos7开始淘汰 |
| -MODE | 每一类对象都必须同时拥有指定权限,与关系 |
0表示不关注
说明:
| find -perm 755 会匹配权限模式恰好是755的文件 |
|---|
| 只要当任意人有写权限时, find -perm +222就会匹配 |
| 只有当每个人都有些权限时,find -perm -222才会匹配 |
| 只有当其他人(other)有些写权限时,find -perm -002才会匹配 |
21.2.12 处理动作
| 默认的处理动作,显示至屏幕 | |
|---|---|
| -ls | 类似对查找的文件执行“ls -l”命令 |
| -delete | 删除查找到的文件 |
| -fls file | 查找到的所有文件的长格式保存至指定文件中(等价于ls >) |
| -ok COMMAND {}; | 对查找到的每个文件执行由COMMAND指定的命令,对于每个文件执行命令之前,都会交互式要求用户确认 |
| -exec COMMAND {} ; | 对查找到的每个文件执行由COMMAND指定的命令,(跟上面一样,不需要确认) |
| {} | 用于引用查找到的文件名称自身 |
范例:
# 备份配置文件,添加.orig这个扩展名
find -name ".conf" -exec cp {} {}.oring \; #{}为占位符,代表find 搜索到的文件名,\;表示表示结束
# 提示删除存在时间超过3天以上的joe的临时文件
find /tmp -ctime +3 -user joe -ok rm {} \;
#在主目录中寻找可被其他用户写入的文件
find ~ -perm -002 -exec chmod o-w {} \;
#查找/data下的权限为644,后缀为sh的普通文件,增加执行权限
find /data -type f -perm 644 -name ".sh" -exec chmod 755 {} \;
#查看/home的目录
find /home -type d -ls
21.3 参数替换xargs
由于很多命令不支持管道|来传递参数,xargs用于产生某个命令的参数,xargs可以输入stdin的数据,并且以空格符或回车符将stdin的数据分隔成参数
另外,许多命令不能接收过多参数,命令执行可能会失败,xargs可以解决
注意:文件名或者是其他意义的名次内含有空格符的情况
格式:
xargs --help
Usage: xargs [OPTION]... COMMAND INITIAL-ARGS...
Run COMMAND with arguments INITIAL-ARGS and more arguments read from input.
find和xargs 的组合
find | xargs COMMAND #xargs作用:让不支持标准输入的命令,配合xargs传给那个命令
范例:
#显示10个数字
seq 10 | xargs
#删除当前目录下的大量文件
ls | xargs rm
#批量创建和删除用户
echo user{1..10} |xargs -n1 useradd
echo user{1..100} |xargs -n1 userdel -r #-r删除家目录
find /sbin/ -perm /700 | ls -l #由于ls -l不支持标准输入,所以这样写是错误的
find /bin/ -perm /7000 |xargs ls -Sl #查找有特殊权限的文件,并排序(通过xargs把标准输出传给ls)/:或的关系(只要其中一个满足即可)
find /bin/ -perm -7000 |xargs ls -Sl #此命令和上面有何区别?-:与的关系(都包括)
find -type f -name "*.txt" -print0 |xargs -0 rm #以字符Nul分隔*(0代表空分隔文件名)
seq 100 |xargs -i -P 10 wget -PO /data http://10.0.0.8/{}.html #并发执行多个进程,-P 10 开启10个进程并发下载, -i把值传到后面的括号中
seq 389 | xargs -i -P3 you-get https://www.bilibili.com/video/av36489007?p={} #并发下载389个视频
练习
1、查找/var目录下属主为root,且属组为mail的所有文件
2、查找/var目录下不属于root、lp、gdm的所有文件
3、查找/var目录下最近一周内其内容修改过,同时属主不为root,也不是postfix的文件
4、查找当前系统上没有属主或属组,且最近一个周内层被访问过的文件
5、查找/etc/目录下大于1M且类型为普通的所有文件
6、查找/etc/目录下所有用户都没有写权限的文件
22. 压缩和解压缩
22.1 compress和uncompress
格式
compress Options [file ...] #默认压缩,把原文件删除,压缩比1:4
常用选项
| -d | 解压缩,相当于uncompress |
|---|---|
| -c | 结果输出至标准输出,不删除原文件(配合重定向) |
| -v | 显示详情 |
uncompress file.Z 解压缩
zcat file.z 不显示解压缩的前提查看文本内容
范例:
zcat file.Z >file
2.2 gzip和gunzip
格式:
gzip [OPTION]... FILE...
常用选项:
| -d | 解压缩,相当于gunzip |
|---|---|
| -c | 结果输出至标准输出,保留原文件不改变 |
| -# | 指定压缩比,#取值为1-9,值越大压缩比越大(因为压缩比高,压缩的时间也会更久) |
| gunzip file.gz | 解压缩 |
| zcat file.gz | 不显示解压缩的前提下查看文本文件内容 |
范例:
gzip -c messafes > messages.gz
gzip -c -d messafes.gz > messages
zcat messages.gz > messages
cat messages | gzip > m.gz
22.3 bzip2和bunzip2
格式:
缺点:可能要自己在环境上装bzip
bzip [OPTION]... FILE...
常用选项
| -k | keep,保留源文件 |
|---|---|
| -c | 结果输出至标准输出,保留原文件不改变 |
| -d | 解压缩 |
| -# | 1-9,压缩比默认为9(比gzip高) |
| bunzip2 file.bz2 | 解压缩 |
| bzcat file.bz2 | 不显示解压缩的前提下查看文本文件内容 |
22.4 xz和unxz
格式
xz [OPTION]... FILE...
常用选项:
| -k | keep,保留原文件 |
|---|---|
| -c | 结果输出至标准输出,保留原文件不改变 |
| -d | 解压缩 |
| -# | 压缩比,1-9,默认为6 |
| unxz file.xz | 解压缩 |
| xzcat file.xz | 不显示解压缩的前提下查看文本文件内容 |
22.5 zip和unzip
zip可以实现打包目录并压缩(上面的压缩都有个缺点就是不能打包目录)
范例:
#打包并压缩
zip -r /backup/sysconfig.zip /etc/sysconfig
#默认解压缩至当前目录
unzip /backup/sysconfig.zip
#解压缩至指定目录
unzip /backup/sysconfig.zip -d /tmp
cat /var/log/messages |zip messages -
unzip -p message.gz > message # -p 表示管道
23 打包和解包
23.1 tar
tar即Tape ARchive,磁带归档,经常用于备份(tar是用来打包的,tar.gz意思就是先gz压缩在tar打包)
格式
tar [OPTION]...
(1)创建归档,保留权限
tar -cpvf /PATH/FILE.tar FILE... #c代表创建p代表保留权限v显示过程,tar本身不压缩,只是打包
(2)追加文件至归档:注:不支持对压缩文件追加
tar -rf /PATH/FILE.tar FILE...
(3)查看归档文件中的文件列表
tar -tf /PATH/FILE.tar
(4)展开归档
tar xf /PATH/FILE.tar
tar xf /PATH/FILE.tar -C /PATH
(5)结合压缩锅具实现:归档并压缩
-z 相当于gzip压缩工具
-j 相当于bzip2压缩工具
-J 相当于xz压缩工具
范例:
# tar zcvf etc.tar.gz /etc/ #前提zip命令要安装了
# tar jcvf etc.tar.bz2 /etc/ #前提bz2命令要安装了
# tar Jcvf etc.tar.xz /etc/ #前提xz命令要安装了
# ll etc.tar.*
# tar xf xxx.tar.* #默认解压所有tar打包压缩的文件
--exclude 排除文件
范例:
tar zcvf /root/a.tar.gz --exclude=/app/host1 --exclude=/app/host2 /app
-T 选项指定输入文件
-X选项指定包含要排除的文件列表
范例:
tar zcvf mybackup.tar.gz -T /root/includefilelist -X /root/excludefilelist
23.2 split
split 命令可以分割一个文件为多个文件
范例:
#分割大的tar 文件为多份小文件
split -b Size -d tar-file-name prefix-name
split -b 1M mybackup.tgz mybackup-parts
#切换成的多个小分文件使用数字后缀
split -b 1M -d mybackup.tgz mybackup-parts
#将多个切割的小文件合并成一个大文件
cat mybackup-parts* > mybackup.tar.gz
23.3 cpio
cpio是历史悠久的打包和解包工具,不过目前也较少使用
cpio命令式通过重定向的方式进行打包备份,还原恢复的工具,他可以解压以“.cpio”或者“.tar”结尾的文件
格式:
cpio [选项] > 文件名或者设备名
cpio [选项] < 文件名或者设备名
常用选项
| -o | output模式,打包,将标准输入传入的文件名打包后发送到标准输出 |
|---|---|
| -i | input模式,解包,对标准输入传入的打包文件名解包到当前目录 |
| -t | 预览,查看标准输入传入的打包文件中包含的文件列表 |
| -O | filename 输出到指定的归档文件 |
| -A | 向已存在的归档文件中追加文件 |
| -l | filename 对指定的归档文件名解压 |
| -F | filename 使用指定的文件名替代标准输入或输出 |
| -d | 解包生成目录,在cpio还原时,自动的建立目录 |
| -v | 显示打包过程中的文件名称 |
范例:
#将etc目录备份:
find ./etc/ -print |cpio -ov > back.cpio
#将/data内容追加bak.cpio
find /data | cpio -oA -F bak.cpio
#内容预览
cpio -tv < etc.cpio
#解包文件
cpio -idv < etc.cpio
23.4 文本处理三剑客之SED
什么是人机交互:就是一运行就等着人输入东西。
23.4.1 sed工作原理
sed即stram EDitor,和vi不同,sed是行编辑器

Sed是从文本或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行,知道最后一行。
每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(Pattern Space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,知道文件末尾。一次处理一行的设计模式使得sed性能很高,sed的读取大文件时不会出现卡顿的现象。如果使用vi命令打开几十M上百M的文件,明显会出现卡顿的现象,这是因为vi命令打开文件是一次性将文件加载到内存,然后再打开。Sed就避免了这种情况,一行一行的处理,打开速度非常快,执行速度也很快
参考网站:http://www.gnu.org/software/sed/manual/sed.html
23.4.2 sed基本用法
格式:
sed [option]... 'script' inputfile... #sed 自己的脚本语法'script', 处理文件
常用选项:
| -n | 不输出模式空间内容到屏幕,即不自动打印 |
|---|---|
| -e | 多点编辑 |
| -f | /PATH/SCRIPT_FILE 从指定文件中读取编辑脚本 |
| -r | 支持使用扩展正则表达式 |
| -i | .bak(后缀可自定义) 备份文件并原处编辑 |
| script | ‘地址命令’ |
地址格式:
1、不给地址:对全文进程处理
2、单给地址:
#:指定的行
$:最后一行
/pattern/:被此处模式所能匹配到的每一行
3、地址范围:
#,#
#,+#
/pat1/,/pat2/
#,/pat1/
4、步进:~
1~2奇数行
2~2偶数行
命令:
| p | 打印当前模式空间内容,追加到默认输出之后 |
|---|---|
| d | 删除模式空间匹配的行,并立即启用下一轮循环 |
| a[]text | 在指定行后面追加文本,支持使用\n实现多行追加 |
| i[]text | 在行前面插入文本,默认插入的内容都是行首,可以用\转义空格内容改变 |
| c[]text | 替换行为单行或多行文件 |
| w/path/file | 保存模式匹配的行至指定文件 |
| r/path/file | 读取指定文件中文件至模式空间中匹配的行后 |
| = | 为模式空间中的行打印行号 |
| ! | 模式空间中匹配行取反处理 |
| s/pattern/string/修饰符 | 查找替换,支持使用其他分隔符,例如s@@@,s### |
范例:
sed '' passwd #把passwd模式空间内容默认自动打印
sed 'p' passwd #p选项把内容追加到内容空间,就是重新打印(因为sed是行处理,所以每行打印2遍)
范例:使用sed取本机ip地址
# sed 基本功能从键盘输入,进行打印
ifconfig eno33554960 | sed -n '2p' |tr -s ' '|cut -d' ' -f3 #-n 关闭自动打印,2p打印第二行
192.168.5.221
范例:使用sed进行匹配过滤取值(会比grep啰嗦一点)
df | sed -n '/\/dev\/sd/p' #/模式/ 进行匹配模式
/dev/sda1 508588 127096 381492 25% /boot
范例:使用sed进行指定从某处开始,到某处结束匹配
sed -n '//,//p' 文件名 #//中的就是模式(开始内容,结束内容)
范例:步进:刚开始从几开始每次增长的数
seq 10 | sed -n '1~2p' #相当于本来每次运行+1,变成每次运行+2
1
3
5
7
9
seq 10 | sed -n '2~2p' #从2开始每次增加2
2
4
6
8
10
范例:使用sed修改原文件并备份
seq 10 > abc.txt
sed -i.bak '1d;2d' abc.txt
sed -n 'p' abc.txt
3
4
5
6
7
8
9
10
范例:使用sed在指定字符后添内容,删除指定字符,替换指定字符
sed -i.bak '/^Listen 80/a listen 8080' /etc/httpd/conf/httpd.conf #/匹配内容/a 插入内容,a表示在匹配内容后插入内容
sed -i '/^listen 8080/d' /etc/httpd/conf/httpd.conf #/匹配内容/d,d表示删除
sed -i '/^Listen 80/c Listen 9527' /etc/httpd/conf/httpd.conf #/匹配内容/c,c表示替换
范例:把#开头的行全删了,把非#开头的行都打印出来
sed -i.bak '/^#/d' /etc/fstab
sed -n '/^#/!p' /etc/fstab
范例:使用查找替换,取ip地址
ifconfig eno33554960 | sed -n '2s/^.*inet//;s/netmask.*//p' #把inet之前的替换为空(也就是删除),在把network之后的删除,追后p显示出来。-n关闭自动打印模式空间内容
192.168.5.221
范例:修改默认网卡名
#先自己修改网卡名称,和配置文件名称,在更新内核参数,没改成功先跳过
sed -rn '/^GRUB_CMDLINE_LINUX=/s#"$# net.ifnames=0"#p' /etc/default/grub #先显示处理结果,不修改源文件
sed -ri '/^GRUB_CMDLINE_LINUX=/s#"$# net.ifnames=0 biosdevname=0"#' /etc/default/grub #修改源文件
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet net.ifnames=0 biosdevname=0"
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot
范例:把文件中不是#开头的行都添加上#号
sed -rn '/^#/!s@^@#@p' /etc/fstab #显示正则处理结果
sed -ri '/^#/!s@^@#@' /etc/fstab
范例:取基名(文件名)、目录名
echo /etc/hosts | sed -rn 's#(.*)/([^/]+)/?#\1#p' #分组中的后相引用,()代表分组,\1代表取第一个分组中的内容
/etc
echo /etc/hosts | sed -rn 's#(.*)/([^/]+)/?#\2#p' #\2代表取第二个分组中的内容
hosts
23.4.3 sed高级用法
sed中除了模式空间(Pattern Space),还另外支持保持空间(Hold Space),利用次空间,可以将模式空间中的数据,临时保存至保存空间,从而后续接着处理,实现更为强大的功能。
常见的高级命令
P 打印模式空间开端至\n内容,并追加到默认输出之前
h 把模式空间中的内容覆盖至保持空间中
H 把模式空间中的内容追加至保持空间中
g 从保持空间取出数据覆盖至模式空间
G 从保持空间中取出内容追加至模式空间
x 把模式空间中的内容与保持空间中的内容进行互换
n 读取匹配的行的下一行覆盖至模式空间
N读取匹配到的行的下一行追加至模式空间
d 删除模式空间的行
D 如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本,并不会读取的输入行,而使用合成的模式空间重新启动循环。如果模式空间不包含换行符,则会像发出d命令那样启动正常的新循环
范例:
seq 10 | sed -n 'n;p' #sed默认从第一行开始打印,n代表匹配到的下一行追加至模式空间,所以就是打印偶数行的内容
2
4
6
8
10
24. 软件管理
24.1 软件运行和编译
24.1.1 软件相关概念
24.1.1.1 ABI
ABI即Application Binary Interface(应用程序二进制接口) Windows与Linux不兼容
ELF(Executable and Linkable Format)
PE(Portable Executable)
库级别的虚拟化
Linux:WINE
Windows:Cygwin
24.1.1.2 API
API即Application Programming Interface(应用程序开发接口),API可以在各种不同的操作系统上实现给应用程序提供完全相同的接口,而他们本身在这些系统上的实现却可能迵异,主流的操作系统有两种,一种是Windows系统,另一种是Linux系统。由操作系统的不同,API又分为Windows API和Linux API。在Windows平台开发出来的软件在Linux上无法运行,在Linux上开发的软件在Windows上又无法运行,这就导致了软件一直困难,POSIX标准的出现就是为了解决这个问题
POSIX:Portable Operating System Interface 可移植操作系统接口,定义了操作系统应该为应用程序提供的接口标准,是IEEE为要在各种UNIX操作系统上运行的软件而定义的一系列API标准的总称。linux和windows都要实现基本的posix标准,程序就在源代码级别可移植了
24.1.1.3 开发语言
系统级开发
汇编语言
C
C++
应用级开发
java
Python
go
php
perl
delphi
ruby
24.2 C语言程序的实现过程
C程序源代码 --> 预处理 --> 编译 --> 汇编 --> 链接
C语言的程序编译主要经过四个过程:

预处理(Pre-Processing)
编译(Compiling)
汇编(Assembling)
链接(Linking)
gcc编译过程范例:
gcc -E hello.c -o hello.i #对hello.c文件进程预处理,生成了hello.i文件
gcc -S hello.i -o hello.s #对预处理文件进程编译,生成了编译文件
gcc -c hello.s -o hello.o #对汇编文件进行编译,生成了目标文件
gcc hello -o hello #对目标文件进程链接,生成可执行文件
gcc hello.c -o hello #直接编译链接可执行目标文件(不需要-o,默认就是生成可执行文件 gcc c语言源代码文件 可执行文件名)
24.3 软件模块的静态和动态链接
链接主要作用把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确地衔接,分为静态和动态链接

24.3.1 静态链接
把程序对应的依赖库复制一份到包
生成模块文件libxxx.a
嵌入程序包
升级难,需要新编译
占用空间多,迁移困难
24.4 Java程序编译运行过程
java源代码 --> 编译成java字节码 --> 对应操作系统的java虚拟机(JVM)解释--> 操作系统运行

25. 软件包和包管理
25.1 软件包介绍
开源软件最初只提供了.tar.gz打包的源码文件,用户必须自己编译每个想在GNU/Linux上运行的软件。用户急需系统能提供一种更加便利的方法来管理这些软件,当Debian诞生时,这样的一个管理工具dpkg也就应运而生,可用来管理deb后缀的“包”文件。从而著名的“packge”概念第一次出现在GUN/Linux系统中,稍后Red Hat才开发自己的rpm包管理工具。
25.1.1 软件包中文件分类
二进制文件
库文件
配置文件
帮助文件
25.1.2 程序包管理器
软件包管理器功能:
将编译好的应用程序的各组成文件打包一个或几个程序包文件,利用包管理器可以方便快捷地实现程序包的安装、卸载、查询、升级和校验等管理操作
主流的程序包管理器
debian:deb文件,dpkg包管理器
redhat:rpm文件,rpm包管理器,rpm:Redhat Package Manager,RPM Package Manager
25.1.3 包命名
源代码打包文件命令:
name-VERSION(版本号:主版本号,次版本号,小版本号).tar.gz|bz2|xz
VERSION: major.minro.release
rpm包命名方式:
name-VERSION-release.arch.rpm
VERSION: major.minor.release
release: release.OS
常见的arch:
x86(32位):i386,i486,i586,i686
x86_64(64位):x64,x86_64,amd64
powerpc:ppc
跟平台无关:noarch
范例:
bash-3.2-32.el5_9.1.i386.rpm #bash为开源软件的版本名称(软件名称),3.2是开源软件对应的版本,32是编译打包的次数,el5_9.1代表红帽5版本系统,i386是该软件需要运行在i386CPU架构的系统上
bash-4.2.46-19.el7.x86_64.rpm
bash-4.4-19-7.el8.x86_64.rpm
bash-4.4-19-7.el8.aarch64.rpm
bash-4.4.19-7.el8.ppc64le.rpm
bc_1.07.1-2_amd64.deb
bc_1.07.1-2_s390x.deb
25.1.4 分类和拆包
软件包为了管理和使用的便利,会将一个大的软件分类,放在不同的子包中。
包的分类:
Application-VERSION-ARCH.rpm:主包
Application-devel(的而wo,开发)-VERSION-ARCH.rpm 开发子包
Application-utils(由ti哦,工具)-VERSION-ARHC.rpm 其它子包
Application-libs(库)-VERSION-ARHC.rpm 其它子包
25.1.5 包的依赖
软件包之间可能存在依赖关系,甚至循环依赖,即:A包依赖B包,B包依赖C包,C包依赖A包
安装软件包时,会因为缺少依赖的包,而导致安装包失败
解决依赖包管理工具:
yum:rpm包管理器的前端工具
dnf:Fedora 18+rpm包管理器前端管理工具,CentOS8版代替yum
apt:deb包管理器前端工具
zypper:suse上的rpm前端管理工具
25.1.6 程序包管理器相关文件
包文件组成(每个包独有)
包内的文件
元数据,如:包的名称,版本,依赖性,描述等
可能会有包安装卸载时运行的脚本
数据库(公共):/var/lib/rpm
程序包名称及版本
依赖关系
功能说明
包安装后生成的各文件路径及校验码信息
范例:利用cpio工具查看包文件列表
rpm2cpio 包文件|cpio -itv #预览包内文件,rpm2cpio 把rpm包转换为cpio
rpm2cpio 包文件|cpio -id "*.conf" #释放包内文件
25.1.7 获取程序包的途径
软件包需要事先将源码进行编译后打包形成,获取包的途径如下:
25.1.7.1:系统筏板的光盘或官方网站
CentOS镜像:
https://www.centos.org/download
https://mirrors.aliyun.com/epel?spm=a2c6h.13651104.0.0.3bc47dfaZpesAr
Rpmforge:官网:http://repoforge.org,RHEL推荐,包很全,即将关闭
25.1.7.3 软件项目官方站点
http://yum.mariadb.org/10.4/centos8-amd64/rpms
http://repo.mysql.com/yum/mysql-8.0-community/el/8/x86_64
25.1.7.4 搜索引擎
注意:第三方包建议要检查其合法性,来源合法性,程序包的完整性
25.1.7.5 自己制作
将源码文件,利用工具,如:rpmbuild,fpm等工具制作成rpm包文件
26. 包管理器rpm
CentOS系统上使用rpm命令管理程序包
功能:
安装、卸载、升级、查询、校验、数据库维护
26.1 安装
格式:
rpm {-i|--install} [install-options] PACKAGE_FILE
选项:
| -v | verbose |
|---|---|
| -vv | |
| -h | 以#显示程序包管理执行进度 |
常用组合:
rpm -ivh PACKAGE_FILE ...
rpm 包安装[install-options]
--test:测试安装,但不真正执行安装,即dry run(干运行)模式
--nodeps:忽略依赖关系
--replacepkgs:重新安装已经安装过的安装包(针对包文件丢失的情况)
--force(强制):忽略软件包及文件冲突(强制安装对应的包)
--replacefiles:替换属于其他软件包的文件
--nosignature:不检查来源合法性
--nodigest:不检查包完整性
--noscripts:不执行程序包脚本
%pre: 安装前脚本 --nopre
%post 安装后脚本 --nopost
%preun 卸载前脚本 --nopreun
%postun 卸载后脚本 --nopostun
26.2 升级和降级
rpm包升级
rpm {-U|--upgrade} [install-options] PACKAGE_FILE...
rpm {-F|--freshen} [install-options] PACKAGE_FILE...
upgrade:安装有旧版本程序包,则“升级”,如果不存在旧版程序包,则“安装”
freshen:安装有旧版本程序包,则“升级”,如果不存在旧版本程序包,则不执行升级操作
--oldpackage:降级
--force:强制安装
常用组合
rpm -Uvh PACKAGE_FILE ...
rpm -Fvh PACKAGE_FILE ...
升级注意项:
(1)不要对内核升级操作;Linux支持多内核版本并存,因此直接安装新版本内核
(2)如果原程序的配置文件安装后曾被修改,升级时,新版本提供的同一个配置文件不会直接覆盖老版本的配置文件,而把新版本文件重命名(FILENAME.rpmnew)后保留
26.3 包查询
rpm {-q|--query} [select-options] [query-options]
[select-options]
| -a | 所有包 |
|---|---|
| -f | 查看指定的文件由哪个程序包安装生成 |
| -p rpmfile | 针对尚未安装的程序包文件做查询操作 |
| --whatprovides CAPABILITY | 查询指定的CAPBILITY由哪个包所提供 |
| --whatrequires CAPABILITY | 查询指定的CAPABILITY被哪个包所依赖 |
[query-options]
| --changelog | 查询rpm包changelog |
|---|---|
| -c | 查询程序的配置文件 |
| -d | 查询程序的文档 |
| -i | information(信息),配合q查询 |
| -l | 查看指定的程序包安装后生成的所有文件 |
| --scripts | 程序包自带的脚本 |
| --provides | 列出指定程序包所提供的CAPABILITY |
| -R | 查询指定的程序包所依赖的CAPABILITY |
常见查询用法:
rpm -qi PACKAGE
rpm -qf FILE
rpm -qc PACKAGE
rpm -ql PACKAGE
rpm -qd PACKAGE
rpm -qpi PACKAGE_FILE
rpm -qpl PACKAGE_FILE ...
rpm -qa
26.4 包卸载
格式:
--nodeps 不检查依赖关系,强制卸载或者强行安装
rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--notriggers] [--test] PACKAGE_NAME ...
注意:当包卸载时,对应的配置文件不会删除,以FILENAMErpmsave形式保留
26.5 包校验
在安装包时,系统也会检查包的来源是否是合法的
检查包的完整性和签名
rpm -K|checksing rpmfile
范例:破坏rpm包,即恢复
echo " ">> FILENAME.rpm #追加一个空格到这个rpm文件中
vim -b FILENAME.rpm #使用vim二进制方式打开,不加-b会在最后面加上一个0x0a(换行符)
:%!xxd #%代表全局替换,成十六进制模式(xxd是一个linux命令用来转换成十六进制 !是在vim中调用外部命令)
:%!xxd -r #转换成二进制
在检查包的来源和完整性前,必须导入所需公钥
范例:
cat /etc/pki/rpm-gpg/RPM-GPG-KEY-centos7 #查看gpg公钥
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial #导入gpg公钥
文件在安装时,会将包里的每个文件的元数据,如:大小,权限,所有者,时间等记录下来,可以用来检查包中的文件是否和当初安装时有所变化
rpm {-V|--verify} [select-options] [verify-options]
S file Size differs
M Mode differs (includes permissions and file type)
5 digest (formerly MD5 sum) differs
D Device major/minor number mismatch
L readLink(2) path mismatch
U User ownership differs
G Group ownership differs
T mTime differs
P capabilities differ
26.6 数据库
rpm包安装时生成的信息,都放在rpm数据库中
/var/lib/rpm #rpm 所有命令都会调用这个库,如果被破坏将无法正常使用rpm 命令
可以重建数据库
rpm {--initdb|--rebuilddb}
initdb:初始化,如果事先不存在数据库,则新建之,否则,不执行任何操作
rebuilddb:重建已安装的包头的数据库索引目录
27. yum和dnf
CentOS使用yum,dnf解决rpm的包依赖关系
YUM:Yellowdog Update Modifier,rpm的前端程序,可解决软件包相关依赖性,可在多个库之间定位软件包,up2date的替代工具,CentOS 8 用dnf代替了yum,不过保留了yum的兼容性,配置也是通用的
27.1 yum/dnf 工作原理
yum/dnf是基于C/S模式
yum服务器存放rpm包和相关包的元数据
yum客户端访问yum服务器进程安装或查询等
yum实现过程
先在yum服务器上创建yum repository(仓库),在仓库中事先存储了众多rpm包,以及包的相关的元数据文件(放置于特定目录repodata下),当yum客户端利用yum/dnf工具进行安装包时,会自动下载repodata中元数据,查询元数据是否存在相关的包及依赖关系,自动从仓库中找到相关包下载并安装。
yum安装包过程:
本地端:从repodata中的索引数据库中找到对应的rpm包及依赖关系进行安装。
客户端:从baseurl指定的地址去找repodata中的索引数据库,然后根据索引数据库找到对应的rpm包及依赖关系进行下载,第一次安装后就会保存索引记录,下次安装可以直接根据索引记录安装。
yum服务器的仓库可以以多种形式存在:
file:// 本地路径
http://
https://
ftp://
27.2 yum客户端配置
yum客户端配置文件
/etc/yum.conf #为所有仓库提供公共配置
/etc/yum.repos.d/*.repo #为每个仓库的提供配置文件
帮组参考:man 5 yum.conf
范例:CentOS8yum配置文件解析
cat /etc/yum.conf
[main]
gpgcheck=1 #安装包前要做包的合法性和完整性校验
installonly_limit=3 #同时可以安装3个包,最小值为2,如设为0或1,为不限制
clean_requirements_on_remove=True #删除包时,是否将不再使用的包删除
best=Ture #升级时,自动选择安装最新版,即使缺少依赖
# ll /etc/yum.conf
-rw-r--r--. 1 root root 970 Dec 3 2015 /etc/yum.conf
范例:CentOS7yum配置文件解析
[main]
cachedir=/var/cache/yum/$basearch/$releasever #客户端下载服务端包的缓存路径,basearch表示CPU架构,releasever表示操作系统的主版本号
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
installonly_limit=5
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=23&ref=http://bugs.centos.org/bug_report_page.php?category=yum
distroverpkg=centos-release
范例:导入key(系统默认没有导入key)
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #导入key,因为gpgcheck=1表示开启包的校验需要key校验
repo仓库配置文件指向的定义:
[repositoryID] #仓库唯一标识
name=Some name for this repository #仓库描述名称
baseurl=url://path/to/repository/ #唯一路径,还有mirrorlist多个路径
enable={1|0} #仓库启用=1(默认启用),仓库禁用=0
gpgcheck={1|0} #gpg校验=1,就需要下面gpgkey
gpgkey=URL #gpg校验的key路径
27.3 yum命令
yum命令的用法:
yum [options] [command] [package ...]
yum的命令行选项:
| -y | 自动回答为“yes” |
|---|---|
| -q | 静默模式 |
| --nogpgcheck | 禁止进行gpgcheck |
| --enablerepo=repoidglob | 临时启用此处指定的repo |
| --disablerepo=repoidglob | 临时禁用此处指定的repo |
| --noplugins | 禁用所有插件 |
27.3.1 显示仓库列表
yum repolist [all|enabled|disabled]
27.2.3 显示程序包
yum list
yum list [all | glob_exp1] [glob_exp2] [...]
yum list {available | installed|updates} [glob_exp1] [...]
范例:
# dnf list mariadb-server
# dnf list mariadb-server --showuplicates
# dnf list mariadb-server --disablerepo=AppStream
# dnf list mariadb-server --showduplicates --disablerepo=AppStream
27.3.3 安装程序包
注意点:yum remove 包名,只会把这个包卸载,但是依赖所安装的却不会删除,需要用 yum history id undo(还原该id安装之前的样子)
yum install package1 [package2] [...]
yum reinstall package1 [package2] [...] #重新安装
27.3.4 卸载程序包
yum remove | erase package1 [package2] [...]
27.3.5 升级和降级
yum update [package1] [package2] [...]
yum downgrade package1 [package2] [...] (降级)
检查可用升级:
yum check-update
27.3.6 查询
查看程序包information:
yum info [...]
查看指定的特性(可以是某文件)是由哪个程序包所提供
yum provides | whatprovides feature1 [feature2] [...]
范例:当指定包没有安装时,也可以通过provides查询由那个程序包所提供
# yum provides vsftpd
以指定的关键字搜索程序包名及summary信息
yum search string1 [string2] [...]
查看指定包所依赖的capabilities:
yum deplist package1 [package2] [...]
范例:
# dnf info bash
28. 程序包编译
28.1 编译源码的项目工具
C、C++de源码编译:使用make项目管理器
相关开发工具
autoconf:生成configure脚本
automake:生成Makefile.in
java源码编译:使用maven
28.2 C语言源码编译安装过程
三个大步骤
1、./configure
(1)执行./configure脚本,通过选项传递参数,指定对应服务的安装路径,启用的特性;
(2)可以检查依赖到外部环境,如依赖的软件包
2、make 根据Makefile.in文件生成Makefile文件,构建应用程序
3、make install 复制文件到相应路径
28.2.1 编译安装准备
准备:安装相关依赖包
开发工具:make(编译命令工具,用来解释Makefile中的规则)gcc(c/c++编译器GNU C Complier )
源码:对应官方地址下载
28.2.2 编译安装
第一步:运行configure脚本,生成Makefile文件
该步骤主要功能:
可以指定安装的位置
指定启用的特性
./configure --help #查看脚本帮助
选项分类:
安装路径设置:
| --prefix=/PATH | 指定默认安装位置,默认为/usr/local/ |
|---|---|
| --sysconfigdir=/PATH | 配置文件安装位置 |
| System types | 支持交叉编译 |
软件特性和相关指定:
Optionnal Features:可选特性
--disable-FEATURE
--enable-FEATURE[=ARG]
Options Packages:可选包
--with-PACKAGE[=ARG] 依赖包
--without-PACKAGE 禁用依赖关系
注意:通常被编译操作依赖的程序包,需要安装此程序包的“开发”组件,其包名一般类似于name-devel-VERSION
第二步:make
第三部:make install
28.2.3 安装后的配置
1.二进制程序目录导入至PATH环境变量中,编辑文件/etc/profile.d/NAME.sh
export PATH=/PATH/TO/BIN:$PATH #配置环境变量,可以写个脚本放在上面的路径,执行优先级是从左到右
范例:编译安装cmatrix
#1 安装基本包
#2 下载并解压缩包
#3 配置
#4 编译安装,可能会出错,观察出错提示,安装欠缺包(删除源码文件夹,重新解压,重新编译)
#5 配置环境
#6 运行
范例:编译安装httpd
#1 安装基本包
yum -y install gcc make (其他httpd服务器所需包,等等根据configure执行报错提示来安装)
#2 下载httpd源码包
curl xxxx
#3 使用configure脚本选项,配置httpd安装路径,及特性
./configure \
--prefix=/apps/httpd2.4 \ #--prefix是指定该服务的一级目录(总目录),其他配置文件都会存放在该指定目录的下层
--sysconfdir=/etc/httpd2.4 \ #单独指定配置文件的目录(默认是在/apps/httpd2.4/etc/目录下,就是总目录的/etc/下)
--enable--ssl \
--enable-so
#4 找到缺少的包
yum list avairible "*apr" #avairible表示可用的,就是没安装的关键字,包含apr关键字的包
yum -y install apr-devel #一般编译安装的包后面都要加-devel,在重新执行./configure,最后的报错少什么按上面方法搜索再次安装
#5 编译安装
make && make install #会少一个Redhat-rpm-config(思路一样用yum search查找可疑缺失包进行安装即可)
#6 指定PATH变量路径
echo 'PATH=/apps/httpd2.4/bin:$PATH' > /etc/profile.d/httpd2.4.sh
. /etc/profile.d/httpd2.4.sh
#7 启动服务
apachectl
#8 修改主页面
cat /apps/httpd2.4/htdocs/index.html
<html><body><h1>welcome to magedu!</h1></body></html>
#9 指定apache用户运行
useradd -r -s /sbin/nologin apache
vim /etc/httpd2.4/httpd.conf
user apache
group apache
#10生效和验证
apachectl -k stop #不行的话用killall apache,可以用man apachectl 查看该服务帮助
apachectl
范例:一键源码编译安装httpd
把编译安装过程写成脚本
29. 磁盘结构与分区方式MBR和GPT
跳过了,数据恢复的知识点,linux当中使用的不多
29.1 分区管理相关工具
29.1.2 fdisk命令
Linux fdisk 是一个创建和维护分区表的程序,它兼容 DOS 类型的分区表、BSD 或者 SUN 类型的磁盘列表。(MBR最大只支持2T的分区,超过2T,就要使用GPT分区类型的管理命令)
语法
fdisk [必要参数][选择参数]
必要参数:
-l 列出素所有分区表
-u 与-l搭配使用,显示分区数目
选择参数:
-s<分区编号> 指定分区
-v 版本信息
菜单操作说明
m :显示菜单和帮助信息
a :活动分区标记/引导分区
d :删除分区
l :显示分区类型
n :新建分区
p :显示分区信息
q :退出不保存
t :设置分区号
v :进行分区检查
w :保存修改
x :扩展应用,高级功能
29.1.3 gdisk命令
gdisk又叫GPT fdisk,算是fdisk的延伸吧,主要使用的是GPT分区类型,用来划分容量大于2T的硬盘。
选项
-l #列出一个磁盘的所有分区表
完整的菜单如下:
主要用到的几个和fdisk差不多:n、p、q、w。
b 将GPT数据备份到一个文件
c 更改分区名称
d 删除一个分区
i 显示分区详细信息
l 列出已知分区类型。此处8200是Linux swap,8300是Linux filesystem(对应fdisk的82和83)。还有一个8e00是Linux LVM
n 增加一个新的分区
o 创建一个新的空白的GPT分区表
p 显示当前磁盘的分区表
q 退出gdisk程序,不保存任何修改
r 恢复和转换选项(仅限专家)
s 排序分区
t 改变分区的类型
v 验证磁盘分区表
w 将分区表写入裁判并退出(保存并退出)
x 额外功能(仅限专家)
? 显示帮助信息
29.1.4 parted命令
Parted是一个比fdisk更高级的工具,它支持多种分区表格式,包括MS-DOS和GPT。
注意点:parted的操作是即刻生效的
命令格式
用法:parted [选项] [设备] [指令]
选项
-h, 显示此求助信息
-l, 列出系统系统中所有的磁盘设备,和fdisk -l命令的作用差不多。
-m, 进入交互模式,如果后面不加设备则对第一个磁盘进行操作
-s, 脚本模式
-v, 显示版本
29.1.5 parted交互模式菜单
align-check 检查分区N的类型(min|opt)是否对齐
help 打印通用求助信息,或关于[指令]的帮助信息
mklabel 创建新的磁盘标签 (分区表)
mkpart 创建一个分区
name 给指定的分区命名
print 打印分区表,或者分区
quit 退出程序
rescue 修复丢失的分区
resizepart 调整分区大小
rm 删除分区
select 选择要编辑的设备,默认只对指定的设备操作,这里可以改变指定的设备
disk_set 更改选定设备上的标志
disk_toggle 切换选定设备上的标志状态
set 更改分区的标记
toggle 设置或取消分区的标记
unit 设置默认的单位
version 显示版本信息
29.2 挂载
29.2.1 挂载文件系统mount
Linux mount命令是经常会使用到的命令,它用于挂载Linux系统外的文件。
语法
mount [-hV]
mount -a [-fFnrsvw] [-t vfstype]
mount [-fnrsvw] [-o options [,...]] device | dir
mount [-fnrsvw] [-t vfstype] [-o options] device dir
参数说明:
-V:显示程序版本
-h:显示辅助讯息
-v:显示较讯息,通常和 -f 用来除错。
-a:将 /etc/fstab 中定义的所有档案系统挂上。
-F:这个命令通常和 -a 一起使用,它会为每一个 mount 的动作产生一个行程负责执行。在系统需要挂上大量 NFS 档案系统时可以加快挂上的动作。
-f:通常用在除错的用途。它会使 mount 并不执行实际挂上的动作,而是模拟整个挂上的过程。通常会和 -v 一起使用。
-n:一般而言,mount 在挂上后会在 /etc/mtab 中写入一笔资料。但在系统中没有可写入档案系统存在的情况下可以用这个选项取消这个动作。
-s-r:等于 -o ro
-w:等于 -o rw
-L:将含有特定标签的硬盘分割挂上。
-U:将档案分割序号为 的档案系统挂下。-L 和 -U 必须在/proc/partition 这种档案存在时才有意义。
-t:指定档案系统的型态,通常不必指定。mount 会自动选择正确的型态。
-o async:打开非同步模式,所有的档案读写动作都会用非同步模式执行。
-o sync:在同步模式下执行。
-o atime、-o noatime:当 atime 打开时,系统会在每次读取档案时更新档案的『上一次调用时间』。当我们使用 flash 档案系统时可能会选项把这个选项关闭以减少写入的次数。
-o auto、-o noauto:打开/关闭自动挂上模式。
-o defaults:使用预设的选项 rw, suid, dev, exec, auto, nouser, and async.
-o dev、-o nodev-o exec、-o noexec允许执行档被执行。
-o suid、-o nosuid:
允许执行档在 root 权限下执行。
-o user、-o nouser:使用者可以执行 mount/umount 的动作。
-o remount:将一个已经挂下的档案系统重新用不同的方式挂上。例如原先是唯读的系统,现在用可读写的模式重新挂上。
-o ro:用唯读模式挂上。
-o rw:用可读写模式挂上。
-o loop=:使用 loop 模式用来将一个档案当成硬盘分割挂上系统。
实例
mount /dev/hda1 /mnt #将 /dev/hda1 挂在 /mnt 之下。
mount -o ro /dev/hda1 /mnt #将 /dev/hda1 用唯读模式挂在 /mnt 之下。
mount -o loop /tmp/image.iso /mnt/cdrom #将 /tmp/image.iso 这个光碟的 image 档使用 loop 模式挂在 /mnt/cdrom之下。
29.2.2 卸载文件系统umount
Linux umount(英文全拼:unmount)命令用于卸除文件系统。
umount可卸除目前挂在Linux目录中的文件系统。
语法
umount [-ahnrvV][-t <文件系统类型>][文件系统]
参数:
-a 卸除/etc/mtab中记录的所有文件系统。
-h 显示帮助。
-n 卸除时不要将信息存入/etc/mtab文件中。
-r 若无法成功卸除,则尝试以只读的方式重新挂入文件系统。
-t<文件系统类型> 仅卸除选项中所指定的文件系统。
-v 执行时显示详细的信息。
-V 显示版本信息。
[文件系统] 除了直接指定文件系统外,也可以用设备名称或挂入点来表示文件系统。
实例
umount -v /dev/sda1 #通过设备名卸载并显示执行信息
umount -v /mnt/mymount/ #通过挂载点卸载
29.2.3 查看挂载情况
mount查看挂载的文件
mount #通过查看/etc/mtab文件显示当前系统已挂载的所有设备
blkid
blkid命令对查询设备上所采用文件系统类型进行查询。
blkid [块设备]
29.2.4 持久挂载
如果我们想实现开机自动挂载某设备,只要修改/etc/fstab文件即可。
要挂载的设备或伪文件系统 挂载点 文件系统类型 挂载选项 转储频率 自检次序
UUID=6efb8a23-bae1-427c-ab10-3caca95250b1 /boot xfs defaults 0 0
要挂载的设备或伪文件系统:设备文件、LABEL(LABEL="")、UUID(UUID="")、伪文件系统名称(proc, sysfs)
挂载点:指定的文件夹
挂载选项:defaults
转储频率:
0:不做备份
1:每天转储
2:每隔一天转储
自检次序:
0:不自检
1:首先自检;一般只有rootfs才用1;
mount -a #依据配置文件/etc/fstab的内容,自动挂载
29.3 swap交换分区
交换分区的作用相当于虚拟内存,当系统真实内存不够用的时候,或者达到使用占比值时,就会使用swap的虚拟内存
29.3.1 创建swap交换分区
echo -e 'n\n p\n \n \n +2G\n t\n 82\n w' | fdisk /dev/vdb #非交换式创建swap分区,t修改分区类型,82swap分区类型
29.3.2 查看swap分区信息
cat /proc/swaps
swapon -s
29.3.3 配置swap交换分区的优先级
echo 'UUID=ac35354f-edec-4397-95ca-56d5f0b4147c swap swap defaults,(pri=优先级) 0 0' > /etc/fstab #优先级越大,就优先使用对应的swap分区
29.3.4 查看swap交换分区使用占比值
cat /proc/sys/vm/swappiness #30=100-70 ,当系统内存使用到70%的时候,就会启用swap虚拟内存交换分区空间
echo 0 > /proc/sys/vm/swappiness #百分百使用内存空间,用完百分百之后再用swap分区
29.3.5 swap相关命令
1、mkswap 分区设备名 #将指定的分区格式化为swap交换文件系统。
2、swapon 交换分区设备名|-a #启动指定的交换分区或所有交换分区。
3、swapoff 交换分区设备名|-a #禁用指定的交换分区或所有交换分区。
4、swapon -s #查看交换分区的使用情况。
5、free -m #以兆字节为单位显示物理内存、交换分区的使用情况。
29.4 使用光盘
在图形环境下自动启用挂载/run/media/
29.4.1 手工挂载
mount /dev/cdrom /mnt
29.4.2 操作光盘
eject #弹出光盘
eject -t #弹入光盘
29.4.3 创建ISO文件
cp /dev/cdrom /root/centos.iso
mkisofs -r -o /root/etc.iso /etc #类似于tar命令,单纯的把系统打包成ISO文件
29.4.4 刻录光盘
wodim -v -eject centos.iso
29.5 USB介质
29.5.1 查看USB设备是否识别
lsusb
被内核探测为SCSI设备
在图形化界面中自动挂载在/run/media/
29.5.2 手动挂载
mount /dev/sdX# /mnt
30. 磁盘常见工具
文件系统空间占用等信息的查看
30.1 工具df
df [OPTION]... [FILE]...
常见选项
-H #以10为单位
-T #文件系统类型
-h #human-readable(人性化显示)
-i #inodes instead of blocks
-P #以Posix(标准)兼容的格式输出
查看某目录总体空间占用状态du
du [OPTION]... DIR
常用选项
-h #human-readable(人性化显示)
-s #summary
--max-depth=# 指定最大目录层级
30.2 工具dd
dd命令:convert and copy a file
格式:
dd if=/PATH/FROM/SEC of=/PATH/TO/DEST bs=# count=#
常用选项
1. if=文件名:输入文件名,缺省为标准输入。即指定源文件。< if=input file >
2. of=文件名:输出文件名,缺省为标准输出。即指定目的文件。< of=output file >
3. ibs=bytes:一次读入bytes个字节,即指定一个块大小为bytes个字节。
obs=bytes:一次输出bytes个字节,即指定一个块大小为bytes个字节。
bs=bytes:同时设置读入/输出的块大小为bytes个字节。
4. cbs=bytes:一次转换bytes个字节,即指定转换缓冲区大小。
5. skip=blocks:从输入文件开头跳过blocks个块后再开始复制。
6. seek=blocks:从输出文件开头跳过blocks个块后再开始复制。
注意:通常只用当输出文件是磁盘或磁带时才有效,即备份到磁盘或磁带时才有效。
7. count=blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数。
8. conv=conversion:用指定的参数转换文件。
ascii:转换ebcdic为ascii
ebcdic:转换ascii为ebcdic
ibm:转换ascii为alternate ebcdic
block:把每一行转换为长度为cbs,不足部分用空格填充
unblock:使每一行的长度都为cbs,不足部分用空格填充
lcase:把大写字符转换为小写字符
ucase:把小写字符转换为大写字符
swab:交换输入的每对字节
noerror:出错时不停止
notrunc:不截短输出文件
sync:将每个输入块填充到ibs个字节,不足部分用空(NUL)字符补齐。
31. RAID
31.1 什么是RAID
RAID主要三个关键概念和技术
- 镜像(Mirroring)
- 数据条带(Data Stripping)
- 数据校验(Data parity)
RAID主要优势
- 大容量
- 高可用性
- 可靠性
- 可管理性
- RAID等级
- JBOD
标准RAID等级
1、RAID0
2、RAID1
3、RAID2
4、RAID3
5、RAID4
6、RAID5
7、RAID6
RAID组合等级
- RAID00
- RAID01和RAID10
- RAID100
- RAID30、RAID50、RAID60
32. LVM逻辑卷
当遇到分区不够用,却无法扩容的时候,这时候就需要lvm对磁盘的动态管理。
LVM是Linux环境中对磁盘分区进行管理的一种机制,是建立在硬盘和分区之上、文件系统之下的一个逻辑层,可提高磁盘分区管理的灵活性。
逻辑卷管理概念?
32.1 物理卷(PV, Physical Volume)
物理卷就是指磁盘,磁盘分区或从逻辑上和磁盘分区具有同样功能的设备(如RAID),是LVM的基本存储逻辑块,但和基本的物理存储介质(如分区、磁盘等)比较,却包含有和LVM相关的管理参数。当前LVM允许你在每个物理卷上保存这个物理卷的0至2份元数据拷贝.默认为1,保存在设备的开始处.为2时,在设备结束处保存第二份备份.
32.2 卷组(VG, Volume Group)
LVM卷组类似于非LVM系统中的物理硬盘,其由物理卷组成。能在卷组上创建一个或多个“LVM分区”(逻辑卷),LVM卷组由一个或多个物理卷组成。
32.3 逻辑卷(LV, Logical Volume)
LVM的逻辑卷类似于非LVM系统中的硬盘分区,在逻辑卷之上能建立文件系统(比如/home或/usr等)。
关系如下:

[:space:] ↩︎

浙公网安备 33010602011771号