文件权限管理&正则表达式
文件权限管理
r读 4
w写 2
x执行 1
权限修改命令 chmod
u user 属主
g group 属组
o other 其他
a all 全部
1、可以使用=来直接指定文件权限
2、可以使用+、来修改文件权限
3、可以使用数字的方法修改权限
拥有着权限修改 chown,chgrp
Chown可以同时对属主、属组进行修改,可以替代chgrp
文件遮罩码 umask
目录777-umask
文件666-umask(若减得的结果致使文件有执行权限,则权限自动加1)
修改后仅在当前shell进程生效
[root@localhost tmp]# umask
0022
[root@localhost tmp]# mkdir test
[root@localhost tmp]# touch a
[root@localhost tmp]# ll
total 4
-rw-r--r-- 1 root root 0 Aug 31 18:07 a
drwxr-xr-x 2 root root 4096 Aug 31 18:07 test
[root@localhost tmp]# umask 0444
[root@localhost tmp]# mkdir testa
[root@localhost tmp]# touch b
[root@localhost tmp]# ll
total 8
-rw-r--r-- 1 root root 0 Aug 31 18:07 a
--w--w--w- 1 root root 0 Aug 31 18:10 b #重新设置了umask后,新建的文件或者目录默认权限发生变化,666-444=222,对应的就是w--w--w--
drwxr-xr-x 2 root root 4096 Aug 31 18:07 test
d-wx-wx-wx 2 root root 4096 Aug 31 18:10 testa #同理,目录的权限777-444=333,-wx-wx-wx
但是有一种情况:
[root@localhost tmp]# umask 0333
[root@localhost tmp]# touch c
[root@localhost tmp]# mkdir testb
[root@localhost tmp]# ll
total 12
-rw-r--r-- 1 root root 0 Aug 31 18:07 a
--w--w--w- 1 root root 0 Aug 31 18:10 b
-r--r--r-- 1 root root 0 Aug 31 18:13 c #按理说设置了333,666-333=333应该是-wx-wx-wx的呀,这是因为如果文件有x权限,则权限自动加1,变成444了
drwxr-xr-x 2 root root 4096 Aug 31 18:07 test
d-wx-wx-wx 2 root root 4096 Aug 31 18:10 testa
dr--r--r-- 2 root root 4096 Aug 31 18:13 testb 目录是有777-333=444,不受影响,正常计算
基本正则表达式
字符匹配:
. 任意单个字符
[] 中括号中,给出范围的单个字符
[^] 取反,中括号中范围之外的单个字符
[:upper:] 大写字母 A-Z
[:lower:] 小写字母 a-z
[:alpha:] 大、小写字母 a-zA-Z
[:digit:] 数字 0-9
[:alnum:] 数字和大、小写字母 0-9a-zA-Z
[:punct:] 各种标点符号 如'"!?$等
[:space:] 空白字符,包括tab
次数匹配
* 匹配前面字符任意长度
.* 贪婪匹配,匹配任意长度的任意字符
\? 前面字符可有可无,出现0次或者1次
\+ 前面字符出现1次或者多次(至少1次)
\{n\} 前面字符出现n次
\{n,m\} 前面字符出现n-m次,至少n次至多m次
\{n,\} 前面字符出现至少n次,多则不限
\{0,m\} 前面字符出现最多m次,少则不限
位置锚定
^ 锚定行首 ^pattern
$ 锚定行尾 pattern$
^$ 空白行 ^[[:space:]]*$ 空白行,含空白字符、tab
\< 锚定词首 \<pattern
\> 锚定词尾 pattern\>
\<pattern\> 锚定整个单词 \<[0-9]\{2\}\> 意思是:整个2位数字的单词(单词不是指自然语言中的单词,而是一连串的字符,不含其他符号)
分组&后向引用
\(\) 把括号中的字符串当作一个整体看待
后向引用,是引用前面括号中的字符,而不是模式
\1 引用从左面数第一个"\("和与之对应的"\)"之间模式所匹配到的值
\2 引用从左面数第二个"\("和与之对应的"\)"之间模式所匹配到的值
…… 以此类推
如:amb test anb 使用: \(a.b\).*\1 则不能匹配,虽然a.b包括amb和anb,但是前面括号中匹配到的值为amb,所以后面\1引用过来的是amb,而不是a.b这个模式
\ 脱意字符
把一些有特殊含义的符号前加上"\",则把它看作一个普通的字符处理,而失去它原本的特殊含义和作用
扩展正则表达式
字符匹配跟基本正则表达式一样:
. 任意单个字符
[] 中括号中,给出范围的单个字符
[^] 取反,中括号中范围之外的单个字符
[:upper:] 大写字母 A-Z
[:lower:] 小写字母 a-z
[:alpha:] 大、小写字母 a-zA-Z
[:digit:] 数字 0-9
[:alnum:] 数字和大、小写字母 0-9a-zA-Z
[:punct:] 各种标点符号 如'"!?$等
[:space:] 空白字符,包括tab
次数匹配,跟基本正则表达式略有不同,没有了“\”
* 匹配前面字符任意长度
.* 贪婪匹配,匹配任意长度的任意字符
? 前面字符可有可无,出现0次或者1次
+ 前面字符出现1次或者多次(至少1次)
{n} 前面字符出现n次
{n,m} 前面字符出现n-m次,至少n次至多m次
{n,} 前面字符出现至少n次
{0,m} 前面字符出现最多m次
位置锚定,跟基本正则表达式一样
^ 锚定行首 ^pattern
$ 锚定行尾 pattern$
^$ 空白行 ^[[:space:]]*$ 空白行,含空白字符、tab
\< 锚定词首 \<pattern
\> 锚定词尾 pattern\>
分组&后向引用,跟正则表达式略有不同,没有了"\"
() 把括号中的字符串当作一个整体看待
后向引用,是引用前面括号中的字符,而不是模式
\1 引用从左面数第一个“(”和与之对应的“)”之间模式所匹配到的值
\2 引用从左面数第二个“(”和与之对应的“)”之间模式所匹配到的值
…… 以此类推
\ 脱意字符,与基本正则表达式中相同
把一些有特殊含义的符号前加上“\”,则把它看作一个普通的字符处理,而失去它原本的特殊含义和作用
| 或者,基本正则表达式中没有的
A|B A或者B |整个左侧内容或者|右侧内容的意思
abc|Cba 是abc或者Cba的意思
ab(c|C)ba 是abcba或者abCba的意思
练习一
1、显示/etc/passwd文件中以bash结尾的行
grep 'bash$' /etc/passwd
2、显示/etc/passwd文件中的两位数或三位数;
grep '\<[[:digit:]]\{2,3\}\>' /etc/passwd
要点:如果不加上\<\>单词锚定的话,那么四位数(两个两位数)也会匹配到
3、显示'netstat -tan'命令结果中以‘LISTEN’后跟0个、1个或多个空白字符结尾的行;
netstat -tan | grep 'LISTEN[[:space:]]*$'
4、添加用户bash,testbash,basher以及nologin用户(nologin用户的shell为/sbin/nologin);而后找出/etc/passwd文件中用户名同shell名的行;
grep '^\(\<[[:alnum:]]*\>\).*\1$' /etc/passwd
这个有点复杂,拆开来看:
[[:alnum:]]* 这样就可以匹配到一串字符,姑且称为单词吧
\< \> 这样就能锚定这是一个单词
\( \) 这样把整个单词看为一个整体,为后面的引用做好准备(因为题目上说用户名部分和shell是同名的,)
.* 贪婪匹配,
\1$,引用前面\(\)中所匹配到的字符串并且锚定于尾部
[root@localhost tmp]# grep '^\(\<[[:alpha:]]*\>\).*\1$' /etc/passwd
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
nologin:x:778:778::/home/nologin:/sbin/nologin
bash:x:779:779::/home/bash:/bin/bash
练习二
1、显示当前系统上root、centos或user1用户的默认的shell和UID;
egrep '^(root|nologin|test)' /etc/passwd |cut -d: -f3,7
使用到了|(或),来找以root或nologin或test开头的行,然后打印出第3和第7段
2、找出/etc/rc.d/init.d/functions文件中某单词(单词中间可以存在下划线)后面跟着一组小括号的行;
egrep '\<[[:alnum:]]+_?[[:alnum:]]+\>\(\)' /etc/rc.d/
3、使用echo输出一个路径,而后egrep找出其路径基名;进一步地:使用egrep取出其目录名;
基名: echo /etc/rc.d/init.d/functions/ | egrep '[[:alnum:]]+/?$' -o |cut -d/ -f1
路径名:
[root@localhost tmp]# echo /etc/rc.d/init.d/functions | egrep '.*/' -o
/etc/rc.d/init.d/
这么做有个问题,如果这个路径的最后面有个"/" 那输出的结果就不对了
4、找出ifconfig命令执行结果中1-255之间的数字;
ifconfig | egrep '\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>'
思路:
1位数|两位数|三位数
一位数或者两位数,每位的取值都可以是0-9,但三位数不行,每位都取值0-9,那么最大可以匹配到999,所以三位数要拆分一下
100-199 1[0-9][0-9]
200-249 2[0-4][0-9]
250-255 25[0-5]