上面讲了很多系统的变量,那么在linux系统中,这些变量被存到了哪里呢,为什么用户一登陆shell就自动有了这些变量呢?
/etc/profile :这个文件预设了几个重要的变量,例如PATH, USER, LOGNAME, MAIL, INPUTRC, HOSTNAME, HISTSIZE, umas等等。
/etc/bashrc :这个文件主要预设umask以及PS1。这个PS1就是我们在敲命令时,前面那串字符了,例如笔者的linux系统PS1就是 [root@localhost ~]# ,你不妨看一下PS1的值。
\u就是用户,\h 主机名, \W 则是当前目录,\$就是那个’#’了,如果是普通用户则显示为’$’
除了两个系统级别的配置文件外,每个用户的主目录下还有几个这样的隐藏文件:
.bash_profile :定义了用户的个人化路径与环境变量的文件名称。每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次。
.bashrc :该文件包含专用于你的shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取。例如你可以将用户自定义的alias或者自定义变量写到这个文件中。
.bash_history :记录命令历史用的。
.bash_logout :当退出shell时,会执行该文件。可以把一些清理的工作放到这个文件中。
在上面的内容中讲到了磁盘的分区和格式化,那么格式化完了后,如何去用它呢?这就涉及到了挂载这块磁盘。格式化后的磁盘其实是一个块设备文件,类型为b,也许你会想,既然这个块文件就是那个分区,那么直接在那个文件中写数据不就写到了那个分区中么?当然不行。
在挂载某个分区前需要先建立一个挂载点,这个挂载点是以目录的形式出现的。一旦把某一个分区挂载到了这个挂载点(目录)下,那么再往这个目录写数据使,则都会写到该分区中。这就需要你注意一下,在挂载该分区前,挂载点(目录)下必须是个空目录。其实目录不为空并不影响所挂载分区的使用,但是一旦挂载上了,那么该目录下以前的东西就不能看到了。只有卸载掉该分区后才能看到。
mount 挂载设备
先建立/test1 /test2 目录,然后在/test1目录下建立一个1.txt文件。
把/dev/hdb1分区挂载到/test1目录,然后再查看/test1目录发下,1.txt不存在了。此时往/test1目录下写数据,则会写到/dev/hdb1分区中。在讲mount的-a选项时,我们有必要先了解一下这个文件 /etc/fstab
这个文件是系统启动时,需要挂载的各个分区。第一列就是分区的label;第二列是挂载点;第三列是分区的格式;第四列则是mount的一些挂载参数,等下会详细介绍一下有哪些参数,一般情况下,直接写defaults即可;第五列的数字表示是否被dump备份,是的话这里就是1,否则就是0;第六列是开机时是否自检磁盘,就是刚才讲过的那个fsck检测。1,2都表示检测,0表示不检测,在Redhat中,这个1,2还有个说法,/ 分区必须设为1,而且整个fstab中只允许出现一个1,这里有一个优先级的说法。1比2优先级高,所以先检测1,然后再检测2,如果有多个分区需要开机检测那么都设置成2吧,1检测完了后会同时去检测2。下面该说说第四列中常用到的参数了。
async/sync :async表示和磁盘和内存不同步,系统每隔一段时间把内存数据写入磁盘中,而sync则会时时同步内存和磁盘中数据;
auto/noauto :开机自动挂载/不自动挂载;
default:按照大多数永久文件系统的缺省值设置挂载定义,它包含了rw, suid, dev, exec, auto, nouser,async ;
ro:按只读权限挂载
;
rw:按可读可写权限挂载
;
exec/noexec :允许/不允许可执行文件执行,但千万不要把根分区挂载为noexec,那就无法使用系统了,连mount命令都无法使用了,这时只有重新做系统了;
user/nouser :允许/不允许root外的其他用户挂载分区,为了安全考虑,请用nouser ;
suid/nosuid :允许/不允许分区有suid属性,一般设置nosuid ;
usrquota :启动使用者磁盘配额模式,磁盘配额相关内容在后续章节会做介绍;
grquota :启动群组磁盘配额模式;
学完这个/etc/fstab后,我们就可以自己修改这个文件,增加一行来挂载新增分区。例如,笔者增加了这样一行
/dev/hdb1 /test1 ext3 defaults 0 0
那么系统再重启时就会挂载这个分区了。
讲完了/etc/fstab 我们继续回来讲这个mount,mout -a 如果运行了这个命令,则会把/etc/fstab中出现的所有磁盘分区挂载上。所以当你在/etc/fstab文件中增加一行后,你完全可以直接运行mount -a 来挂载你增加的那行,这样就不用重启啦。
你可以使用mount -o 选项来重新挂载一个分区,并同时指定你想要的选项(即上边介绍fstab第六列中那些)
看到了吧,使用了ro选项,则不能新建文件了。
再重新挂载一次就恢复正常了,如果不加任何其他选项,则就是defaults。
笔者在日常的运维工作中遇到过这样的情况,一台服务器上新装了亮块磁盘,磁盘a(在服务器上显示为sdc)和磁盘b(在服务器上显示为sdd),有一次把这两块磁盘都拔掉了,然后再重新插上,重启机器,结果磁盘编号调换了,a变成了sdd,b变成了sdc(这是因为把磁盘插错了插槽),问题来了。通过上边的学习,你挂载磁盘是通过/dev/hdb1 这样的分区名字来挂载的,如果先前加入到了/etc/fstab 中,结果系统启动后则会挂载错分区。那么怎么样避免这样的情况发生?
blkid
这个命令是用来显示磁盘分区uuid的,uuid其实就是一大串字符,在linux系统中每一个分区都会有唯一的一个uuid。说到这,聪明的你想到了吧,没有错,我们就用这唯一的uuid来挂载磁盘分区。
这个命令笔者只是用来显示uuid,没有其他用途所以不做详细介绍,当然你也可以在命令后边跟某一个分区,只显示该分区的uuid。
看到了吧,其实是很好用的。那么怎么让它也开机启动?很简单,把刚才敲的mount 磁盘的命令直接写到 /etc/rc.d/rc.local 文件即可。对了,笔者到现在还没有给你讲过这个rc.local文件的作用。简单点说,系统启动完后会执行这个文件中的命令。所以只要你想开机后运行什么命令统统写入到这个文件下面吧。
其实这个文件就是一个shell 脚本,以后笔者会单独用一章来介绍它。行开头的”#”是注释的意思,代表这行在这个脚本中不生效。你想让系统开机后运行什么命令,就把什么命令写到这里面来。就比如刚才笔者挂载的那条命令。你可以这样实现:
mount 还有一个比较常用的选项就是-t ,后边指定文件系统的类型,比如挂载软盘时就需要指定 vfat,而挂载光盘时就需要指定iso9660,但在笔者多年来的经验,目前的系统都是智能识别所要挂载分区的系统格式类别的。也就是说,用不着你去指定,它会自动判断的。
umount 卸载设备
现在你学会了如何挂载一个设备,那么如何去卸载一个设备呢,这就要用到umount了,这个命令也简单的很,后边可以跟挂载点,也可以跟分区名(/dev/hdb1)
有时也许你会遇到比较难卸载的设备,就像在windows下无法删除U盘一样,教你一个特管用的方法就是 umount -l /dev/hdb1 ,这个-l选项有强制卸载的意思,你一定要记住哦,非常有用的。
你在学习linux的过程中,也许你已经接触过某个特殊符号,例如”*”,它是一个通配符号,代表零个或多个字符或数字。下面笔者就说一说常用到的特殊字符。
1. *
:代表零个或多个字符或数字。
test后面可以没有任何字符,也可以有多个字符,总之有或没有都能匹配出来。
2. ?
:只代表一个任意的字符
不管是数字还是字母,只要是一个都能匹配出来。
3. #
:这个符号在linux中表示注释说明的意思,即”#”后面的内容linux忽略掉。
在命令的开头或者中间插入”#” ,linux都会忽略掉的。这个符号在shell脚本中用的很多。
4. \
:脱意字符,将后面的特殊符号(例如”*” )还原为普通字符。
5. |
:管道符,前面多次说过,它的作用在于将符号前面命令的结果丢给符号后面的命令。这里提到的后面的命令,并不是所有的命令都可以的,一般针对文档操作的命令比较常用,例如cat, less, head, tail, grep, cut, sort, wc, uniq, tee, tr, split, sed, awk等等,其中grep, sed, awk为正则表达式必须掌握的工具,在后续内容中详细介绍。
6. $ :除了用于变量前面的标识符外,还有一个妙用,就是和’!’结合起来使用。
‘!$’表示上条命中中最后一个变量(也许称为变量不合适,总之就是上条命令中最后出现的那个东西)例如上边命令最后是test.txt那么在当前命令下输入!$则代表test.txt。
1)grep
:过滤一个或多个字符,将会在后续内容中详细介绍其用法。
2) cut
:截取某一个字段
语法:cut -d “分隔字符” [-cf] n 这里的n是数字
-d :后面跟分隔字符,分隔字符要用双引号括起来
-c :后面接的是第几个字符
-f :后面接的是第几个区块
-d 后面跟分隔字符,这里使用冒号作为分割字符,-f 1 就是截取第一段,-f和1之间的空格可有可无。
-c 后面可以是1个数字n,也可以是一个区间n1-n2,还可以是多个数字n1,n2,n3
3) sort
:用做排序
语法:sort [-t 分隔符] [-kn1,n2] [-nru] 这里的n1 < n2
-t 分隔符
:作用跟cut的-d一个意思
-n :使用纯数字排序
-r :反向排序
-u :去重复
-kn1,n2 :由n1区间排序到n2区间,可以只写-kn1,即对n1字段排序
4) wc
:统计文档的行数、字符数、词数,常用的选项为:
-l :统计行数
-m :统计字符数
-w :统计词数
5) uniq
:去重复的行,笔者常用的选项只有一个:
-c :统计重复的行数,并把行数写在前面
有一点需要注意,在进行uniq之前,需要先用sort排序然后才能uniq,否则你将得不到你想要的,笔者上面的试验当中已经是排序过所以省略掉那步了。
6)tee :后跟文件名,类似与重定向”>”,但是比重定向多了一个功能,在把文件写入后面所跟的文件中的同时,还显示在屏幕上。
7)tr :替换字符,常用来处理文档中出现的特殊符号,如DOS文档中出现的^M符号。常用的选项有两个:
-d :删除某个字符,-d 后面跟要删除的字符
-s :把重复的字符去掉
最常用的就是把小写变大写: tr ‘[a-z]’ ‘[A-Z]’
当然替换一个字符也是完全可以的。
不过替换、删除以及去重复都是针对一个字符来讲的,有一定局限性。如果是针对一个字符串就不再管用了,所以笔者建议只是简单了解这个tr即可,以后你还会学到更多可以实现针对字符串操作的工具。
8)split :切割文档,常用选项:
-b :依据大小来分割文档,单位为byte
格式如上例,后面的passwd为分割后文件名的前缀,分割后的文件名为passwdaa, passwdab, passwdac …
-l :依据行数来分割文档
6. ;
:分号。平时我们都是在一行中敲一个命令,然后回车就运行了,那么想在一行中运行两个或两个以上的命令如何呢?则需要在命令之间加一个”;”了。
7. ~
:用户的家目录,如果是root则是 /root ,普通用户则是 /home/username
8. & :如果想把一条命令放到后台执行的话,则需要加上这个符号。通常用于命令运行时间非常长的情况。
使用jobs可以查看当前shell中后台执行的任务。用fg可以调到前台执行。这里的sleep命令就是休眠的意思,后面跟数字,单位为秒,常用语循环的shell脚本中。
此时你按一下CTRL +z 使之暂停,然后再输入bg可以再次进入后台执行。
如果是多任务情况下,想要把任务调到前台执行的话,fg后面跟任务号,任务号可以使用jobs命令得到。
9. >, >>, 2>, 2>>
:前面讲过重定向符号> 以及>> 分别表示取代和追加的意思,然后还有两个符号就是这里的2> 和 2>> 分别表示错误重定向和错误追加重定向,当我们运行一个命令报错时,报错信息会输出到当前的屏幕,如果想重定向到一个文本里,则要用2>或者2>>。
10. [ ]
:中括号,中间为字符组合,代表中间字符中的任意一个
11. && 与 ||
在上面刚刚提到了分号,用于多条命令间的分隔符。另外还有两个可以用于多条命令中间的特殊符号,那就是 “&&”和”||”。下面笔者把这几种情况全列出:
1) command1 ; command2
2) command1 && command2
3) command1 || command2
使用”;”时,不管command1是否执行成功都会执行command2;
使用”&&”时,只有command1执行成功后,command2才会执行,否则command2不执行;使用”||”时,command1执行成功后command2 不执行,否则去执行command2,总之command1和command2总有一条命令会执行。
在讲连接档之前,需要你先理解inode的概念。什么是inode呢?这就需要你知道磁盘的整体构造。磁盘是有多个盘片(类似与光盘)重叠在一起构成的,而每个盘片上会有一个可以移动的磁头,这个磁头的作用就是用来读写数据的。磁头并不是一直在动,当磁头固定时,盘片转一圈,这一圈就是一个磁道了。很多个盘片同半径的那一圈的磁道总和称为磁柱。而由圆心向外画出直线,可以得到一个个扇区,如图二所示,一个扇区的物理量大约是 512 bytes ( 约 0.5K )。
图一
图二
知道了大体的硬盘构造之后,再来谈一谈怎么硬盘分割( partition )呢?我们在进行硬盘分割的时候,最小都是以磁柱为单位进行分割的,那么分割完成之后自然就是格式化( format )啰,在 Linux 里面我们在进行格式化的时候必须要考虑到 Block 与 inode 的信息,这个 block 还好理解,他是我们磁盘可以记录的最小单位,是由数个 sector 所组成的,所以他的大小通常为 n*512 bytes ,例如 4K 。那么 inode 是什么? Block 是记录“档案内容数据”的地区,而 inode 则是记录“该档案的属性、及该档案放置在哪一个 Block 之内”的信息!所以,每个档案都会占用到至少一个 inode 。而当我们 Linux 系统要找到这个档案时,他会先去搜寻 inode table 找到这个档案的属性及数据放置的地区,然后再到数据去找到数据存放的 Block 进而将数据取出利用。这个 inode 数目在一开始就会被设定好,他的设定方式通常是利用 ( 硬盘大小 / 一个容量 ),这个容量至少应该比 Block 要大一些较佳,例如刚刚的 Block 订为 4K ,那么 inode 可以订为 8K 左右。所以,一颗 1GB 的硬盘,如果以 8K 来规划他的 inode 数时,他的 inode 就会有 131072 个 inode 啦!而一个 inode 的大小为 128 bytes 这么大!这么一来的话,我们就可以清楚的知道了,那就是一个 partition 格式化为一个 filesystem 之后,基本上,他一定会有 inode table 与 data area 两个区块,一个用来记录档案的信息与该档案放置的 block 区块,一个用来记录档案的内容!
由于我们 Linux 在读取数据的时候,是先查询 inode table 以得到数据是放在那个 Block 里面,然后再去该 Block 里面读取真正的数据内容!然后,那个 block 是我们在格式化硬盘的时候规定出来的一个值,这个 block 是由 2 的 n 次方个sector 所集结而成的!所以,他是 0.5K 的倍数!假设我们 block 规划为 4KBytes 好了,那么由于一个 inode 与一个block 最多均只纪录一个档案,所以,如果你的一个档案有 0.1 K bytes 这么大时,你要晓得的是,由于你的 block 为 4K bytes ,因此,你就会有 3.9 Kbytes 的空间浪费掉!所以,当你在格式化硬盘的时候,请千万注意到你的系统未来的使用方向。
笔者在前面的内容中多次提到并用到grep命令,可见它的重要性。所以好好学习一下这个重要的命令吧。你要知道的是grep连同下面讲的sed, awk都是针对文本的行才操作的。
语法: grep [-cinvABC] ‘word’ filename
-c :打印符合要求的行数
-i :忽略大小写
-n :在输出符合要求的行的同时连同行号一起输出
-v :打印不符合要求的行
-A :后跟一个数字(有无空格都可以),例如 –A2则表示打印符合要求的行以及下面两行
-B :后跟一个数字,例如 –B2 则表示打印符合要求的行以及上面两行
-C :后跟一个数字,例如 –C2 则表示打印符合要求的行以及上下各两行
以下,笔者举几个小例子帮助你好好掌握这个grep工具的用法。
a. 过滤出带有某个关键词的行并输出行号
b. 过滤不带有某个关键词的行,并输出行号
c. 过滤出所有包含数字的行
在前面也提到过这个”[ ]”的应用,如果是数字的话就用[0-9]这样的形式,当然有时候也可以用这样的形式[15]即只含有1或者5,注意,它不会认为是15。如果要过滤出数字以及大小写字母则要这样写[0-9a-zA-Z]。另外[ ]还有一种形式,就是[^字符] 表示除[ ]内的字符之外的字符。
这就表示筛选包含oo字符串,但是不包含r字符。
d. 过滤出文档中以某个字符开头或者以某个字符结尾的行
在正则表达式中,”^”表示行的开始,”$”表示行的结尾,那么空行则表示”^$”,如果你只想筛选出非空行,则可以使用 “grep -v ‘^$’ filename”得到你想要的结果。现在想一下,如何打印出不以英文字母开头的行呢?
e. 过滤任意一个字符与重复字符
“.”表示任意一个字符,上例中,就是把符合r与o之间有两个任意字符的行过滤出来。
“*”表示零个或多个前面的字符。
‘ooo*’ 表示oo, ooo, oooo … 或者更多的’o’。现在你是否想到了’.*’ 这个组合表示什么意义?
‘.*’表示零个或多个任意字符,空行也包含在内。
f. 指定要过滤字符出现的次数
这里用到了{ },其内部为数字,表示前面的字符要重复的次数。上例中表示包含有两个o 即’oo’的行。注意,{ }左右都需要加上脱意字符’\’。另外,使用{ }我们还可以表示一个范围的,具体格式是 ‘\{n1,n2\}’其中n1<n2,表示重复n1到n2次前面的字符,n2还可以为空,则表示大于等于n1次。
上面部分讲的grep,另外笔者常常用到egrep这个工具,简单点讲,后者是前者的扩展版本,我们可以用egrep完成grep不能完成的工作,当然了grep能完成的egrep完全可以完成。如果你嫌麻烦,egrep了解一下即可,因为grep的功能已经足够可以胜任你的日常工作了。下面笔者介绍egrep不用于grep的几个用法。为了试验方便,笔者把test.txt 编辑成如下内容:
rot:x:0:0:/rot:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
operator:x:11:0:operator:/rooot:/sbin/nologin
roooot:x:0:0:/rooooot:/bin/bash
1111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a. 筛选一个或一个以上前面的字符
和grep 不同的是,egrep这里是使用’+’的。
b. 筛选零个或一个前面的字符
c. 筛选字符串1或者字符串2
中间有一个’|’表示或者的意思,笔者用这个用的很多,所以这个你最好记一下。
d. egrep中’( )’的应用
用’( )’表示一个整体,例如(oo)+就表示1个’oo’或者多个’oo’
从装系统时就接触过这个swap了,前面也说过它类似与windows的虚拟内存,分区的时候一般大小为内存的2倍,如果你的内存超过4G,那么你分8G似乎是没有必要了。分4G足够日常交换了。然而,还会有虚拟内存不够用的情况发生。如果真遇到了,莫非还要重新分一下磁盘?当然不能!那我们就增加一个虚拟的磁盘出来。
基本的思路就是:1 建立swapfile; 2 格式化为swap格式; 3 启用该虚拟磁盘。
利用dd 来创建一个419M的文件/tmp/newdisk出来,其中if代表从哪个文件读,/dev/zero是linux下特有的一个0生成器,of表示输出到哪个文件,bs即块大小,count则定义有多少个块。
mkswap 这个命令是专门格式化swap格式的分区的,这个命令用的时候一定要看清楚了,否则把其他分区给格式化错了就只有哭了。
free 是用来查看系统内存以及虚拟内存使用情况的,-m选项是以M的形式查看。可以看到当前系统的。而swapon 是启用我们新建的swap文件,启用后再用free查看发现多了400M。
我们还可以用swapoff 关闭启用的swap文件。
前面多次提到过vim这个东西,它是linux中必不可少的一个工具。没有它很多工作都无法完成。早期的Unix都是使用的vi作为系统默认的编辑器的。你也许会有疑问,vi与vim有什么区别?可以这样简单理解,vim是vi的升级版。很多linux系统管理员都习惯用vi,那是因为他们接触linux的时候用的就是vi,vim后来才比较流行。所以,无所谓用vi和vim,只要你能达到你想要的目的即可。
在笔者看来vi 和vim最大的区别就是编辑一个文本时,vi不会显示颜色,而vim会显示颜色。显示颜色更易于用户进行编辑。其他功能没有什么区别。所以在linux系统下,使用vi还是vim完全取决你的个人爱好而已。笔者从一开始学linux就一直使用vim,所以也会一直以vim的角色来教授给你。
vim的三种模式:一般模式、编辑模式、命令模式。这需要你牢记的,因为以前笔者刚刚从事linux工作的时候去面试,很多单位的笔试题就有这个知识点。
* 一般模式:
当你vim filename 编辑一个文件时,一进入该文件就是一般模式了。在这个模式下,你可以做的操作有,上下移动光标;删除某个字符;删除某行;复制、粘贴一行或者多行。
* 编辑模式:一般模式下,是不可以修改某一个字符的,只能到编辑模式了。从一般模式进入编辑模式,只需你按一个键即可(i,I,a,A,o,O,r,R)。当进入编辑模式时,会在屏幕的最下一行出现“INSERT或REPLACE”的字样。从编辑模式回到一般模式只需要按一下键盘左上方的ESC键即可。
* 命令模式:在一般模式下,输入”:”或者”/”即可进入命令模式。在该模式下,你可以搜索某个字符或者字符串,也可以保存、替换、退出、显示行号等等。
下面笔者教你如何在一个空白文档中写入一段文字,然后保存。
输入vim test.txt直接回车进入一般模式。然后按"i" 字母进入编辑模式
会看到窗口的左下方出现”INSERT”字样,说明已经进入了编辑模式,此时就可以写入内容了。
等编辑完内容后,按ESC退出编辑模式,进入一般模式。此时在左下方的”INSERT”字样消失,然后按”:”进入命令模式,最后输入wq保存并退出vim。
这时,看一下test.txt文档的内容吧。
其实vim为全键盘操作的编辑器,所以在各个模式下都有很多功能键盘的。下面笔者列举一下,其中笔者认为常用的会用红色标出,需要你多加练习,另外不常用的你也要知道的。
前面提到过两次连接档的概念,现在终于该好好介绍下这部分内容了。连接档分为两种,硬连接(hard link)和软连接(symbolic link)。
Hard Links:
上面内容中说过,当系统要读取一个文件时,就会先去读inode table,然后再去根据inode中的信息到块区域去将数据取出来。而hard link 是直接再建立一个inode连接到文件放置的块区域。也就是说,进行hard link的时候实际上该文件内容没有任何变化,只是增加了一个指到这个文件的inode,不过这样一来就会有个问题,因为增加的inode会连接到块区域,而目录本身仅仅消耗inode而已,那么hard link就不能连接目录了。请你记住,hard link 有两个限制:1 不能跨文件系统,因为不通的文件系统有不同的inode table; 2 不能连接目录。
Symbolic Links:跟hard link不同,这个是建立一个独立的文件,而这个文件的作用是当读取这个连接文件时,它会把读取的行为转发到该文件所link的文件上。这样讲,也许比较绕口,那么就来举一个例子。现在有文件a,我们做了一个软连接文件b(只是一个连接文件,非常小),b指向了文件a。当读取b时,那么b就会把读取的动作转发到a上,这样就读取到了文件a。所以,当你删除文件a时,文件b并不会被删除,但是再读取b时,会提示无法打开文件。而,当你删除b时,a是不会有任何影响的。
看样子,似乎 hard link 比较安全,因为即使某一个 inode 被杀掉了,只要有任何一个 inode 存在,那么该文件就不会不见!不过,不幸的是,由于 Hard Link 的限制太多了,包括无法做目录的 link ,所以在用途上面是比较受限的!反而是 Symbolic Link 的使用方向较广!那么如何建立软连接和硬连接呢?这就用到了ln 命令。
ln 语法: ln [-s] [来源文件] [目的文件]
ln 常用的选项就一个-s ,如果不加就是建立硬连接,加上就建立软连接。
在建立硬连接前后,123目录所占空间大小并没有改变。
当把源文件删除后,空间仍旧没有变化。说明了删除一个文件其实只是删除了inode信息。
不能创建目录的硬连接。
建立软连接后,456目录增加了4k
删除源文件后会提示“没有这个文件”的错误。
目录是可以软连接的。
删除软连接对源文件没有任何影响。
grep 工具的功能其实还不够强大,其实说白了,grep实现的只是查找功能,而它却不能实现把查找的内容替换掉。以前用vim的时候,可以查找也可以替换,但是只局限于在文本内部来操作,而不能输出到屏幕上。sed工具以及下面要讲的awk工具就能实现把替换的文本输出到屏幕上的功能了,而且还有其他更丰富的功能。sed和awk都是流式编辑器,是针对文档的行来操作的。
a. 打印某行 sed -n ‘n’p filename 单引号内的n是一个数字,表示第几行
b. 打印多行
打印整个文档用 -n ‘1,$’p
c. 打印包含某个字符串的行
上面grep中使用的特殊字符,如’^’, ‘$’, ‘.’, ‘*’等同样也能在sed中使用。
d. -e 可以实现多个行为
e. 删除某行或者多行
‘d’ 这个字符就是删除的动作了,不仅可以删除指定的单行以及多行,而且还可以删除匹配某个字符的行,另外还可以删除从某一行一直到文档末行。
f. 替换字符或字符串
上例中的’s’就是替换的命令,’g’为本行中全局替换,如果不加’g’,只换该行中出现的第一个。
除了可以使用’/’外,还可以使用其他特殊字符例如’#’或者[email=’@’]’@’[/email]都没有问题。
现在思考一下,如何删除文档中的所有数字或者字母?
有意思吧,[0-9]表示任意的数字。这里你也可以写成[a-zA-Z]甚至[0-9a-zA-Z]
g. 调换两个字符串的位置
这个就需要解释一下了,上例中用’()’把所想要替换的字符括起来成为一个整体,因为括号在sed中属于特殊符号,所以需要在前面加脱意字符’\’,替换时则写成’\1’, ‘\2’, ‘\3’ 的形式。除了调换两个字符串的位置外,笔者还常常用到在某一行前或者后增加指定内容。
h. 直接修改文件的内容
sed -i ‘s/:/#/g’ test.txt ,这样就可以直接更改test.txt文件中的内容了。由于这个命令可以直接把文件修改,所以在修改前最好先复制一下文件以免改错。
sed常用到的也就上面这些了,只要你多加练习就能熟悉它了。为了能让你更加牢固的掌握sed的应用,笔者留几个练习题给你,希望你能认真完成。
1. 把/etc/passwd 复制到/root/test.txt,用sed打印所有行;
2. 打印test.txt的3到10行;
3. 打印test.txt 中包含’root’的行;
4. 删除test.txt 的15行以及以后所有行;
5. 删除test.txt中包含’bash’的行;
6. 替换test.txt 中’root’为’toor’;
7. 替换test.txt中’/sbin/nologin’为’/bin/login’
8. 删除test.txt中5到10行中所有的数字;
9. 删除test.txt 中所有特殊字符(除了数字以及大小写字母);
10. 把test.txt中第一个单词和最后一个单词调换位置;
11. 把test.txt中出现的第一个数字和最后一个单词替换位置;
12. 把test.txt 中第一个数字移动到行末尾;
13. 在test.txt 20行到末行最前面加’aaa:’;
现在给出以上练习题的答案,你如果实在想不出如何操作,那你看看答案吧,请尽量多想一下。
1. /bin/cp /etc/passwd /root/test.txt ; sed -n '1,$'p test.txt
2. sed -n '3,10'p test.txt
3. sed -n '/root/'p test.txt
4. sed '15,$'d test.txt
5. sed '/bash/'d test.txt
6. sed 's/root/toor/g' test.txt
7. sed 's#sbin/nologin#bin/login#g' test.txt
8. sed '5,10s/[0-9]//g' test.txt
9. sed 's/[^0-9a-zA-Z]//g' test.txt
10. sed 's/\(^[a-zA-Z][a-zA-Z]*\)\([^a-zA-Z].*\)\([^a-zA-Z]\)\([a-zA-Z][a-zA-Z]*$\)/\4\2\3\1/' test.txt
11. sed 's#\([^0-9][^0-9]*\)\([0-9][0-9]*\)\([^0-9].*\)\([^a-zA-Z]\)\([a-zA-Z][a-zA-Z]*$\)#\1\5\3\4\2#' test.txt
12. sed 's#\([^0-9][^0-9]*\)\([0-9][0-9]*\)\([^0-9].*$\)#\1\3\2#' test.txt
13. sed '20,$s/^.*$/aaa:&/' test.txt
在windows下我们接触最多的压缩文件就是.rar格式的了。但在linux下这样的格式是不能识别的,它有自己所特有的压缩工具。但有一种文件在windows和linux下都能使用那就是.zip格式的文件了。压缩的好处不用笔者介绍相信你也晓得吧,它不仅能节省磁盘空间而且在传输的时候还能节省网络带宽呢。
在linux下最常见的压缩文件通常都是以.tar.gz 为结尾的,除此之外还有.tar, .gz, .bz2, .zip等等。以前也介绍过linux系统中的后缀名其实要不要无所谓,但是对于压缩文件来讲必须要带上。这是为了判断压缩文件是由哪种压缩工具所压缩,而后才能去正确的解压缩这个文件。以下介绍常见的后缀名所对应的压缩工具。
.gz gzip 压缩工具压缩的文件
.bz2 bzip2 压缩工具压缩的文件
.tar tar 打包程序打包的文件(tar并没有压缩功能,只是把一个目录合并成一个文件)
.tar.gz 可以理解为先用tar打包,然后再gzip压缩
.tar.bz2 同上,先用tar打包,然后再bzip2压缩
这两个文件可以说是linux系统中最重要的文件之一。如果没有这两个文件或者这两个文件出问题,则你是无法正常登录linux系统的。
/etc/passwd由’:’分割成7个字段,每个字段的具体含义是:
1)用户名(如第一行中的root就是用户名),代表用户账号的字符串。用户名字符可以是大小写字母、数字、减号(不能出现在首位)、点以及下划线,其他字符不合法。虽然用户名中可以出现点,但不建议使用,尤其是首位为点时,另外减号也不建议使用,因为容易造成混淆。
2)存放的就是该账号的口令,为什么是’x’呢?早期的unix系统口令确实是存放在这里,但基于安全因素,后来就将其存放到/etc/shadow中了,在这里只用一个’x’代替。
3)这个数字代表用户标识号,也叫做uid。系统识别用户身份就是通过这个数字来的,0就是root,也就是说你可以修改test用户的uid为0,那么系统会认为root和test为同一个账户。通常uid的取值范围是0~65535,0是超级用户(root)的标识号,1~499由系统保留,作为管理账号,普通用户的标识号从500开始,如果我们自定义建立一个普通用户,你会看到该账户的标识号是大于或等于500的。
4)表示组标识号,也叫做gid。这个字段对应着/etc/group 中的一条记录,其实/etc/group和/etc/passwd基本上类似。
5)注释说明,该字段没有实际意义,通常记录该用户的一些属性,例如姓名、电话、地址等等。不过,当你使用finger的功能时就会显示这些信息的(稍后做介绍)。
6)用户的家目录,当用户登录时就处在这个目录下。root的家目录是/root,普通用户的家目录则为/home/username,这个字段是可以自定义的,比如你建立一个普通用户test1,要想让test1的家目录在/data目录下,只要修改/etc/passwd文件中test1那行中的该字段为/data即可。
7)shell,用户登录后要启动一个进程,用来将用户下达的指令传给内核,这就是shell。Linux的shell有很多种sh, csh, ksh, tcsh, bash等,而Redhat/CentOS的shell就是bash。查看/etc/passwd文件,该字段中除了/bin/bash外还有/sbin/nologin比较多,它表示不允许该账号登录。如果你想建立一个账号不让他登录,那么就可以把该字段改成/sbin/nologin,默认是/bin/bash。
再来看看/etc/shadow这个文件,和/etc/passwd类似,用”:”分割成9个字段。
1)用户名,跟/etc/passwd对应。
2)用户密码,这个才是该账号的真正的密码,不过这个密码已经加密过了,但是有些黑客还是能够解密的。所以为了安全,该文件属性设置为600,只允许root读写。
3)上次更改密码的日期,这个数字是这样计算得来的,距离1970年1月1日到上次更改密码的日期,例如上次更改密码的日期为2012年1月1日,则这个值就是365*(2012-1970)+1=15331。
4)要过多少天才可以更改密码,默认是0,即不限制。
5)密码多少天后到期。即在多少天内必须更改密码,例如这里设置成30,则30天内必须更改一次密码,否则将不能登录系统,默认是99999,可以理解为永远不需要改。
6)密码到期前的警告期限,若这个值设置成7,则表示当7天后密码过期时,系统就发出警告告诉用户,提醒用户他的密码将在7天后到期。
7)账号失效期限。你可以这样理解,如果设置这个值为3,则表示:密码已经到期,然而用户并没有在到期前修改密码,那么再过3天,则这个账号就失效了,即锁定了。
8)账号的生命周期,跟第三段一样,是按距离1970年1月1日多少天算的。它表示的含义是,账号在这个日期前可以使用,到期后账号作废。
9)作为保留用的,没有什么意义。
上面也提到了awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行。awk比sed更加强大,它能做到sed能做到的,同样也能做到sed不能做到的。awk工具其实是很复杂的,有专门的书籍来介绍它的应用,但是笔者认为学那么复杂没有必要,只要能处理日常管理工作中的问题即可。何必让自己的脑袋装那么东西来为难自己?毕竟用的也不多,即使现在教会了你很多,你也学会了,如果很久不用肯定就忘记了。鉴于此,笔者仅介绍比较常见的awk应用,如果你感兴趣的话,再去深入研究吧。
a. 截取文档中的某个段
解释一下,-F 选项的作用是指定分隔符,如果不加-F指定,则以空格或者tab为分隔符。
Print为打印的动作,用来打印出某个字段。$1为第一个字段,$2为第二个字段,依次类推,有一个特殊的那就是$0,它表示整行。
注意awk的格式,-F后紧跟单引号,然后里面为分隔符,print的动作要用’{ }’括起来,否则会报错。print还可以打印自定义的内容,但是自定义的内容要用双引号括起来。
b. 匹配字符或字符串
跟sed很类似吧,不过还有比sed更强大的匹配。
可以让某个段去匹配,这里的’~’就是匹配的意思,继续往下看
awk还可以多次匹配,如上例中匹配完root,再匹配test,它还可以只打印所匹配的段。
不过这样没有啥意义,笔者只是为了说明awk确实比sed强大。
d. 条件操作符
awk中是可以用逻辑符号判断的,比如’==’就是等于,也可以理解为“精确匹配”。另外也有’>’, ‘>=’, ‘<’, ‘<=’, ‘!=’ 等等,值得注意的是,即使$3为数字,awk也不会把它当数字看待,它会认为是一个字符。所以不要妄图去拿$3当数字去和数字做比较。
这样是得不到我们想要的效果的。这里只是字符与字符之间的比较,’6’是>’500’的。
上例中用的是’!=’ 即不匹配。
另外还可以使用”&&” 和 “||”表示“并且”和“或者”的意思。
也可以是或者的关系
d. awk的内置变量
常用的变量有:
NF :用分隔符分隔后一共有多少段;
NR :行数
上例中,打印总共的段数以及最后一段的值。
可以使用NR作为条件,来打印出指定的行。
e. awk中的数学运算
awk比较强的地方,还在于能把某个段改成指定的字符串,下面还有更强的呢!
当然还可以计算某个段的总和。
这里的END要注意一下,表示所有的行都已经执行,这是awk特有的语法,其实awk连同sed都可以写成一个脚本文件,而且有他们特有的语法,在awk中使用if判断、for循环都是可以的,只是笔者认为日常管理工作中没有必要使用那么复杂的语句而已。
注意这里’( )’的使用。
基本上,正则表达的内容就这些了。但是笔者要提醒你一下,笔者介绍的这些仅仅是最基本的东西,并没有提啊深入的去讲sed和awk,但是完全可以满足日常工作的需要,有时候也许你会碰到比较复杂的需求,如果真遇到了就去请教一下google吧。下面出几道关于awk的练习题,希望你要认真完成。
1. 用awk 打印整个test.txt (以下操作都是用awk工具实现,针对test.txt);
2. 查找所有包含’bash’的行;
3. 用’:’作为分隔符,查找第三段等于0的行;
4. 用’:’作为分隔符,查找第一段为’root’的行,并把该段的’root’换成’toor’(可以连同sed一起使用);
5. 用’:’作为分隔符,打印最后一段;
6. 打印行数大于20的所有行;
7. 用’:’作为分隔符,打印所有第三段小于第四段的行;
8. 用’:’作为分隔符,打印第一段以及最后一段,并且中间用’@’连接
(例如,第一行应该是这样的形式 “root@/bin/bash”;
9. 用’:’作为分隔符,把整个文档的第四段相加,求和;
下面给出答案:
1. awk '{print $0}' test.txt
2. awk '/bash/' test.txt
3. awk -F':' '$3=="0"' test.txt
4. awk -F':' '$1=="root"' test.txt |sed 's/root/toor/'
5. awk -F':' '{print $NF}' test.txt
6. awk -F':' 'NR>20' test.txt
7. awk -F':' '$3<$4' test.txt
8. awk -F':' '{print $1"@"$NF}' test.txt
9. awk -F':' '{(sum+=$4)}; END {print sum}' test.txt
a. 新增一个组 groupadd [-g GID] groupname
不加-g 则按照系统默认的gid创建组,跟用户一样,gid也是从500开始的
-g选项可以自定义gid
b. 删除组 gropudel groupname
没有特殊选项。
c. 增加用户 useradd [-u UID] [-g GID] [-d HOME] [-M] [-s]
-u 自定义UID
-g 使其属于已经存在的某个GID
-d 自定义用户的家目录
-M 不建立家目录
-s 自定义shell
你会发现,创建test11时,加上了-M选项后,在/etc/passwd文件中test11那行的第六字段依然有/home/test11,可是ls查看该目录时,会提示该目录不存在。
-M选项的作用就是不创建用户的家目录。
-d. 删除用户 userdel [-r] username
-r 选项的作用是删除用户时,连同用户的家目录一起删除。
RPM是”Redhat Package Manager”的缩写,根据名字也能猜到这是Redhat公司开发出来的。RPM 是以一种数据库记录的方式来将你所需要的套件安装到你的Linux 主机的一套管理程序。也就是说,你的linux系统中存在着一个关于RPM的数据库,它记录了安装的包以及包与包之间依赖相关性。RPM包是预先在linux机器上编译好并打包好的文件,安装起来非常快捷。但是也有一些缺点,比如安装的环境必须与编译时的环境一致或者相当;包与包之间存在着相互依赖的情况;卸载包时需要先把依赖的包卸载掉,如果依赖的包是系统所必须的,那就不能卸载这个包,否则会造成系统崩溃。
如果你的光驱中还有系统安装盘的话,你可以通过”mount /dev/cdrom /mnt”命令把光驱挂载到/mnt目录下,那么你会在/mnt/CentOS目录下看到很多.rpm的文件,这就是RPM包了。
每一个rpm包的名称都由”-“和”.”分成了若干部分。就拿 a2ps-4.13b-57.2.el5.i386.rpm 这个包来解释一下,a2ps 为包名;4.13b则为版本信息;57.2.el5为发布版本号;i386为运行平台。其中运行平台常见的有i386, i586, i686, x86_64 ,需要你注意的是cpu目前是分32位和64位的,i386,i586和i686都为32位平台,x86_64则代表为64位的平台。另外有些rpm包并没有写具体的平台而是noarch,这代表这个rpm包没有硬件平台限制。例如 alacarte-0.10.0-1.fc6.noarch.rpm 。下面介绍一下rpm常用的命令。
1)安装一个rpm包
-i :安装的意思
-v :可视化
-h :显示安装进度
另外在安装一个rpm包时常用的附带参数有:
--force 强制安装,即使覆盖属于其他包的文件也要安装
--nodeps 当要安装的rpm包依赖其他包时,即使其他包没有安装,也要安装这个包
2)升级一个rpm包
rpm -Uvh filename -U :即升级的意思
3)卸载一个rpm包
rpm -e filename 这里的filename是通过rpm的查询功能所查询到的,稍后会作介绍。
卸载时后边跟的filename和安装时的是有区别的。上面命令提到的 “|”在linux系统中用的非常多也非常有用,它是一个管道符,用来把前面运行的结果传递给后面的命令。以后会做详细介绍,而后出现的grep命令则是用来过滤某个关键词的工具,在后续章节中会做详细介绍。
4)查询一个包是否安装
rpm -q rpm包名(这里的包名,是不带有平台信息以及后缀名的)
如果加上了平台信息以及后缀名反而不能查出来。你还可以查询当前系统中所安装的所有rpm包。
因为太多,所以笔者列出前十个。
5)得到一个rpm包的相关信息
rpm -qi 包名
(同样不需要加平台信息与后缀名)
6)列出一个rpm包安装的文件
rpm -ql 包名
通过上面的命令可以看出vim是通过安装vim-enhanced-7.0.109-6.el5这个rpm包得来的。那么反过来如何通过一个文件去查找是由安装哪个rpm包得来的?
7)列出某一个文件属于哪个rpm包
rpm -qf 文件的绝对路径
前面讲过如何查找一个文件(可执行命令)的绝对路径
所以你也可以把这两条命令连起来写
看到了吗,which vim 这条命令是由两个反引号引起来的,这代表引用反引号里面的命令所产生的结果。关于rpm工具的使用还有很多内容,笔者就不一一列举了,只要你掌握上面这些内容,完全够你平时工作用的了。
终于到shell 脚本这章了,在以前笔者卖了好多关子说shell脚本怎么怎么重要,确实shell脚本在linux系统管理员的运维工作中非常非常重要。下面笔者就带你正式进入shell脚本的世界吧。
到现在为止,你明白什么是shell脚本吗?如果明白最好了,不明白也没有关系,相信随着学习的深入你就会越来越了解到底什么是shell脚本。首先它是一个脚本,并不能作为正式的编程语言。因为是跑在linux的shell中,所以叫shell脚本。说白了,shell脚本就是一些命令的集合。举个例子,我想实现这样的操作:1)进入到/tmp/目录;2)列出当前目录中所有的文件名;3)把所有当前的文件拷贝到/root/目录下;4)删除当前目录下所有的文件。简单的4步在shell窗口中需要你敲4次命令,按4次回车。这样是不是很麻烦?当然这4步操作非常简单,如果是更加复杂的命令设置需要几十次操作呢?那样的话一次一次敲键盘会很麻烦。所以不妨把所有的操作都记录到一个文档中,然后去调用文档中的命令,这样一步操作就可以完成。其实这个文档呢就是shell脚本了,只是这个shell脚本有它特殊的格式。
Shell脚本能帮助我们很方便的去管理服务器,因为我们可以指定一个任务计划定时去执行某一个shell脚本实现我们想要需求。这对于linux系统管理员来说是一件非常值得自豪的事情。现在的139邮箱很好用,发邮件的同时还可以发一条邮件通知的短信给用户,利用这点,我们就可以在我们的linux服务器上部署监控的shell脚本,比如网卡流量有异常了或者服务器web服务器停止了就可以发一封邮件给管理员,同时发送给管理员一个报警短信这样可以让我们及时的知道服务器出问题了。
有一个问题需要约定一下,凡是自定义的脚本建议放到/usr/local/sbin/目录下,这样做的目的是,一来可以更好的管理文档;二来以后接管你的管理员都知道自定义脚本放在哪里,方便维护。
- «
- 1
- ...
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- ...
- 63
- »