Mark blog

知行合一 划水归档

编程基础

程序:指令+数据

程序编程风格:

​ 过程式:以指令为中心,数据服务于指令

​ 对象式:以数据为中心,指令服务于数据

shell程序:提供了编程能力,解释执行

程序的执行方式

编程逻辑处理方式:

​ 顺序执行

​ 循环执行

​ 选择执行

shell编程:过程式、解释执行

​ 编程语言的基本结构:

​ 各种系统命令的组合

​ 数据存储:变量、数组

​ 表达式: a + b

​ 语句:if

shell脚本基础

shell脚本:

​ 包含一些命令或声明,并符合一定格式的文本文件

格式要求:首行shebang机制

​ #!/bin/bash

​ #!/usr/bin/python

​ #!/usr/bin/perl

shell脚本的用途有:

​ 自动化常用命令

​ 执行系统管理和故障排除

​ 创建简单的应用程序

​ 处理文本或文件

创建shell脚本

第一步:使用文本编辑器来创建文本文件

​ 第一行必须包括shell声明序列:#!

​ #!/bin/bash

​ 添加注释

​ 注释以#开头

​ 第二步:运行脚本

​ 给予执行权限,在命令行上指定脚本的绝对或相对路径

​ 直接运行解释器,将脚本作为解释器程序的参数运行

脚本规范

脚本代码开头约定

​ 1、第一行一般为调用使用的语言

​ 2、程序名,避免更改文件名为无法找到正确的文件

​ 3、版本号

​ 4、更改后的时间

​ 5、作者相关信息

​ 6、该程序的作用,及注意事项

​ 7、最后是各版本的更新简要说明

脚本的基本结构

#!SHEBANG

CONFIGURATION_VARIABLES

FUNCTION_DEFINITIONS

MAIN_CODE

脚本调试

检测脚本中的语法错误

​ bash -n /path/to/some_script

调试执行

​ bash -x /path/to/some_script

变量

变量:命名的内存空间

​ 数据存储方式:

​ 字符:

​ 数值:整型,浮点型

变量:变量类型

​ 作用:

​ 1、数据存储格式

​ 2、参与的运算

​ 3、表示的数据范围

​ 类型:

​ 字符

​ 数值:整型、浮点型

强类型:变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转 换.一般定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明 变量会产生错误

​ 如 java,c#

弱类型:语言的运行时会隐式做数据类型转换.无须指定类型,默认均为字符 型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用

​ 如:bash 不支持浮点数,php

变量命名法则:

​ 1、不能使程序中的保留字:例如if, for

​ 2、只能使用数字、字母及下划线,且不能以数字开头

​ 3、见名知义

​ 4、统一命名规则:驼峰命名法

bash中变量的种类

根据变量的生效范围等标准划分下面变量类型:

​ 局部变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括 当前shell的子shell进程均无效

​ 环境(全局)变量:生效范围为当前shell进程及其子进程

​ 本地变量:生效范围为当前shell进程中某代码片断,通常指函数

​ 位置变量:$1, $2, …来表示,用于让脚本在脚本代码中调用通过命令行传递给它 的参数

​ 特殊变量:$?, $0, $*, $@, $#,$$

局部变量

变量赋值:name=‘value’

可以使用引用value:

​ (1) 可以是直接字串; name=“root”

​ (2) 变量引用:name=”$USER”

​ (3) 命令引用:name=`COMMAND` name=$(COMMAND)

变量引用:${name} $name

​ "“:弱引用,其中的变量引用会被替换为变量值

​ '‘:强引用,其中的变量引用不会被替换为变量值,而保持原字符串

显示已定义的所有变量:set

删除变量:unset name

环境变量

变量声明、赋值:

​ 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

​ MAIL

​ HOSTNAME

​ HISTSIZE

只读和位置变量

只读变量:只能声明,但不能修改和删除

​ 声明只读变量:

​ readonly name

​ declare -r name

​ 查看只读变量:

​ readonly –p

位置变量:在脚本代码中调用通过命令行传递给脚本的参数

​ $1, $2, …:对应第1、第2等参数,shift [n]换位置

​ $0: 命令本身

​ $*: 传递给脚本的所有参数,全部参数合为一个字符串

​ $@: 传递给脚本的所有参数,每个参数为独立字符串

​ $#: 传递给脚本的参数的个数

​ $@ $* 只在被双引号包起来的时候才会有差异

​ set – 清空所有位置变量

退出状态

进程使用退出状态来报告成功或失败

​ • 0 代表成功,1-255代表失败

​ • $? 变量保存最近的命令退出状态

例如:

​ ping -c1 -W1 hostdown &> /dev/null

​ echo $?

退出状态码

bash自定义退出状态码

​ exit [n]:自定义退出状态码

注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命 令后面的数字 注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行 的最后一条命令的状态码

算数运算

bash中的算术运算:help let

​ +, -, *, /, %取模(取余), **(乘方)

​ 实现算术运算:

​ (1) let var=算术表达式

​ (2) var=$[算术表达式]

​ (3) var=$((算术表达式))

​ (4) var=$(expr arg1 arg2 arg3 …)

​ (5) declare –i var = 数值

​ (6) echo ‘算术表达式’ | bc

乘法符号有些场景中需要转义,如*

bash有内建的随机数生成器:$RANDOM(0-32767)

​ echo $[$RANDOM%50] :0-49之间随机数

赋值

增强型赋值:

​ +=, -=, *=, /=, %=

let varOPERvalue

​ 例如:let count+=3 自加3后自赋值

自增,自减:

​ let var+=1

​ let var++ let

​ var-=1

​ let var–

逻辑运算

true, false

​ 1, 0

与(and):

​ 1 与 1 = 1

​ 1 与 0 = 0

​ 0 与 1 = 0

​ 0 与 0 = 0

或(or):

​ 1 或 1 = 1

​ 1 或 0 = 1

​ 0 或 1 = 1

​ 0 或 0 = 0

非(not):!

​ ! 1 = 0

​ ! 0 = 1

短路运算

​ 短路与

​ 第一个为0,结果必定为0

​ 第一个为1,第二个必须要参与运算

短路或

​ 第一个为1,结果必定为1

​ 第一个为0,第二个必须要参与运算

异或:

​ ^ 异或的两个值,相同为假,不同为真

条件测试

判断某需求是否满足,需要由测试机制来实现

专用的测试表达式需要由测试命令辅助完成测试过程

评估布尔声明,以便用在条件性执行中

​ • 若真,则返回0

​ • 若假,则返回1

测试命令:

​ • test EXPRESSION

​ • [ EXPRESSION ]

​ • [[ EXPRESSION ]]

​ 注意:EXPRESSION前后必须有空白字符

条件性的执行操作符

根据退出状态而定,命令可以有条件地运行

​ • && 代表条件性的AND THEN

​ • || 代表条件性的OR ELSE

例如:

grep -q no_such_user /etc/passwd \

|| echo 'No such user'

No such user

ping -c1 -W2 station1 &> /dev/null \

> && echo “station1 is up" \

> || (echo ‘station1 is unreachable’; exit 1)

station1 is up

test命令

长格式的例子:

​ test “$A” = “$B” && echo “Strings are equal”

​ test “$A”-eq “$B” && echo “Integers are equal”

简写格式的例子:

​ [ “$A” = “$B” ] && echo “Strings are equal”

​ [ “$A” -eq “$B” ] && echo “Integers are equal”

bash的数值测试

-v VAR

​ 变量VAR是否设置

数值测试:

​ -gt 是否大于

​ -ge 是否大于等于

​ -eq 是否等于

​ -ne 是否不等于

​ -lt 是否小于

​ -le 是否小于等于

bash 的字符串测试

字符串测试:

​ = 是否等于

​ > ascii码是否大于ascii码

​ < 是否小于

​ != 是否不等于

​ =~ 左侧字符串是否能够被右侧的PATTERN所匹配,注意: 此表达式一般用于[[ ]]中;扩展的正则表达式

​ -z “STRING“ 字符串是否为空,空为真,不空为假

​ -n “STRING“ 字符串是否不空,不空为真,空为假

注意:用于字符串比较时的用到的操作数都应该使用引号

bash的文件测试

存在性测试

​ -a FILE:同-e

​ -e FILE: 文件存在性测试,存在为真,否则为假

存在性及类别测试

​ -b FILE:是否存在且为块设备文件

​ -c FILE:是否存在且为字符设备文件

​ -d FILE:是否存在且为目录文件

​ -f FILE:是否存在且为普通文件

​ -h FILE 或 -L FILE:存在且为符号链接文件

​ -p FILE:是否存在且为命名管道文件

​ -S FILE:是否存在且为套接字文件

bash的文件权限测试

文件权限测试:

​ -r FILE:是否存在且可读

​ -w FILE: 是否存在且可写

​ -x FILE: 是否存在且可执行

文件特殊权限测试:

​ -u FILE:是否存在且拥有suid权限

​ -g FILE:是否存在且拥有sgid权限

​ -k FILE:是否存在且拥有sticky权限

bash的文件属性测试

文件大小测试:

​ -s FILE: 是否存在且非空

文件是否打开:

​ -t fd: fd 文件描述符是否在某终端已经打开

​ -N FILE:文件自从上一次被读取之后是否被修改过

​ -O FILE:当前有效用户是否为文件属主

​ -G FILE:当前有效用户是否为文件属组

双目测试:

​ FILE1 -ef FILE2: FILE1是否是FILE2的硬链接

​ FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)

​ FILE1 -ot FILE2: FILE1是否旧于FILE2

bash的组合测试条件

第一种方式:

​ COMMAND1 && COMMAND2 并且

​ COMMAND1 || COMMAND2 或者

​ ! COMMAND 非

​ 如:[[ -r FILE ]] && [[ -w FILE ]]

第二种方式:

​ EXPRESSION1 -a EXPRESSION2 并且

​ EXPRESSION1 -o EXPRESSION2 或者

​ ! EXPRESSION

​ 必须使用测试命令进行

使用read命令来接受输入

使用read来把输入值分配给一个或多个shell变量

​ -p 指定要显示的提示

​ -s 静默输入,一般用于密码

​ -n N 指定输入的字符长度N

​ -d ‘字符’ 输入结束符

​ -t N TIMEOUT为N秒

​ read 从标准输入中读取值,给每个单词分配一个变量

​ 所有剩余单词都被分配给最后一个变量

​ read -p “Enter a filename: “ FILE

bash展开命令行的顺序

把命令行分成单个命令词

展开别名

展开大括号的声明({})

展开波浪符声明(~)

命令替换$() 和 (``)

再次把命令行分成命令词

展开文件通配(* 、?、[abc]等等)

准备I/0重导向(<、>)

运行命令

防止扩展

反斜线()会使随后的字符按原意解释

​ $ echo Your cost: \$5.00

​ Your cost: $5.00

加引号来防止扩展

​ • 单引号(’)防止所有扩展

​ • 双引号(”)也防止所有扩展,但是以下情况例外:

​ $(美元符号) - 变量扩展

​ `(反引号) - 命令替换

​ (反斜线) - 禁止单个字符扩展

​ !(叹号) - 历史命令替换

bash的配置文件

按生效范围划分,存在两类:

全局配置:

​ /etc/profile

​ /etc/profile.d/*.sh

​ /etc/bashrc

个人配置:

​ ~/.bash_profile

​ ~/.bashrc

Profile类

按功能划分,存在两类:

​ profile类和bashrc类

profile类:为交互式登录的shell提供配置

​ 全局:/etc/profile, /etc/profile.d/*.sh

​ 个人:~/.bash_profile

​ 功用:

​ (1) 用于定义环境变量

​ (2) 运行命令或脚本

bashrc类

bashrc类:为非交互式和交互式登录的shell提供配置

​ 全局:/etc/bashrc

​ 个人:~/.bashrc

​ 功用:

​ (1) 定义命令别名和函数

​ (2) 定义本地变量

编辑配置文件生效

修改profile和bashrc文件后需生效

​ 两种方法:

​ 1重新启动shell进程

​ 2 . 或source

​ 例:

​ . ~/.bashrc

bash退出任务

保存在~/.bash_logout文件中(用户)

在退出登录shell时运行

用于

​ • 创建自动备份

​ • 清除临时文件

$-变量

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 个历史命令

VIM简介

vi: Visual Interface,文本编辑器

文本:ASCII, Unicode

文本编辑种类:

行编辑器: sed 

全屏编辑器:nano, vi 

vim - Vi Improved 

其他编辑器:

gedit 一个简单的图形编辑器 

gvim 一个Vim编辑器的图形版本 

打开文件

vim [OPTION]… FILE…

+#: 打开文件后,让光标处于第#行的行首,+默认行尾 

+/PATTERN:打开文件后,直接让光标处于第一个被PATTERN匹配到的行的行首 

–b file 二进制方式打开文件 

–d file1 file2… 比较多个文件 

-m file 只读打开文件 

ex file 或 vim –e 直接进入ex模式

如果该文件存在,文件被打开并显示内容 如果该文件不存在,当编辑后第一次存盘时创建它

vim: 一个模式编辑器

击键行为是依赖于 vim的 的”模式”

三种主要模式:

命令(Normal)模式:默认模式,移动光标,剪切/粘贴文本 

插入(Insert)或编辑模式: 修改文本 

扩展命令(extended command )模式: 保存,退出等 

Esc键 退出当前模式

Esc键 Esc键 总是返回到命令模式

模式转换

命令模式 –> 插入模式

i: insert, 在光标所在处输入 

I:在当前光标所在行的行首输入 

a: append, 在光标所在处后面输入 

A:在当前光标所在行的行尾输入 

o: 在当前光标所在行的下方打开一个新行 

O:在当前光标所在行的上方打开一个新行 

插入模式 ——–> 命令模式

ESC 

命令模式 ——–> 扩展命令模式

: 

扩展命令模式 ——–> 命令模式

ESC,enter 

关闭文件

扩展模式:

:q 退出 

:q! 强制退出,丢弃做出的修改 

:wq 保存退出 :x 保存退出 

命令模式

ZZ: 保存退出 

ZQ:不保存退出 

扩展模式

按”:”进入Ex模式

创建一个命令提示符: 处于底部的屏幕左侧

命令:

w     写(存)磁盘文件 

wq     写入并退出 

x     写入并退出 

q     退出 

q!     不存盘退出,即使更改都将丢失 

r filename     读文件内容到当前文件中 

w filename     将当前文件内容写入另一个文件 

!command     执行命令 

r!command     读入命令的输出 

命令模式光标跳转

字符间跳转:

h: 左 l: 右 j: 下 k: 上 

#COMMAND:跳转由#指定的个数的字符 

单词间跳转:

w:下一个单词的词首 

e:当前或下一单词的词尾 

b:当前或前一个单词的词首 

#COMMAND:由#指定一次跳转的单词数 

当前页跳转:

H:页首 M:页中间行 L:页底 

行首行尾跳转:

^: 跳转至行首的第一个非空白字符 

0: 跳转至行首 

$: 跳转至行尾 

行间移动:

#G、扩展模式:# :跳转至由#指定行 

G:最后一行 

1G, gg: 第一行 

句间移动:

):下一句 (:上一句 

段落间移动:

}:下一段 {:上一段 

命令模式翻屏操作

Ctrl+f: 向文件尾部翻一屏

Ctrl+b: 向文件首部翻一屏

Ctrl+d: 向文件尾部翻半屏

Ctrl+u:向文件首部翻半屏

命令模式操作

字符编辑:

x: 删除光标处的字符 

#x: 删除光标处起始的#个字符 

xp: 交换光标所在处的字符及其后面字符的位置 

~:转换大小写 

J:删除当前行后的换行符 

替换命令(r, replace)

r: 替换光标所在处的字符 

R:切换成REPLACE模式 

删除命令:

d: 删除命令,可结合光标跳转字符,实现范围删除 

d$: 删除到行尾 

d^:删除到非空行首 

d0:删除到行首 

dw: 

de: 

db: 

#COMMAND 

dd: 删除光标所在的行

#dd:多行删除 

D:从当前光标位置一直删除到行尾,留空行,等同于d$

复制命令(y, yank):

y: 复制,行为相似于d命令 

y$ 

y0 

y^ 

ye 

yw 

yb 

#COMMAND 

yy:复制行

#yy: 复制多行 

Y: 复制整行

粘贴命令(p, paste):

p:缓冲区存的如果为整行,则粘贴当前光标所在行的下方;否则,则粘贴 至当前光标所在处的后面 

P:缓冲区存的如果为整行,则粘贴当前光标所在行的上方;否则,则粘贴 至当前光标所在处的前面 

改变命令(c, change)

c: 修改后切换成插入模式 

命令模式 –> 插入模式

c$ 

c^ 

c0 

cb 

ce 

cw 

#COMMAND 

cc:删除当前行并输入新内容,相当于S

#cc: 

C:删除当前光标到行尾,并切换成插入模式

命令模式

100imark [ESC] 粘贴”mark”100次

<start position><commend><end position>

Command:

y 复制、d 删除、gU 变大写、gu 变小写 

例如 0y$ 命令意味着:

0 → 先到行头 

y → 从这里开始拷贝 

$ → 拷贝到本行最后一个字符 

ye 从当前位置拷贝到本单词的最后一个字符 

扩展命令模式:地址定界

地址定界

:start_pos,end_pos 

\# 具体第#行,例如2表示第2行 

\#,# 从左侧#表示起始行,到右侧#表示结尾行 

\#,+# 从左侧#表示的起始行,加上右侧#表示的行数 

    :2,+3 表示2到5行

 . 当前行 

$ 最后一行 

    .,$-1 当前行到倒数第二行 

% 全文, 相当于1,$ 

/pat1/,/pat2/

从第一次被pat1模式匹配到的行开始,一直到第一次被pat2匹配到的行结 束 

#,/pat/ 

/pat/,$ 

使用方式:后跟一个编辑命令

d 

y 

w file: 将范围内的行另存至指定文件中 

r file:在指定位置插入指定文件中的所有内容 

扩展命令模式:查找

查找

/PATTERN:从当前光标所在处向文件尾部查找 

?PATTERN:从当前光标所在处向文件首部查找 

n:与命令同方向 

N:与命令反方向 

扩展命令模式:查找并替换

s: 在扩展模式下完成查找替换操作

格式:s/要查找的内容/替换为的内容/修饰符 

要查找的内容:可使用模式 

替换为的内容:不能使用模式,但可以使用\1, \2, ...等后向引用符号;还可 以使用"&"引用前面查找时查找到的整个内容 

修饰符: 

i: 忽略大小写 

g: 全局替换;默认情况下,每一行只替换第一次出现 

gc:全局替换,每次替换前询问 

查找替换中的分隔符/可替换为其它字符,例如

s@/etc@/var@g 

s#/boot#/#i 

命令模式:撤销更改

u 撤销最近的更改

#u 撤销之前多次更改

U 撤消光标落在这行后所有此行的更改

按Ctrl - r重做最后的”撤消”更改

. 重复前一个操作

n. 重复前一个操作n次

vim的寄存器

有26个命名寄存器和1个无命名寄存器,常存放不同的剪贴版内容,可以不同会话间共享

寄存器名称a,b,…,z,格式:”寄存器 放在数字和命令之间

如:3"tyy 表示复制3行到t寄存器中  

"tp 表示将t寄存器内容粘贴 

未指定,将使用无命名寄存器

有10个数字寄存器,用0,1,…,9表示,0存放最近复制内容,1存放最近删除内容。当新的文本变更和删除时,1转存到2,2转存到3,以此类推。数字寄存器不能在不 同会话间共享

编辑二进制文件

以二进制方式打开文件

vim –b binaryfile 

扩展命令模式下,利用xxd命令转换为可读的十六进制

:%!xxd 

编辑二进制文件

扩展命令模式下,利用xxd命令转换回二进制

:%!xxd –r 

保存退出

可视化模式

允许选择的文本块

v 面向字符 

V 面向行 

ctrl-v 面向块 

可视化键可用于与移动键结合使用:

w ) } 箭头等 

突出显示的文字可被删除,复制,变更,过滤,搜索,替换等

多文件模式

vim FILE1 FILE2 FILE3 …

:next 下一个 

:prev 前一个 

:first 第一个 

:last 最后一个 

:wall 保存所有 

:qall 退出所有 

:wqall 保存退出所有

使用多个窗口

多文件分割

vim -o|-O FILE1 FILE2 ... 

-o: 水平分割 

-O: 垂直分割 

在窗口间切换:Ctrl+w, Arrow 

单文件窗口分割:

Ctrl+w,s: split, 水平分割 

Ctrl+w,v: vertical, 垂直分割 

ctrl+w,q:取消相邻窗口 

ctrl+w,o:取消全部窗口 

:wqall 退出 

定制vim的工作特性

配置文件:永久有效

全局:/etc/vimrc 

个人:~/.vimrc 

扩展模式:当前vim进程有效

(1) 行号

显示:set number, 简写为set nu 

取消显示:set nonumber, 简写为set nonu 

(2) 忽略字符的大小写

启用:set ic 

不忽略:set noic 

(3) 自动缩进

启用:set ai 

禁用:set noai

(4) 智能缩进

启用:smartindent 简写 set si 

禁用:set nosi 

(5) 高亮搜索

启用:set hlsearch 

禁用:set nohlsearch 

(6) 语法高亮

启用:syntax on 

禁用:syntax off 

(7) 显示Tab和换行符 ^I 和$显示

启用:set list 

禁用:set nolist 

(8) 文件格式

启用windows格式:set fileformat=dos 

启用unix格式:set fileformat=unix 

简写: set ff=dos|unix 

(9) 设置文本宽度

启用: set textwidth=65 (vim only) 

禁用: set wrapmargin=15 

(10) 设置光标所在行的标识线

启用:set cursorline,简写cul 

禁用:set no cursorline 

(11) 复制保留格式

启用: set paste 

禁用: set nopaste 

了解更多

Set 帮助

:help option-list 

:set or :set all 

vi/vim内置帮助

:help 

:help topic 

Use :q to exit help 

vimtutor

抽取文本的工具

文件内容:less和 cat

文件截取:head和tail

按列抽取:cut

按关键字抽取:grep

文件查看

文件查看命令 :

cat ,tac ,rev

cat [OPTION]… [FILE]…

-E: 显示行结束符$ 

-n: 对显示出的每一行进行编号 

-A:显示所有控制符 

-b:非空行编号 

-s:压缩连续的空行成一行 

tac

rev

分页查看文件内容

more: 分页查看文件

more [OPTIONS…] FILE…

-d: 显示翻页及退出提示 

less:一页一页地查看文件或STDIN输出

查看时有用的命令包括:

/文本 搜索 文本 

n/N 跳到下一个 或 上一个匹配 

less 命令是man命令使用的分页器

显示文本前或后行内容

head [OPTION]… [FILE]…

-c #: 指定获取前#字节 

-n #: 指定获取前#行 

-#: 指定行数 

tail [OPTION]… [FILE]…

-c #: 指定获取后#字节 

​ -n #: 指定获取后#行

-f: 跟踪显示文件fd新追加的内容,常用日志监控 

相当于 --follow=descriptor 

-F: 跟踪文件名,相当于—follow=name --retry     

tailf 类似tail –f,当文件不增长时并不访问文件

按列抽取文本cut和合并文件paste

cut [OPTION]… [FILE]…

-d DELIMITER: 指明分隔符,默认tab 

​ -f FILEDS:

​ #: 第#个字段

​ #,#[,#]:离散的多个字段,例如1,3,6

#-#:连续的多个字段, 例如1-6 

混合使用:1-3,7

-c 按字符切割

–output-delimiter=STRING指定输出分隔符

cut和paste

显示文件或STDIN数据的指定列

​ cut -d: -f1 /etc/passwd //以 : 为分隔符取出第一个参数

cat /etc/passwd | cut -d: -f7 

​ cut -c2-5 /usr/share/dict/words

paste 合并两个文件同行号的列到一行

paste [OPTION]... [FILE]... 

​ -d 分隔符:指定分隔符,默认用TAB

​ -s : 所有行合成一行显示

​ paste f1 f2

​ paste -s f1 f2

分析文本的工具

文本数据统计:wc

整理文本:sort

比较文件:diff和patch

收集文本统计数据wc

计数单词总数、行总数、字节总数和字符总数

可以对文件或STDIN中的数据运行

wc story.txt 

39     237 1901     story.txt 

行数 字数 字节数  文件名

常用选项

​ -l 只计数行数

​ -w 只计数单词总数

​ -c 只计数字节总数

​ -m 只计数字符总数

​ -L 显示文件中最长行的长度

文本排序sort

把整理过的文本显示在STDOUT,不改变原始文件

sort [options] file(s) 

常用选项

​ -r 执行反方向(由上至下)整理

​ -R 随机排序

​ -n 执行按数字大小整理

​ -f 选项忽略(fold)字符串中的字符大小写

​ -u 选项(独特,unique)删除输出中的重复行

​ -t c 选项使用c做为字段界定符

​ -k X 选项按照使用c字符分隔的X列来整理能够使用多次

uniq

uniq命令:从输入中删除前后相接的重复的行

uniq [OPTION]… [FILE]…

​ -c: 显示每行重复出现的次数

​ -d: 仅显示重复过的行

​ -u: 仅显示不曾重复的行

​ 注:连续且完全相同方为重复

常和sort 命令一起配合使用:

sort userlist.txt | uniq -c 

比较文件

比较两个文件之间的区别

diff foo.conf foo2.conf 

5c5 

< use_widgets = no 

--- 

> use_widgets = yes 

注明第5行有区别(改变)

复制对文件改变patch

diff 命令的输出被保存在一种叫做”补丁”的文件中

使用 -u 选项来输出"统一的(unified)"diff格式文件,最适用于补丁文件 

patch 复制在其它文件中进行的改变(要谨慎使用)

适用 -b 选项来自动备份改变了的文件 

$ diff -u foo.conf foo2.conf > foo.patch 

$ patch -b foo.conf foo.patch 

Linux文本处理三剑客

grep:文本过滤(模式:pattern)工具

grep, egrep, fgrep(不支持正则表达式搜索) 

sed:stream editor,文本编辑工具

awk:Linux上的实现gawk,文本报告生成器

grep

grep: Global search REgular expression and Print out the line

作用:文本搜索工具,根据用户指定的”模式”对目标文本逐行进行匹配检 查;打印匹配到的行

模式:由正则表达式字符及文本字符所编写的过滤条件

grep [OPTIONS] PATTERN [FILE…]

grep root /etc/passwd 

grep "$USER" /etc/passwd 

grep '$USER' /etc/passwd 

grep \`whoami` /etc/passwd 

grep命令选项

--color=auto: 对匹配到的文本着色显示 

-v: 显示不被pattern匹配到的行 

-i: 忽略字符大小写 

-n:显示匹配的行号 

-c: 统计匹配的行数 

-o: 仅显示匹配到的字符串 

-q: 静默模式,不输出任何信息 

-A #: after, 后#行 

-B #: before, 前#行 

-C #:context, 前后各#行 

-e:实现多个选项间的逻辑or关系 

   grep –e ‘cat ’ -e ‘dog’ file 

-w:匹配整个单词 

-E:使用ERE 

   使用正则表达式

-F:相当于fgrep,不支持正则表达式 

   可以测试文件1和文件2的包含关系

正则表达式

REGEXP:由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能

程序支持:grep,sed,awk,vim, less,nginx,varnish等

分两类:

基本正则表达式:BRE

扩展正则表达式:ERE

grep -E, egrep 

正则表达式引擎:

采用不同算法,检查处理正则表达式的软件模块

PCRE(Perl Compatible Regular Expressions)

元字符分类:字符匹配、匹配次数、位置锚定、分组

man 7 regex

基本正则表达式元字符

字符匹配:
​ . 匹配任意单个字符
​ [] 匹配指定范围内的任意单个字符
​ [^] 匹配指定范围外的任意单个字符
​ [:alnum:] 字母和数字
​ [:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
​ [:lower:] 小写字母 [:upper:] 大写字母
​ [:blank:] 空白字符(空格和制表符)
​ [:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
​ [:cntrl:] 不可打印的控制字符(退格、删除、警铃…)
​ [:digit:] 十进制数字 [:xdigit:]十六进制数字
​ [:graph:] 可打印的非空白字符
​ [:print:] 可打印字符
​ [:punct:] 标点符号

正则表达式

匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数

位置锚定:定位出现的位置

^ 行首锚定,用于模式的最左侧

$ 行尾锚定,用于模式的最右侧

^PATTERN$ 用于模式匹配整行

^$ 空行

^[[:space:]]*$ 空白行

< 或 \b 词首锚定,用于单词模式的左侧

> 或 \b 词尾锚定;用于单词模式的右侧

<PATTERN\> 匹配整个单词

分组:\(\) 将一个或多个字符捆绑在一起,当作一个整体进行处理,如: \(root\)\+

分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这 些变量的命名方式为: \1, \2, \3, …

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

示例: \(string1\+\(string2\)*\)

\1 :string1\\+\\(string2\\)* 

\2 :string2 

后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身

或者:\|

示例:a\\|b: a或b C\\|cat: C或cat \\(C\\|c\\)at:Cat或cat 
元字符 定义
^ 行首
$ 行尾
. 任意单一字符
[] []内任意单一字符
[^] 除[]内任意单一字符
* *前面字符重复不确定次数
\+ \+前面字符重复一次以上不确定次数
? ? 前面字符重复0或1次
\ 转义符
.* 任意长度字符
\{n\} 前面字符重复n次
\{n,\} 前面字符重复n次以上
\{m,n\} 前面字符重复m次和n次之间
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,即 A-Z,a-z
[:lower:] 小写字母
[:upper:] 大写字母
[:blank:] 水平空白字符(空格和制表符)
[:space:] 所有水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格,删除,警铃)
[:digit:] 十进制数字
[:graph:] 可打印的非空白字符
[:punct:] 标点符号
[:xdigit:] 十六进制数字

egrep及扩展的正则表达式

egrep = grep -E

egrep [OPTIONS] PATTERN [FILE…]

扩展正则表达式的元字符:

字符匹配:

. 任意单个字符 

[] 指定范围的字符 

[^] 不在指定范围的字符     

扩展正则表达式

次数匹配:

 *:匹配前面字符任意次 

?: 0或1次 

+:1次或多次 

{m}:匹配m次 

{m,n}:至少m,至多n次     

位置锚定:

 ^ :行首 

$ :行尾 

\<, \b :语首 

\>, \b :语尾     

分组:

() 

后向引用:\1, \2, ...     

或者:

a|b: a或b 

C|cat: C或cat 

(C|c)at:Cat或cat    

sed工具

用法:

sed [option]... 'script' inputfile... 

常用选项:

-n:不输出模式空间内容到屏幕,即不自动打印 

-e: 多点编辑 

-f:/PATH/SCRIPT_FILE: 从指定文件中读取编辑脚本 

-r: 支持使用扩展正则表达式 

-i.bak: 备份文件并原处编辑     

script:

'地址命令' 

地址定界:
(1) 不给地址:对全文进行处理
(2) 单地址:
​ #: 指定的行,$:最后一行
​ /pattern/:被此处模式所能够匹配到的每一行
(3) 地址范围:
​ #,#
​ #,+#
​ /pat1/,/pat2/
​ #,/pat1/
(4) :步进
​ 1
2 奇数行
​ 2~2 偶数行

编辑命令:

d             删除模式空间匹配的行,并立即启用下一轮循环 

p             打印当前模式空间内容,追加到默认输出之后 

a [\\]text         在指定行后面追加文本,支持使用\n实现多行追加 

i [\\\]text         在行前面插入文本 

c [\]text         替换行为单行或多行文本 

w /path/file     保存模式匹配的行至指定文件 

r /path/file     读取指定文件的文本至模式空间中匹配到的行后 

=             为模式空间中的行打印行号 

!             模式空间中匹配行取反处理     

s/// 查找替换,支持使用其它分隔符,s@@@,s###

替换标记:

g         行内全局替换 

p         显示替换成功的行 

w         /PATH/FILE 将替换成功的行保存至文件中     

高级编辑命令

P: 打印模式空间开端至\n内容,并追加到默认输出之前 

h: 把模式空间中的内容覆盖至保持空间中 

H:把模式空间中的内容追加至保持空间中 

g: 从保持空间取出数据覆盖至模式空间 

G:从保持空间取出内容追加至模式空间 

x: 把模式空间中的内容与保持空间中的内容进行互换 

n: 读取匹配到的行的下一行覆盖至模式空间 

N:读取匹配到的行的下一行追加至模式空间 

d: 删除模式空间中的行 

D:如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本, 并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间 不包含换行符,则会像发出d命令那样启动正常的新循环 

用户user

令牌token,identity

Linux用户:Username/UID

管理员:root, 0

普通用户:1-60000 自动分配

系统用户:1-499, 1-999 (CentOS7)

对守护进程获取资源进行权限分配

登录用户:500+, 1000+(CentOS7)

交互式登录

组group

Linux组:Groupname/GID

管理员组:root, 0

普通组:

系统组:1-499, 1-999(CENTOS7)

普通组:500+, 1000+(CENTOS7)

安全上下文

Linux安全上下文

运行中的程序:进程 (process)

以进程发起者的身份运行:

root: /bin/cat 

mark: /bin/cat 

进程所能够访问资源的权限取决于进程的运行者的身份

组的类别

Linux组的类别

用户的主要组(primary group)

用户必须属于一个且只有一个主组 

组名同用户名,且仅包含一个用户,私有组    

用户的附加组(supplementary group)

一个用户可以属于零个或多个辅助组 

用户和组的配置文件

Linux用户和组的主要配置文件:

/etc/passwd:        

    名称,密码,UID,GID,描述信息,用户家目录,shell类型 

/etc/group:        

    组及其属性信息

/etc/shadow:        

    用户名:加密字段:上一次口令更改的时间:最小的口令有效期:最大的口令有效期:口令过期时间:口令过期宽限时间:账户有效期:最后一位是保留位

/etc/gshadow:    

    组密码及其相关属性 

passwd文件格式

login name:登录用名(mark)

passwd:密码 (x)

UID:用户身份编号 (1000)

GID:登录默认所在组编号 (1000)

GECOS:用户全名或注释

home directory:用户主目录 (/home/mark)

shell:用户默认使用shell (/bin/bash)

账户中为!代表账户被锁定,虽然被锁定账户了,但是还是能够通过 su - username 来切换用户,但是如果将用户的 shell 类型设置为 nologin的话 再次切用户的时候是不能够输入命令的.

新建用户的时候如果不设置密码是无法登录的,会在shadow文件中出现!!,centOS7中会提示用户登录不需要密码.

使用 usermod -U username 来解锁

可以使用 chage username 来修改用户的账户时间

shadow文件格式

登录用名

用户密码:一般用sha512加密

从1970年1月1日起到密码最近一次被更改的时间

密码再过几天可以被变更(0表示随时可被变更)

密码再过几天必须被变更(99999表示永不过期)

密码过期前几天系统提醒用户(默认为一周)

密码过期几天后帐号会被锁定

从1970年1月1日算起,多少天后帐号失效

密码加密

加密机制:

加密:明文--> 密文 

解密:密文--> 明文 

单向加密:哈希算法,原文不同,密文必不同

相同算法定长输出,获得密文不可逆推出原始数据

雪崩效应:初始条件的微小改变,引起结果的巨大改变

md5: message digest, 128bits

sha1: secure hash algorithm, 160bits

sha224: 224bits

sha256: 256bits

sha384: 384bits

sha512: 512bits

更改加密算法:

authconfig --passalgo=sha256 --update

密码的复杂性策略

使用数字、大写字母、小写字母及特殊字符中至少3种

足够长

使用随机密码

定期更换,不要使用最近曾经使用过的密码

group文件格式

群组名称:就是群组名称

群组密码:通常不需要设定,密码是被记录在 /etc/gshadow

GID:就是群组的 ID

以当前组为附加组的用户列表

(分隔符为逗号)

gshdow文件格式

群组名称:就是群组名称

群组密码:

组管理员列表:组管理员的列表,更改组密码和成员

以当前组为附加组的用户列表

(分隔符为逗号)

用户和组管理命令

用户管理命令

useradd 

usermod 

userdel 

组帐号维护命令

groupadd 

groupmod 

groupdel

用户创建:useradd

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: 创建系统用户 CentOS 6: ID<500, CentOS 7: ID<1000

-m 创建家目录,用于系统用户 

​ -M 不创建家目录,用于非系统用户

使用 -r 选项创建系统用户的时候会默认不创建用户家目录,

默认值设定:/etc/default/useradd文件中

显示或更改默认设置

useradd -D 

useradd –D -s SHELL 

useradd –D –b BASE_DIR 

​ useradd –D –g GROUP

新建用户的相关文件和命令

/etc/default/useradd

/etc/skel/* 创建用户的时候默认的文件夹

/etc/login.defs 创建用户的时候默认的加密策略

newusers passwd 格式文件 批量创建用户

chpasswd 批量修改用户口令

用户属性修改

usermod [OPTION] login

-u UID: 新UID 

-g GID: 新主组 

-G GROUP1[,GROUP2,...[,GROUPN]]:新附加组,原来的附加组将会被 覆盖;若保留原有,则要同时使用-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: 设定非活动期限

删除所有的附加组 usermod -G “” apache

删除用户

userdel [OPTION]… login

-r: 删除用户家目录 

查看用户相关的ID信息

id [OPTION]... [USER] 

-u: 显示UID 

-g: 显示GID 

-G: 显示用户所属的组的ID 

​ -n: 显示名称,需配合ugG使用

可以用id来判断用户是否存在

切换用户或以其它用户身份执行命令

su [options…][-][user [args…]]

切换用户的方式:

​ su UserName:非登录式切换,即不会读取目标用户的配置文件,不改变 当前工作目录

​ su - UserName:登录式切换,会读取目标用户的配置文件,切换至家目 录,完全切换

​ root su至其他用户无须密码;非root用户切换时需要密码

换个身份执行命令:

​ su [-] UserName -c ‘COMMAND’

选项:-l –login

​ su -l UserName 相当于 su - UserName

设置密码

passwd [OPTIONS] UserName: 修改指定用户的密码

常用选项:

-d:删除指定用户密码 

-l:锁定指定用户 

-u:解锁指定用户 

-e:强制用户下次登录修改密码 

-f:强制操作 

-n mindays:指定最短使用期限 

-x maxdays:最大使用期限 

-w warndays:提前多少天开始警告 

​ -i inactivedays:非活动期限

​ –stdin:从标准输入接收用户密码

示例:

1
echo "PASSWORD" | passwd --stdin USERNAME >/dev/null

修改用户密码策略

chage [OPTION]… LOGIN

-d LAST_DAY 

-E --expiredate EXPIRE_DATE 

-I --inactive INACTIVE 

-m --mindays MIN_DAYS 

-M --maxdays MAX_DAYS 

-W --warndays WARN_DAYS 

–l 显示密码策略     

示例:

1
2
3
4
5
chage -d 0 USERNAME  	//下一次登录强制重设密码 

chage -m 0 –M 42 –W 14 –I 7 USERNAME

chage -E 2016-09-10 USERNAME

创建组

groupadd [OPTION]… group_name

​ -g GID: 指明GID号;[GID_MIN, GID_MAX]

​ -r: 创建系统组

​ CentOS 6: ID<500

​ CentOS 7: ID<1000

修改和删除组

组属性修改:groupmod

groupmod [OPTION]… group

​ -n group_name: 新名字

​ -g GID: 新的GID

组删除:groupdel

​ groupdel GROUP

更改组密码

组密码:gpasswd

gpasswd [OPTION] GROUP

​ -a user 将user添加至指定组中

​ -d user 从指定组中移除用户user

​ -A user1,user2,… 设置有管理权限的用户列表

newgrp命令:临时切换主组

如果用户本不属于此组,则需要组密码

更改和查看组成员

groupmems [options][action]

options:

​ -g, –group groupname 更改为指定组 (只有root)

Actions:

​ -a, –add username 指定用户加入组

​ -d, –delete username 从组中删除用户

​ -p, –purge 从组中清除所有成员

​ -l, –list 显示组成员列表

groups [USERNAME]… 查看用户所属组列表

标准输入和输出

程序:指令+数据

​ 读入数据: Input

​ 输出数据: Output

打开的文件都有一个fd: file descriptor (文件描述符)

Linux给程序提供三种I/O设备

​ 标准输入(STDIN) -0 默认接受来自键盘的输入

​ 标准输出(STDOUT) -1 默认输出到终端窗口

​ 标准错误(STDERR) -2 默认输出到终端窗口

I/O重定向:改变默认位置

把 I/O 重定向至文件


把输出和错误重新定向到文件

STDOUT和STDERR可以被重定向到文件

​ 命令 操作符号 文件名

支持的操作符号包括:

​ > 把STDOUT重定向到文件

​ 2> 把STDERR重定向到文件

​ &> 把所有输出重定向到文件

>文件内容会被覆盖

​ set –C 禁止将内容覆盖已有文件,但可追加

​ >| file 强制覆盖

​ set +C 允许覆盖

>>原有内容基础上,追加内容

​ 2> 覆盖重定向错误输出数据流

​ 2>> 追加重定向错误输出数据流

标准输出和错误输出各自定向至不同位置

​ COMMAND > /path/to/file.out 2> /path/to/error.out

合并标准输出和错误输出为同一个数据流进行重定向

​ &> 覆盖重定向

​ &>> 追加重定向

​ COMMAND > /path/to/file.out 2>&1 (顺序很重要)

​ COMMAND >> /path/to/file.out 2>&1

():合并多个程序的STDOUT

​ ( cal 2007 ; cal 2008 ) > all.txt

tr命令

tr 转换和删除字符 tr [OPTION]… SET1 [SET2]

选项:

​ -c –C –complement:取字符集的补集

​ -d –delete:删除所有属于第一字符集的字符

​ -s –squeeze-repeats:把连续重复的字符以单独一个字符表示

​ -t –truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符

​ [:alnum:]:字母和数字

​ [:alpha:]:字母

​ [:cntrl:]:控制(非打印)字符

​ [:digit:]: 数字

​ [:graph:]:图形字符

​ [:lower:]:小写字母

​ [:print:]:可打印字符

​ [:punct:]: 标点符号

​ [:space:]:空白字符

​ [:upper:]:大写字母

​ [:xdigit:]:十六进制字符

使用管道


从文件中导入STDIN

使用<来重定向标准输入

某些命令能够接受从文件中导入的STDIN

​ tr ‘a-z’ ‘A-Z’< /etc/issue

该命令会把/etc/issue中的小写字符都转换成写写字符

tr –d abc < /etc/fstab 删除fstab文件中的所有abc中任意字符

cat > file

​ google

​ mark

​ 按ctrl+d离开,可以使用文件来代替键盘的输入

cat > filea < fileb

把多行发送给STDIN

使用“<<终止词”命令从键盘把多行重导向给STDIN
直到 终止词 位置的所有文本都发送给STDIN
有时被称为就地文本(heretext)
mail -s “Please Call” admin@google.com << END

>Hi Mark,

>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

>END

管道

管道(使用符号“|”表示)用来连接命令

命令1 | 命令2 | 命令3 | …

将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的 STDIN

STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现

最后一个命令会在当前shell进程的子shell进程中执行用来组合多种工具的功能

ls | tr ‘a-z’ ‘A-Z

less :一页一页地查看输入

ls -l /etc | less

mail: 通过电子邮件发送输入

echo "test email" | mail -s "test" user@example.com

lpr:把输入发送给打印机

echo "test print" | lpr -P printer_name

管道中的 - 符号

示例:

将 /home 里面的文件打包,但打包的数据不是记录到文件,而是传送到 stdout, 经过管道后,将 tar -cvf - /home 传送给后面的 tar -xvf - , 后面的这个 - 则是取 前一个命令的 stdout, 因此,就不需要使用临时file了

tar -cvf - /home | tar -xvf -

重定向到多个目标(tee)

命令1 | tee [-a ] 文件名 | 命令2

​ 把命令1的STDOUT保存在文件中,做为命令2的输入

​ -a 追加

使用:

​ 保存不同阶段的输出

​ 复杂管道的故障排除

​ 同时查看和记录输出

文件属性操作

​ chown 设置文件的所有者

​ chgrp 设置文件的属组信息

修改文件的主属性和属组

修改文件的属主:chown

chown [OPTION]... \[OWNER][:[GROUP]] FILE... 

用法:

​ OWNER

​ OWNER:GROUP

​ :GROUP

​ 命令中的冒号可用.替换

​ -R: 递归

​ chown [OPTION]… –reference=RFILE FILE…

修改文件的属组:chgrp

​ chgrp [OPTION]… GROUP FILE…

​ chgrp [OPTION]… –reference=RFILE FILE…

​ -R 递归

文件权限

文件的权限主要针对三类对象进行定义

​ owner: 属主, u

​ group: 属组, g

​ other: 其他, o

每个文件针对每类访问者都定义了三种权限

​ r: Readable

​ w: Writable

​ x: eXcutable

文件:

​ r: 可使用文件查看类工具获取其内容

​ w: 可修改其内容

​ x: 可以把此文件提请内核启动为一个进程

目录:

​ r: 可以使用ls查看此目录中文件列表

​ w: 可在此目录中创建文件,也可删除此目录中的文件

​ x: 可以使用ls -l查看此目录中文件元数据(须配合r),可以cd进入此目录

​ X:只给目录x权限,不给文件x权限

文件权限操作

文件权限操作命令:chmod

文件权限(rwx|X)

八进制数字

— 000 0

–x 001 1

-w- 010 2

-wx 011 3

r– 100 4

r-x 101 5

rw- 110 6

rwx 111 7

例如:

640: rw-r----- 

755: rwxr-xr-x 

修改文件权限

chmod [OPTION]… OCTAL-MODE FILE…

​ -R: 递归修改权限

chmod [OPTION]… MODE[,MODE]… FILE…

MODE:

修改一类用户的所有权限:

​ u= g= o= ug= a= u=,g=

修改一类用户某位或某些位权限

​ u+ u- g+ g- o+ o- a+ a- + -

chmod [OPTION]… –reference=RFILE FILE…

​ 参考RFILE文件的权限,将FILE的修改为同RFILE

权限设置示例

chgrp sales testfile

chown root:admins testfile

chmod u+wx,g-r,o=rx file

chmod -R g+rwX /testdir

chmod 600 file

chown mark testfile

新建文件和目录的默认权限

umask值 可以用来保留在创建文件权限

新建FILE权限: 666-umask

​ 如果所得结果某位存在执行(奇数)权限,则将其权限+1

新建DIR权限: 777-umask

非特权用户umask是 002

root的umask 是 022

umask: 查看

umask #: 设定

​ umask 002

​ umask –S 模式方式显示

​ umask –p 输出可被调用

全局设置: /etc/bashrc 用户设置:~/.bashrc

Linux文件系统上的特殊权限

SUID, SGID, Sticky

三种常用权限:r, w, x user, group, other

安全上下文

前提:进程有属主和属组;文件有属主和属组

(1) 任何一个可执行程序文件能不能启动为进程,取决发起者对程序文件是否拥有 执行权限

(2) 启动为进程之后,其进程的属主为发起者,进程的属组为发起者所属的组

(3) 进程访问文件时的权限,取决于进程的发起者

​ (a) 进程的发起者,同文件的属主:则应用文件属主权限

​ (b) 进程的发起者,属于文件属组;则应用文件属组权限

​ (c) 应用文件“其它”权限

可执行文件上的SUID权限

任何一个可执行程序文件能不能启动为进程:取决发起者对程序文件是否拥有 执行权限

启动为进程之后,其进程的属主为原程序文件的属主

SUID只对二进制可执行程序有效

SUID设置在目录上无意义

权限设定:

​ chmod u+s FILE…

​ chmod u-s FILE…

​ SUID使用数字表示法可以用 4 来表示.

可执行文件上SGID权限

任何一个可执行程序文件能不能启动为进程,取决发起者对程序文件是否拥有 执行权限

启动为进程之后,其进程的属组为原程序文件的属组

权限设定:

​ chmod g+s FILE…

​ chmod g-s FILE…

目录上的SGID权限

默认情况下,用户创建文件时,其属组为此用户所属的主组

一旦某目录被设定了SGID,则对此目录有写权限的用户在此目录中创建的文件 所属的组为此目录的属组

通常用于创建一个协作目录

权限设定:

​ chmod g+s DIR…

​ chmod g-s DIR…

​ SGID使用数字表示法可以用 2 来表示.

Sticky位

具有写权限的目录通常用户可以删除该目录中的任何文件,无论该文件的权限 或拥有权

在目录设置Sticky 位,只有文件的所有者或root可以删除该文件

sticky 设置在文件上无意义

权限设定:

​ chmod o+t DIR…

​ chmod o-t DIR…

​ Sticky使用数字表示发可以用 1 来表示.

例如:

​ ls -ld /tmp drwxrwxrwt 12 root root 4096 Nov 2 15:44 /tmp

特殊权限数字法

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权限

特殊权限

suid (4) : 作用于二进制程序,功能: 当用户执行此程序的时,将继承此文件所有者的权限

sgid (2) : 作用于二进制程序,功能: 当用户执行此程序的时,将继承此文件所有组的权限

作用于目录上,功能:当用户在目录新建文件时,新文件的所属组自动继承此目录的所属组

sticky (1) : 作用于目录上,功能: 此目录中的文件,只能被所有者自己删除

设定文件特定属性

chattr +i 不能删除,改名,更改

chattr +a 只能追加内容

lsattr 显示特定属性

访问控制列表

ACL:Access Control List,实现灵活的权限管理

除了文件的所有者,所属组和其它人,可以对更多的用户设置权限

CentOS7 默认创建的xfs和ext4文件系统具有ACL功能

CentOS7 之前版本,默认手工创建的ext4文件系统无ACL功能,需手动增加

tune2fs –o acl /dev/sdb1 

mount –o acl /dev/sdb1 /mnt/test 

ACL生效顺序:所有者,自定义用户,自定义组,其他人

为多用户或者组的文件和目录赋予访问权限rwx

• mount -o acl /directory

• getfacl file |directory

• setfacl -m u:mark:rwx file|directory

• setfacl -Rm g:sales:rwX directory

• setfacl -M file.acl file|directory

• setfacl -m g:salesgroup:rw file| directory

• setfacl -m d:u:mark:rx directory

• setfacl -x u:mark file |directory

• setfacl -X file.acl directory

ACL文件上的group权限是mask 值(自定义用户,自定义组,拥有组的最大权 限),而非传统的组权限

getfacl 可看到特殊权限:flags

通过ACL赋予目录默认x权限,目录内文件也不会继承x权限

base ACL 不能删除

setfacl -k dir 删除默认ACL权限

setfacl –b file1清除所有ACL权限

getfacl file1 | setfacl –set-file=- file2 复制file1的acl权限给file2

mask只影响除所有者和other的之外的人和组的最大权限

Mask需要与用户的权限进行逻辑与运算后,才能变成有限的权限(Effective Permission)

用户或组的设置必须存在于mask权限设定范围内才会生效

setfacl -m mask::rx file 

–set选项会把原有的ACL项都删除,用新的替代,需要注意的是一定要包含 UGO的设置,不能象-m一样只是添加ACL就可以

示例:

setfacl --set u::rw,u:mark:rw,g::r,o::- file1 

备份和恢复ACL

主要的文件操作命令cp和mv都支持ACL,只是cp命令需要加上-p 参数。但是 tar等常见的备份工具是不会保留目录和文件的ACL信息

getfacl -R /tmp/dir1 > acl.txt 

setfacl -R -b /tmp/dir1 

setfacl -R --set-file=acl.txt  /tmp/dir1 

setfacl --restore acl.txt 

getfacl -R /tmp/dir1 

文件系统结构元素

文件和目录被组织成一个单根倒置树结构

文件系统从根目录下开始,用“/”表示

根文件系统(rootfs):root filesystem

文件名称区分大小写

以.开头的文件为隐藏文件

路径分隔的 / 文件有两类数据:

​ 元数据:metadata

​ 数据:data

文件系统分层结构:LSB Linux Standard Base

FHS: (Filesystem Hierarchy Standard) http://www.pathname.com/fhs/

文件名规则

文件名最长255个字节

包括路径在内文件名称最长4095个字节

蓝色–>目录 绿色–>可执行文件 红色–>压缩文件 浅蓝色–>链接文 件 灰色–>其他文件

除了斜杠和NUL,所有字符都有效.但使用特殊字符的目录名和文件不推荐使用, 有些字符需要用引号来引用它们。

标准Linux文件系统(如ext4),文件名称大小写敏感。例如: MAIL, Mail, mail, mAiL

文件系统结构

/boot:引导文件存放目录,内核文件(vmlinuz)、引导加载器(bootloader, grub)都存放于此目录 /bin:供所有用户使用的基本命令;不能关联至独立分区,OS启动即会用到的 程序

/sbin:管理类的基本命令;不能关联至独立分区,OS启动即会用到的程序

/lib:启动时程序依赖的基本共享库文件以及内核模块文件(/lib/modules)

/lib64:专用于x86_64系统上的辅助共享库文件存放位置

/etc:配置文件目录

/home/USERNAME:普通用户家目录

/root:管理员的家目录

/media:便携式移动设备挂载点

文件系统结构

/mnt:临时文件系统挂载点

/dev:设备文件及特殊文件存储位置

​ b: block device,随机访问

​ c: character device,线性访问

/opt:第三方应用程序的安装位置

/srv:系统上运行的服务用到的数据

/tmp:临时文件存储位置

文件系统结构

/usr: universal shared, read-only data

​ bin: 保证系统拥有完整功能而提供的应用程序

​ sbin: lib:32位使用

​ lib64:只存在64位系统

​ include: C程序的头文件(header files)

​ share:结构化独立的数据,例如doc, man等

​ local:第三方应用程序的安装位置

​ bin, sbin, lib, lib64, etc, share

/var: variable data files

​ cache: 应用程序缓存数据目录

​ lib: 应用程序状态信息数据

​ local:专用于为/usr/local下的应用程序存储可变数据;

​ lock: 锁文件

​ log: 日志目录及文件

​ opt: 专用于为/opt下的应用程序存储可变数据;

​ run: 运行中的进程相关数据,通常用于存储进程pid文件

​ spool: 应用程序数据池

​ tmp: 保存系统两次重启之间产生的临时数据

/proc: 用于输出内核与进程信息相关的虚拟文件系统

/sys:用于输出当前系统上硬件设备相关信息虚拟文件系统

/selinux: security enhanced Linux,selinux相关的安全策略等信息的存储位置

Linux上应用程序的组成部分

二进制程序:/bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin

库文件:/lib, /lib64, /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64

配置文件:/etc, /etc/DIRECTORY, /usr/local/etc

帮助文件:/usr/share/man, /usr/share/doc, /usr/local/share/man, /usr/local/share/doc

Linux下的文件类型

-:普通文件

d: 目录文件

b: 块设备

c: 字符设备

l: 符号链接文件

p: 管道文件pipe

s: 套接字文件socket

CentOS 7 目录变化

/bin 和 /usr/bin

/sbin 和 /usr/sbin

/lib 和/usr/lib

/lib64 和 /usr/lib64

显示当前工作目录

每个shell和系统进程都有一个当前的工作目录

CWD:current work directory

显示当前shell CWD的绝对路径

pwd: printing working directory

​ -P 显示真实物理路径

​ -L 显示链接路径(默认)

相对路径和绝对路径

​ 绝对路径

​ / 以正斜杠开始

​ 可以用于完整的文件的位置路径

​ 可用于任何想指定一个文件名的时候

相对路径名

​ 不以斜线开始

​ 指定相对于当前工作目录或某目录的位置

​ 可以作为一个简短的形式指定一个文件名

基名:basename

目录名:dirname

更改目录

cd 改变目录

使用绝对或相对路径:

​ cd /home/mark/

​ cd home/mark

切换至父目录: cd ..

切换至当前用户主目录: cd

切换至以前的工作目录: cd -

选项:-P

相关的环境变量:

​ PWD:当前目录路径

​ OLDPWD:上一次目录路径

列出目录内容

列出当前目录的内容或指定目录

用法:ls [options][files_or_dirs]

示例:

​ ls -a 包含隐藏文件

​ ls -l 显示额外的信息

​ ls -R 目录递归通过

​ ls -ld 目录和符号链接信息

​ ls -1 文件分行显示

​ ls –S 按从大到小排序

​ ls –t 按mtime排序

​ ls –u 配合-t选项,显示并按atime从新到旧排序

​ ls –U 按目录存放顺序显示

​ ls –X 按文件后缀排序

查看文件状态

stat

文件:metadata, data

三个时间戳:

​ access time:访问时间,atime,读取文件内容

​ modify time: 修改时间, mtime,改变文件内容(数据)

​ change time: 改变时间, ctime,元数据发生改变

文件通配符

*匹配零个或多个字符 *

? : 匹配任何单个字符

~ : 当前用户家目录

​ ~mark 用户mark家目录

~+ : 当前工作目录

~- : 前一个工作目录

[0-9] 匹配数字范围

[a-z]:字母

[A-Z]:字母

[mark] 匹配列表中的任何的一个字符

[^mark] 匹配列表中的所有字符以外的字符

预定义的字符类:man 7 glob

[:digit:]:任意数字,相当于0-9

[:lower:]:任意小写字母

[:upper:]: 任意大写字母

[:alpha:]: 任意大小写字母

[:alnum:]:任意数字或字母

[:blank:]:水平空白字符

[:space:]:水平或垂直空白字符

[:punct:]:标点符号

[:print:]:可打印字符

[:cntrl:]:控制(非打印)字符

[:graph:]:图形字符

[:xdigit:]:十六进制字符

创建空文件和刷新时间

touch命令:

​ touch [OPTION]… FILE…

​ -a 仅改变 atime和ctime

​ -m 仅改变 mtime和ctime

​ -t [[CC]YY]MMDDhhmm[.ss] 指定atime和mtime的时间戳

​ touch -t 200909010059.30 marktest.sh //#将文件时间属性改为9月1号0点59分30秒

​ -c 如果文件不存在,则不予创建

复制转移和删除文件

复制文件和目录 CP

cp [OPTION]… [-T] SOURCE DEST

cp [OPTION]… SOURCE… DIRECTORY

cp [OPTION]… -t DIRECTORY SOURCE…

cp SRC DEST

SRC是文件:

​ 如果目标不存在:新建DEST,并将SRC中内容填充至DEST中

​ 如果目标存在:

​ 如果DEST是文件:将SRC中的内容覆盖至DEST中

​ 基于安全,建议为cp命令使用-i选项

​ 如果DEST是目录:在DEST下新建与原文件同名的文件,并将SRC中内容填 充至新文件中

cp SRC... DEST 

SRC…:多个文件

​ DEST必须存在,且为目录,其它情形均会出错;

cp SRC DEST 

​ SRC是目录:此时使用选项:-r

​ 如果DEST不存在:则创建指定目录,复制SRC目录中所有文件至DEST中;

​ 如果DEST存在:

​ 如果DEST是文件:报错

​ 如果DEST是目录:

源\目标 不存在 存在且为文件 存在且为目录
一个文件 新建DEST,并将SRC中内容填充至DEST中 将SRC中的内容覆盖至DEST中,存在数据丢失的风险,要加 -i 在DEST下新建与原文件同名的文件,并将SRC中内容填充至新文件中
多个文件 提示错误 提示错误 在DEST下新建与源文件同名的文件,并将源文件内容复制进新文件中
目录要用 -r 选项 创建指定DEST同名目录,复制SRC目录中所有文件至DEST下 提示错误 在DEST下新建与原 目录同名的目录, 并将SRC中内容复 制至新目录中

cp 常用选项

-i:覆盖前提示 –n:不覆盖,注意两者顺序

-r, -R: 递归复制目录及内部的所有内容

-a: 归档,相当于-dR –preserv=all

-d:–no-dereference –preserv=links 不复制原文件,只复制链接名

–preserv[=ATTR_LIST]

​ mode: 权限

​ ownership: 属主属组

​ timestamp:

​ links

​ xattr

​ context

​ all

-p: 等同–preserv=mode,ownership,timestamp

-v: –verbose

-f: –force

-u:–update 只复制源比目标更新文件或目标不存在的文件

–backup=numbered 目标存在,覆盖前先备份加数字后缀

移动和重命名文件

mv [OPTION]… [-T] SOURCE DEST

mv [OPTION]… SOURCE… DIRECTORY

mv [OPTION]… -t DIRECTORY SOURCE…

​ 常用选项:

​ -i: 交互式

​ -f: 强制

删除

rm [OPTION]… FILE…

常用选项:

​ -i 交互式

​ -f 强制删除

​ -r 递归

​ –no-preserve-root 删除/

示例: rm -rf /

目录操作

tree 显示目录树

​ -d: 只显示目录

​ -L level:指定显示的层级数目

​ -P pattern: 只显示由指定pattern匹配到的路径

mkdir 创建目录

​ -p: 存在于不报错,且可自动创建所需的各目录

​ -v: 显示详细信息

​ -m MODE: 创建目录时直接指定权限

rmdir 删除空目录

​ -p: 递归删除父空目录

​ -v: 显示详细信息

rm -r 递归删除目录树

索引节点

​ inode(index node)表中包含文件系统所有文件列表

一个节点 (索引节点)是在一个表项,包含有关文件的信息( 元数据 ),包 括:

​ 文件类型,权限,UID,GID

​ 链接数(指向这个文件名路径名称个数)

​ 该文件的大小和不同的时间戳

​ 指向磁盘上文件的数据块指针

​ 有关文件的其他数据

详情查看inode表结构

cp和inode

在 CP的 命令:

​ 分配一个空闲的inode号,在inode表中生成新条目 在目录中创建一个目录项,将名称与inode编号关联 拷贝数据生成新的文件

rm和inode

rm 命令:

​ 链接数递减,从而释放的inode号可以被重用

​ 把数据块放在空闲列表中

​ 删除目录项

​ 数据实际上不会马上被删除,但当另一个文件使用数据块时将被覆盖。

mv和inode

​ 如果mv命令的目标和源在相同的文件系统,作为mv 命令

​ 用新的文件名创建对应新的目录项

​ 删除旧目录条目对应的旧的文件名

​ 不影响inode表(除时间戳)或磁盘上的数据位置:没有数据被移动!

如果目标和源在一个不同的文件系统, mv相当于cp和rm

硬链接

创建硬链接会增加额外的记录项以引用文件

对应于同一文件系统上一个物理文件

每个目录引用相同的inode号

创建时链接数递增

删除文件时,rm命令递减计数的链接

文件要存在,至少有一个链接数

当链接数为零时,该文件被删除

不能跨越驱动器或分区

语法: ln filename [linkname ]

符号(软)链接

一个符号链接指向另一个文件

ls - l的 显示链接的名称和引用的文件

一个符号链接的内容是它引用文件的名称

可以对目录进行

可以跨分区

指向的是另一个文件的路径;其大小为指向的路径字符串的长度;不增加或减 少目标文件inode的引用计数;

语法: ln -s filename [linkname]

确定文件内容

文件可以包含多种类型的数据

检查文件的类型,然后确定适当的打开命令或应用程序使用

file [options] …

常用选项:

​ -b 列出文件辨识结果时,不显示文件名称

​ -f filelist 列出文件filelist中文件名的文件类型

​ -F 使用指定分隔符号替换输出文件名后默认的”:”分隔符

​ -L 查看对应软链接对应文件的文件类型

​ –help 显示命令在线帮助