【鸟哥的 Linux 私房菜 - 基础】学习笔记

因为之后更多会涉及后台开发的部分,所以系统学习一下 Linux 还是很有必要的,这里就用《鸟哥的 Linux 私房菜》作为主要的学习材料。不过因为我本身已经有一定基础了,所以这里主要会记录个人觉得比较生疏和重要的地方。


对于计算机的基本了解,可以参考我之前写的『深入理解计算机系统』系列日志。接下来主要是比较零散的知识点,具体可以参见目录。

常用技巧

  • 遇到不懂的命令,一定先用 man 命令来了解一下,可以看到详细的介绍
    • /string 向下搜索 string 这个字符串
    • ?string 向上搜索这个字符串
    • 搜索的时候输入 n, N 可以跳到下一个/上一个结果 ,q 可以退出
  • 遇到不懂的命令,可以使用 info 命令来查看
    • n(下一个),p(前一个),u(上一层),h(帮助),q(退出)
  • nano 是非常简单的编辑器,只需要 nano filename 即可,具体的操作会在终端中显示
    • ^ 表示 ctrl 按键
  • 改变文件属性与权限的命令
    • chgrp:改变文件所属群组
    • chown:改变文件拥有者
    • chmod:改变文件权限
  • 目录相关操作
    • .:代表此层目录
    • ..:代表上一层目录
    • -:代表前一个工作目录
    • ~:代表“目前使用者身份”所在的主文件夹
    • ~account:代表 account 这个使用者的主文件夹(account是个帐号名称)
    • 在所有目录下面都会存在的两个目录,分别是“.”与“..” 分别代表此层与上层目录的意思
    • cd:变化目录
    • pwd:显示目前目录
    • mkdir:创建新目录
    • rmdir:删除一个空的目录
  • 可执行文件路径变量 $PATH
    • 当我们在执行一个指令的时候,举例来说“ls”好了,系统会依照PATH的设置去每个PATH定义的目录下搜寻文件名为ls的可执行文件, 如果在PATH定义的目录中含有多个文件名为ls的可可执行文件,那么先搜寻到的同名指令先被执行!
    • echo $PATH 来查看当前的值

命令: ls, cp, rm, mv

ls 用来查看文件与目录,选项与参数为:

  • -a:全部的文件,连同隐藏文件( 开头为 . 的文件) 一起列出来(常用)
  • -A:全部的文件,连同隐藏文件,但不包括 . 与 .. 这两个目录
  • -d:仅列出目录本身,而不是列出目录内的文件数据(常用)
  • -f:直接列出结果,而不进行排序 (ls 默认会以文件名排序!)
  • -F:根据文件、目录等信息,给予附加数据结构,例如:*: 代表可可执行文件; /: 代表目录; =: 代表 socket 文件; |: 代表 FIFO 文件;
  • -h:将文件大小以人类较易读的方式(例如 GB, KB 等等)列出来;
  • -i:列出 inode 号码,inode 的意义下一章将会介绍;
  • -l:长数据串行出,包含文件的属性与权限等等数据;(常用)
  • -n:列出 UID 与 GID 而非使用者与群组的名称 (UID与GID会在帐号管理提到!)
  • -r:将排序结果反向输出,例如:原本文件名由小到大,反向则为由大到小;
  • -R:连同子目录内容一起列出来,等于该目录下的所有文件都会显示出来;
  • -S:以文件大小大小排序,而不是用文件名排序;
  • -t:依时间排序,而不是用文件名。
  • --color=never:不要依据文件特性给予颜色显示;
  • --color=always:显示颜色
  • --color=auto:让系统自行依据设置来判断是否给予颜色
  • --full-time:以完整时间模式 (包含年、月、日、时、分) 输出
  • --time={atime,ctime}:输出 access 时间或改变权限属性时间 (ctime) 而非内容变更时间 (modification time)

cp 用来复制文件或者创建链接,选项与参数为:

  • -a:相当于 -dr –preserve=all 的意思,至于 dr 请参考下列说明;(常用)
  • -d:若来源文件为链接文件的属性(link file),则复制链接文件属性而非文件本身;
  • -f:为强制(force)的意思,若目标文件已经存在且无法打开,则移除后再尝试一次;
  • -i:若目标文件(destination)已经存在时,在覆盖时会先询问动作的进行(常用)
  • -l:进行硬式链接(hard link)的链接文件创建,而非复制文件本身;
  • -p:连同文件的属性(权限、用户、时间)一起复制过去,而非使用默认属性(备份常用);
  • -r:递回持续复制,用于目录的复制行为;(常用)
  • -s:复制成为符号链接文件 (symbolic link),亦即“捷径”文件;
  • -u:destination 比 source 旧才更新 destination,或 destination 不存在的情况下才复制。
  • --preserve=all:除了 -p 的权限相关参数外,还加入 SELinux 的属性, links, xattr 等也复制了。最后需要注意的,如果来源文件有两个以上,则最后一个目的文件一定要是“目录”才行!

mv 用来移动文件或者重命名,选项与参数为:

  • -f:force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
  • -i:若目标文件 (destination) 已经存在时,就会询问是否覆盖!
  • -u:若目标文件已经存在,且 source 比较新,才会更新 (update)

rm 用来删除文件,选项与参数为:

  • -f:就是 force 的意思,忽略不存在的文件,不会出现警告讯息;
  • -i:互动模式,在删除前会询问使用者是否动作
  • -r:递回删除啊!最常用在目录的删除了!这是非常危险的选项!!!

命令: cat, tac, nl, more, less

cat 由第一行开始显示文件内容

  • -A:相当于 -vET 的整合选项,可列出一些特殊字符而不是空白而已;
  • -b:列出行号,仅针对非空白行做行号显示,空白行不标行号!
  • -E:将结尾的断行字符 $ 显示出来;
  • -n:打印出行号,连同空白行也会有行号,与 -b 的选项不同;
  • -T:将 [tab] 按键以 ^I 显示出来;
  • -v:列出一些看不出来的特殊字符

tac 从最后一行开始显示,可以看出 tac 是 cat 的倒着写!

具体的参数和 cat 是一致的,这里不赘述

nl 显示的时候,顺道输出行号!

  • -b:指定行号指定的方式,主要有两种:
    • -b a:表示不论是否为空行,也同样列出行号(类似 cat -n);
    • -b t:如果有空行,空的那一行不要列出行号(默认值);
  • -n:列出行号表示的方法,主要有三种:
    • -n ln:行号在屏幕的最左方显示;
    • -n rn:行号在自己字段的最右方显示,且不加 0 ;
    • -n rz:行号在自己字段的最右方显示,且加 0 ;
  • -w:行号字段的占用的字符数。

more 一页一页的显示文件内容,支持的按键有

  • 空格:代表向下翻一页;
  • Enter:代表向下翻“一行”;
  • /字串:代表在这个显示的内容当中,向下搜寻“字串”这个关键字;
  • :f:立刻显示出文件名以及目前显示的行数;
  • q:代表立刻离开 more ,不再显示该文件内容。
  • b 或 [ctrl]-b:代表往回翻页,不过这动作只对文件有用,对管线无用。

less 与 more 类似,但是比 more 更好的是,他可以往前翻页!支持的按键有

  • 空格:向下翻动一页;
  • [pagedown]:向下翻动一页;
  • [pageup]:向上翻动一页;
  • /字串:向下搜寻“字串”的功能;
  • ?字串:向上搜寻“字串”的功能;
  • n:重复前一个搜寻 (与 / 或 ? 有关!)
  • N:反向的重复前一个搜寻 (与 / 或 ? 有关!)
  • g:前进到这个数据的第一行去;
  • G:前进到这个数据的最后一行去 (注意大小写);
  • q:离开 less 这个程序;

你是否会觉得 less 使用的画面与环境与 man page 非常的类似呢?没错啦!因为man这个指令就是调用 less 来显示说明文档的内容的!

命令: head, tail, od, touch

head 只看头几行

  • -n:后面接数字,代表显示几行的意思
  • 另外那个 -n 选项后面的参数较有趣,如果接的是负数,例如上面范例的 -n -100时,代表列前的所有行数, 但不包括后面100行

tail 只看尾巴几行

  • -n:后面接数字,代表显示几行的意思
  • -f:表示持续侦测后面所接的文件名,要等到按下[ctrl]-c才会结束tail的侦测

od 以二进制的方式读取文件内容!

  • -t:后面可以接各种“类型 (TYPE)”的输出,例如:
    • a:利用默认的字符来输出;
    • c:使用 ASCII 字符来输出
    • d[size]:利用十进制(decimal)来输出数据,每个整数占用 size Bytes ;
    • f[size]:利用浮点数值(floating)来输出数据,每个数占用 size Bytes ;
    • o[size]:利用八进位(octal)来输出数据,每个整数占用 size Bytes ;
    • x[size]:利用十六进制(hexadecimal)来输出数据,每个整数占用 size Bytes ;

touch 修改文件时间或创建新文件

我们在 ls 这个指令的介绍时,有稍微提到每个文件在linux下面都会记录许多的时间参数, 其实是有三个主要的变动时间,那么三个时间的意义是什么呢?

  • modification time (mtime):
    • 当该文件的“内容数据”变更时,就会更新这个时间!内容数据指的是文件的内容,而不是文件的属性或权限喔!
  • status time (ctime):
    • 当该文件的“状态 (status)”改变时,就会更新这个时间,举例来说,像是权限与属性被更改了,都会更新这个时间啊。
  • access time (atime):
    • 当“该文件的内容被取用”时,就会更新这个读取时间 (access)。举例来说,我们使用 cat 去读取 /etc/man_db.conf , 就会更新该文件的 atime 了。

选项与参数

  • -a:仅修订 access time;
  • -c:仅修改文件的时间,若该文件不存在则不创建新文件;
  • -d:后面可以接欲修订的日期而不用目前的日期,也可以使用 –date=”日期或时间”
  • -m:仅修改 mtime ;
  • -t:后面可以接欲修订的时间而不用目前的时间,格式为[YYYYMMDDhhmm]

命令: file, which, whereis, locate/updatedb, find

file 观察文件类型

如果你想要知道某个文件的基本数据,例如是属于 ASCII 或者是 data 文件,或者是 binary , 且其中有没有使用到动态函数库 (share library) 等等的信息,就可以利用 file 这个指令来检阅喔!

which 指令文件名的搜寻

which [-a] command 选项或参数:

  • -a:将所有由 PATH 目录中可以找到的指令均列出,而不止第一个被找到的指令名称

whereis 由一些特定的目录中寻找文件文件名

whereis [-bmsu] 文件或目录名 选项或参数:

  • -l:可以列出 whereis 会去查询的几个主要目录而已
  • -b:只找 binary 格式的文件
  • -m:只找在说明文档 manual 路径下的文件
  • -s:只找 source 来源文件
  • -u:搜寻不在上述三个项目当中的其他特殊文件

locate 搜索包含指定词的文件

locate [-ir] keyword 选项与参数:

  • -i:忽略大小写的差异;
  • -c:不输出文件名,仅计算找到的文件数量
  • -l:仅输出几行的意思,例如输出五行则是 -l 5
  • -S:输出 locate 所使用的数据库文件的相关信息,包括该数据库纪录的文件/目录数量等
  • -r:后面可接正则表达式的显示方式

locate 寻找的数据是由“已创建的数据库 /var/lib/mlocate/” 里面的数据所搜寻到的,所以不用直接在去硬盘当中存取数据。那么有什么限制呢?就是因为他是经由数据库来搜寻的,而数据库的创建默认是在每天执行一次

那能否手动更新数据库哪?当然可以啊!更新 locate 数据库的方法非常简单,直接输入“ updatedb ”就可以了! updatedb 指令会去读取 /etc/updatedb.conf 这个配置文件的设置,然后再去硬盘里面进行搜寻文件名的动作, 最后就更新整个数据库文件啰!因为 updatedb 会去搜寻硬盘,所以当你执行 updatedb 时,可能会等待数分钟的时间喔!

find 查找具体文件

find [PATH] [option] [action] 选项与参数:

  • 与时间有关的选项:共有 -atime, -ctime 与 -mtime ,以 -mtime 说明
    • -mtime n:n 为数字,意义为在 n 天之前的“一天之内”被更动过内容的文件;
    • -mtime +n:列出在 n 天之前(不含 n 天本身)被更动过内容的文件文件名;
    • -mtime -n:列出在 n 天之内(含 n 天本身)被更动过内容的文件文件名。
    • -newer file:file 为一个存在的文件,列出比 file 还要新的文件文件名
  • 与使用者或群组名称有关的参数
    • -uid n:n 为数字,这个数字是使用者的帐号 ID,亦即 UID ,这个 UID 是记录在 /etc/passwd 里面与帐号名称对应的数字。
    • -gid n:n 为数字,这个数字是群组名称的 ID,亦即 GID,这个 GID 记录在/etc/group
    • -user name:name 为使用者帐号名称喔!例如 dmtsai
    • -group name:name 为群组名称喔,例如 users ;
    • -nouser:寻找文件的拥有者不存在 /etc/passwd 的人!
    • -nogroup:寻找文件的拥有群组不存在于 /etc/group 的文件!
    • 当你自行安装软件时,很可能该软件的属性当中并没有文件拥有者,这是可能的!在这个时候,就可以使用 -nouser 与 -nogroup 搜寻。
  • 与文件权限及名称有关的参数:
    • -name filename:搜寻文件名称为 filename 的文件;
    • -size [+-]SIZE:搜寻比 SIZE 还要大(+)或小(-)的文件。这个 SIZE 的规格有:
      • c: 代表 Byte
      • k: 代表 1024Bytes
      • 所以,要找比 50KB 还要大的文件,就是 -size +50k
    • -type TYPE:搜寻文件的类型为 TYPE 的,类型主要有:一般正规文件 (f), 设备文件 (b, c),目录 (d), 链接文件 (l), socket (s), 及 FIFO (p) 等属性。
    • -perm mode:搜寻文件权限“刚好等于” mode 的文件,这个 mode 为类似 chmod 的属性值,举例来说, -rwsr-xr-x 的属性为 4755 !
    • -perm -mode:搜寻文件权限“必须要全部囊括 mode 的权限”的文件,举例来说,我们要搜寻 -rwxr--r-- ,亦即 0744 的文件,使用 -perm -0744,当一个文件的权限为 -rwsr-xr-x ,亦即 4755 时,也会被列出来,因为 -rwsr-xr-x 的属性已经囊括了 -rwxr--r-- 的属性了。
    • -perm /mode:搜寻文件权限“包含任一 mode 的权限”的文件,举例来说,我们搜寻 -rwxr-xr-x ,亦即 -perm /755 时,但一个文件属性为 -rw------- 也会被列出来,因为他有 -rw.... 的属性存在!

命令: gzip, zcat/zmore/zless/zgrep

gzip 可以说是应用度最广的压缩指令了!目前 gzip 可以解开 compress, zip 与 gzip 等软件所压缩的文件。 至于 gzip 所创建的压缩文件为 *.gz 的文件名喔!

gzip [-cdtv#] 文件名
zcat 文件名.gz

选项与参数:

  • -c:将压缩的数据输出到屏幕上,可通过数据流重导向来处理;
  • -d:解压缩的参数;
  • -t:可以用来检验一个压缩文件的一致性~看看文件有无错误;
  • -v:可以显示出原文件/压缩文件的压缩比等信息;
  • -#:# 为数字的意思,代表压缩等级,-1 最快,但是压缩比最差、-9 最慢,但是压缩比最好!默认是 -6

当你使用 gzip 进行压缩时,在默认的状态下原本的文件会被压缩成为 .gz 的文件名,原始文件就不再存在了。

cat/more/less 可以使用不同的方式来读取纯文本文件,那个 zcat/zmore/zless 则可以对应于 cat/more/less 的方式来读取纯文本文件被压缩后的压缩文件! 由于 gzip 这个压缩指令主要想要用来取代 compress 的,所以不但 compress 的压缩文件可以使用 gzip 来解开,同时 zcat 这个指令可以同时读取 compress 与 gzip 的压缩文件呦!

命令: bzip2, bzcat/bzmore/bzless/bzgrep

若说 gzip 是为了取代 compress 并提供更好的压缩比而成立的,那么 bzip2 则是为了取代 gzip 并提供更佳的压缩比而来的。 bzip2 真是很不错用的东西~这玩意的压缩比竟然比 gzip 还要好~至于 bzip2 的用法几乎与 gzip 相同!

bzip2 [-cdkzv#] 文件名
bzcat 文件名.bz2

选项与参数:

  • -c:将压缩的过程产生的数据输出到屏幕上!
  • -d:解压缩的参数
  • -k:保留原始文件,而不会删除原始的文件喔!
  • -z:压缩的参数 (默认值,可以不加)
  • -v:可以显示出原文件/压缩文件的压缩比等信息;
  • -#:与 gzip 同样的,都是在计算压缩比的参数, -9 最佳, -1 最快!

命令: tar

tar 可以将多个目录或文件打包成一个大文件,同时还可以通过 gzip/bzip2/xz 的支持,将该文件同时进行压缩! 更有趣的是,由于 tar 的使用太广泛了,目前 Windows 的 WinRAR 也支持 .tar.gz 文件名的解压缩呢!

tar 的选项与参数非常的多!我们只讲几个常用的选项,更多选项您可以自行 man tar 查询啰!

tar [-z|-j|-J] [cv] [-f 待创建的新文件名] filename... <==打包与压缩
tar [-z|-j|-J] [tv] [-f 既有的 tar文件名] <==察看文件名
tar [-z|-j|-J] [xv] [-f 既有的 tar文件名] [-C 目录] <==解压缩

选项与参数:

  • -c:创建打包文件,可搭配 -v 来察看过程中被打包的文件名(filename)
  • -t:察看打包文件的内容含有哪些文件名,重点在察看“文件名”就是了;
  • -x:解打包或解压缩的功能,可以搭配 -C (大写) 在特定目录解开特别留意的是, -c, -t, -x 不可同时出现在一串指令列中。
  • -z:通过 gzip 的支持进行压缩/解压缩:此时文件名最好为 *.tar.gz
  • -j:通过 bzip2 的支持进行压缩/解压缩:此时文件名最好为 *.tar.bz2
  • -J:通过 xz 的支持进行压缩/解压缩:此时文件名最好为 *.tar.xz 特别留意, -z, -j, -J 不可以同时出现在一串指令列中
  • -v:在压缩/解压缩的过程中,将正在处理的文件名显示出来!
  • -f filename:-f 后面要立刻接要被处理的文件名!建议 -f 单独写一个选项啰!(比较不会忘记)
  • -C 目录:这个选项用在解压缩,若要在特定目录解压缩,可以使用这个选项。
  • -p:保留备份数据的原本权限与属性,常用于备份(-c)重要的配置文件
  • -P:保留绝对路径,亦即允许备份数据中含有根目录存在之意;
  • --exclude=FILE:在压缩的过程中,不要将 FILE 打包!

tar 并不会主动的产生创建的文件名喔!我们要自订啦! 所以扩展名就显的很重要了!如果不加 [-z|-j|-J] 的话,文件名最好取为 *.tar 即可。如果是 -j选项,代表有 bzip2 的支持,因此文件名最好就取为 *.tar.bz2 ,因为 bzip2 会产生 .bz2 的扩展名之故! 至于如果是加上了 -z 的 gzip 的支持,那文件名最好取为 *.tar.gz 喔!

另外值得一提的是,tar 打包出来的文件有没有进行压缩所得到文件称呼不同喔! 如果仅是打包而已,就是 tar -cv -f file.tar而已,这个文件我们称呼为 tarfile 。 如果还有进行压缩的支持,例如 tar -jcv -f file.tar.bz2 时,我们就称呼为 tarball (tar 球?)!这只是一个基本的称谓而已,不过很多书籍与网络都会使用到这个 tarball 的名称!所以得要跟您介绍介绍。

命令: cut, grep

cut

cut 不就是“切”吗?没错啦!这个指令可以将一段讯息的某一段给他“切”出来~ 处理的讯息是以“行”为单位喔!

cut -d'分隔字符' -f fields <==用于有特定分隔字符
cut -c 字符区间 <==用于排列整齐的讯息

选项与参数:

  • -d:后面接分隔字符。与 -f 一起使用;
  • -f:依据 -d 的分隔字符将一段讯息分区成为数段,用 -f 取出第几段的意思;
  • -c:以字符 (characters) 的单位取出固定字符区间;
# 范例一:将 PATH 变量取出,我要找出第五个路径。
echo ${PATH} | cut -d ':' -f 5
echo ${PATH} | cut -d ':' -f 3,5 # 找第 3 与第 5
# 范例二:将 export 输出的讯息,取得第 12 字符以后的所有字串
export | cut -c 12-
# 知道怎么回事了吧?用 -c 可以处理比较具有格式的输出数据!
# 我们还可以指定某个范围的值,例如第 12-20 的字符,就是 cut -c 12-20 等等!
# 范例三:用 last 将显示的登陆者的信息中,仅留下使用者大名
last | cut -d ' ' -f 1
# 由输出的结果我们可以发现第一个空白分隔的字段代表帐号,所以使用如上指令:
# 但是因为 root pts/1 之间空格有好几个,并非仅有一个,所以,如果要找出
# pts/1 其实不能以 cut -d ' ' -f 1,2 喔!输出的结果会不是我们想要的。

grep

刚刚的 cut 是将一行讯息当中,取出某部分我们想要的,而 grep 则是分析一行讯息, 若当中有我们所需要的信息,就将该行拿出来~简单的语法是这样的:

grep [-acinv] [--color=auto] '搜寻字串' filename

选项与参数:

  • -a:将 binary 文件以 text 文件的方式搜寻数据
  • -c:计算找到 ‘搜寻字串’ 的次数
  • -i:忽略大小写的不同,所以大小写视为相同
  • -n:顺便输出行号
  • -v:反向选择,亦即显示出没有 ‘搜寻字串’ 内容的那一行!
  • --color=auto:可以将找到的关键字部分加上颜色的显示喔!
# 范例一:将 last 当中,有出现 root 的那一行就取出来;
last | grep 'root'
# 范例二:与范例一相反,只要没有 root 的就取出!
last | grep -v 'root'
# 范例三:在 last 的输出讯息中,只要有 root 就取出,并且仅取第一栏
last | grep 'root' | cut -d ' ' -f1
# 在取出 root 之后,利用上个指令 cut 的处理,就能够仅取得第一栏啰!
# 范例四:取出 /etc/man_db.conf 内含 MANPATH 的那几行
grep --color=auto 'MANPATH' /etc/man_db.conf
....(前面省略)....
MANPATH_MAP /usr/games /usr/share/man
MANPATH_MAP /opt/bin /opt/man
MANPATH_MAP /opt/sbin /opt/man
# 神奇的是,如果加上 --color=auto 的选项,找到的关键字部分会用特殊颜色显示喔!

命令: sort, wc, uniq

sort

sort 是很有趣的指令,他可以帮我们进行排序,而且可以依据不同的数据型态来排序喔! 例如数字与文字的排序就不一样。此外,排序的字符与语系的编码有关,因此, 如果您需要排序时,建议使用 LANG=C 来让语系统一,数据排序比较好一些。

sort [-fbMnrtuk] [file or stdin]

选项与参数:

  • -f:忽略大小写的差异,例如 A 与 a 视为编码相同;
  • -b:忽略最前面的空白字符部分;
  • -M:以月份的名字来排序,例如 JAN, DEC 等等的排序方法;
  • -n:使用“纯数字”进行排序(默认是以文字体态来排序的);
  • -r:反向排序;
  • -u:就是 uniq ,相同的数据中,仅出现一行代表;
  • -t:分隔符号,默认是用 [tab] 键来分隔;
  • -k:以那个区间 (field) 来进行排序的意思
# 范例一:个人帐号都记录在 /etc/passwd 下,请将帐号进行排序。
cat /etc/passwd | sort
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
alex:x:1001:1002::/home/alex:/bin/bash
# 鸟哥省略很多的输出~由上面的数据看起来, sort 是默认“以第一个”数据来排序,
# 而且默认是以“文字”型态来排序的喔!所以由 a 开始排到最后啰!
# 范例二:/etc/passwd 内容是以 : 来分隔的,我想以第三栏来排序,该如何?
cat /etc/passwd | sort -t ':' -k 3
root:x:0:0:root:/root:/bin/bash
dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash
alex:x:1001:1002::/home/alex:/bin/bash
arod:x:1002:1003::/home/arod:/bin/bash
# 看到特殊字体的输出部分了吧?怎么会这样排列啊?呵呵!没错啦~
# 如果是以文字体态来排序的话,原本就会是这样,想要使用数字排序:
# cat /etc/passwd | sort -t ':' -k 3 -n
# 这样才行啊!用那个 -n 来告知 sort 以数字来排序啊!
# 范例三:利用 last ,将输出的数据仅取帐号,并加以排序
last | cut -d ' ' -f1 | sort

wc

如果我想要知道 /etc/man_db.conf 这个文件里面有多少字?多少行?多少字符的话, 可以怎么做呢?其实可以利用 wc 这个指令来达成喔!他可以帮我们计算输出的讯息的整体数据!

wc [-lwm]

选项与参数:

  • -l:仅列出行;
  • -w:仅列出多少字(英文单字);
  • -m :多少字符;
# 范例一:那个 /etc/man_db.conf 里面到底有多少相关字、行、字符数?
cat /etc/man_db.conf | wc
131 723 5171
# 输出的三个数字中,分别代表: “行、字数、字符数”
# 范例二:我知道使用 last 可以输出登陆者,但是 last 最后两行并非帐号内容,那么请问,我该如何以一行指令串取得登陆系统的总人次?
last | grep [a-zA-Z] | grep -v 'wtmp' | grep -v 'reboot' | \
> grep -v 'unknown' |wc -l
# 由于 last 会输出空白行, wtmp, unknown, reboot 等无关帐号登陆的信息,因此,我利用
# grep 取出非空白行,以及去除上述关键字那几行,再计算行数,就能够了解啰

uniq

如果我排序完成了,想要将重复的数据仅列出一个显示,可以怎么做呢?

uniq [-ic]

选项与参数:

  • -i:忽略大小写字符的不同;
  • -c:进行计数
# 范例一:使用 last 将帐号列出,仅取出帐号栏,进行排序后仅取出一位;
last | cut -d ' ' -f1 | sort | uniq
# 范例二:承上题,如果我还想要知道每个人的登陆总次数呢?
last | cut -d ' ' -f1 | sort | uniq -c
1
6 (unknown
47 dmtsai
4 reboot
7 root
1 wtmp
# 从上面的结果可以发现 reboot 有 4 次, root 登陆则有 7 次!大部分是以 dmtsai 来操作!
# wtmp 与第一行的空白都是 last 的默认字符,那两个可以忽略的!

命令: tee, split, xargs

tee

tee 的工作流程示意图

tee 会同时将数据流分送到文件去与屏幕 (screen);而输出到屏幕的,其实就是 stdout ,那就可以让下个指令继续处理喔!

tee [-a] file

选项与参数:

  • -a:以累加 (append) 的方式,将数据加入 file 当中!
last | tee last.list | cut -d " " -f1
# 这个范例可以让我们将 last 的输出存一份到 last.list 文件中;
ls -l /home | tee ~/homefile | more
# 这个范例则是将 ls 的数据存一份到 ~/homefile ,同时屏幕也有输出讯息!
ls -l / | tee -a ~/homefile | more
# 要注意! tee 后接的文件会被覆盖,若加上 -a 这个选项则能将讯息累加。

tee 可以让 standard output 转存一份到文件内并将同样的数据继续送到屏幕去处理! 这样除了可以让我们同时分析一份数据并记录下来之外,还可以作为处理一份数据的中间暂存盘记录之用!

split 将一个大文件,依据文件大小或行数来分区

split [-bl] file PREFIX

选项与参数:

  • -b:后面可接欲分区成的文件大小,可加单位,例如 b, k, m 等;
  • -l:以行数来进行分区。
  • PREFIX:代表前置字符的意思,可作为分区文件的前导文字。
# 范例一:我的 /etc/services 有六百多K,若想要分成 300K 一个文件时?
cd /tmp; split -b 300k /etc/services services
ll -k services*
-rw-rw-r--. 1 dmtsai dmtsai 307200 Jul 9 22:52 servicesaa
-rw-rw-r--. 1 dmtsai dmtsai 307200 Jul 9 22:52 servicesab
-rw-rw-r--. 1 dmtsai dmtsai 55893 Jul 9 22:52 servicesac
# 那个文件名可以随意取的啦!我们只要写上前导文字,小文件就会以
# xxxaa, xxxab, xxxac 等方式来创建小文件的!
# 范例二:如何将上面的三个小文件合成一个文件,文件名为 servicesback
cat services* >> servicesback
# 很简单吧?就用数据流重导向就好啦!简单!
# 范例三:使用 ls -al / 输出的信息中,每十行记录成一个文件
ls -al / | split -l 10 - lsroot
wc -l lsroot*
10 lsrootaa
10 lsrootab
4 lsrootac
24 total
# 重点在那个 - 啦!一般来说,如果需要 stdout/stdin 时,但偏偏又没有文件,
# 有的只是 - 时,那么那个 - 就会被当成 stdin 或 stdout ~

xargs 参数代换

xargs 是在做什么的呢?就以字面上的意义来看, x 是加减乘除的乘号,args 则是 arguments (参数) 的意思,所以说,这个玩意儿就是在产生某个指令的参数的意思! xargs 可以读入 stdin 的数据,并且以空白字符或断行字符作为分辨,将 stdin 的数据分隔成为 arguments 。 因为是以空白字符作为分隔,所以,如果有一些文件名或者是其他意义的名词内含有空白字符的时候, xargs 可能就会误判了

xargs [-0epn] command

选项与参数:

  • -0:如果输入的 stdin 含有特殊字符,例如 `, \, 空白键等等字符时,这个 -0 参数可以将他还原成一般字符。这个参数可以用于特殊状态喔!
  • -e:这个是 EOF (end of file) 的意思。后面可以接一个字串,当 xargs 分析到这个字串时,就会停止继续工作!
  • -p:在执行每个指令的 argument 时,都会询问使用者的意思;
  • -n:后面接次数,每次 command 指令执行时,要使用几个参数的意思。
  • 当 xargs 后面没有接任何的指令时,默认是以 echo 来进行输出喔!
# 范例一:将 /etc/passwd 内的第一栏取出,仅取三行,使用 id 这个指令将每个帐号内容秀出来
id root
uid=0(root) gid=0(root) groups=0(root) # 这个 id 指令可以查询使用者的 UID/GID 等信息
id $(cut -d ':' -f 1 /etc/passwd | head -n 3)
# 虽然使用 $(cmd) 可以预先取得参数,但可惜的是, id 这个指令“仅”能接受一个参数而已!
# 所以上述的这个指令执行会出现错误!根本不会显示用户的 ID 啊!
cut -d ':' -f 1 /etc/passwd | head -n 3 | id
uid=1000(dmtsai) gid=1000(dmtsai) groups=1000(dmtsai),10(wheel) # 我不是要查自己啊!
# 因为 id 并不是管线命令,因此在上面这个指令执行后,前面的东西通通不见!只会执行 id!
cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs id
# 依旧会出现错误!这是因为 xargs 一口气将全部的数据通通丢给 id 处理~但 id 就接受 1 个啊最多!
cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id
uid=0(root) gid=0(root) groups=0(root)
uid=1(bin) gid=1(bin) groups=1(bin)
uid=2(daemon) gid=2(daemon) groups=2(daemon)
# 通过 -n 来处理,一次给予一个参数,因此上述的结果就 OK 正常的显示啰!
# 范例二:同上,但是每次执行 id 时,都要询问使用者是否动作?
cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 1 id
id root ?...y
uid=0(root) gid=0(root) groups=0(root)
id bin ?...y
.....(下面省略).....
# 呵呵!这个 -p 的选项可以让使用者的使用过程中,被询问到每个指令是否执行!
# 范例三:将所有的 /etc/passwd 内的帐号都以 id 查阅,但查到 sync 就结束指令串
cut -d ':' -f 1 /etc/passwd | xargs -e'sync' -n 1 id
# 仔细与上面的案例做比较。也同时注意,那个 -e'sync' 是连在一起的,中间没有空白键
# 上个例子当中,第六个参数是 sync 啊,那么我们下达 -e'sync' 后,则分析到 sync 这个字串时,
# 后面的其他 stdin 的内容就会被 xargs 舍弃掉了!

其实,在 man xargs 里面就有三四个小范例,您可以自行参考一下内容。 此外, xargs 真的是很好用的一个玩意儿!您真的需要好好的参详参详!会使用 xargs 的原因是, 很多指令其实并不支持管线命令,因此我们可以通过 xargs 来提供该指令引用 standard input 之用!

# 范例四:找出 /usr/sbin 下面具有特殊权限的文件名,并使用 ls -l 列出详细属性
find /usr/sbin -perm /7000 | xargs ls -l
-rwx--s--x. 1 root lock 11208 Jun 10 2014 /usr/sbin/lockdev
-rwsr-xr-x. 1 root root 113400 Mar 6 12:17 /usr/sbin/mount.nfs
-rwxr-sr-x. 1 root root 11208 Mar 6 11:05 /usr/sbin/netreport
.....(下面省略).....
# 聪明的读者应该会想到使用“ ls -l $(find /usr/sbin -perm /7000) ”来处理这个范例!
# 都 OK!能解决问题的方法,就是好方法!

命令: tr, col, join, paste, expand

tr 可以用来删除一段讯息当中的文字,或者是进行文字讯息的替换!

tr [-ds] SET1 ...

选项与参数:

  • -d:删除讯息当中的 SET1 这个字串;
  • -s:取代掉重复的字符!
# 范例一:将 last 输出的讯息中,所有的小写变成大写字符:
last | tr '[a-z]' '[A-Z]'
# 事实上,没有加上单引号也是可以执行的,如:last | tr [a-z] [A-Z]
# 范例二:将 /etc/passwd 输出的讯息中,将冒号 (:) 删除
cat /etc/passwd | tr -d ':'
# 范例三:将 /etc/passwd 转存成 dos 断行到 /root/passwd 中,再将 ^M 符号删除
cp /etc/passwd ~/passwd && unix2dos ~/passwd
file /etc/passwd ~/passwd
/etc/passwd: ASCII text
/home/dmtsai/passwd: ASCII text, with CRLF line terminators <==就是 DOS 断行
cat ~/passwd | tr -d '\r' > ~/passwd.linux
# 那个 \r 指的是 DOS 的断行字符,关于更多的字符,请参考 man tr
ll /etc/passwd ~/passwd*
-rw-r--r--. 1 root root 2092 Jun 17 00:20 /etc/passwd
-rw-r--r--. 1 dmtsai dmtsai 2133 Jul 9 22:13 /home/dmtsai/passwd
-rw-rw-r--. 1 dmtsai dmtsai 2092 Jul 9 22:13 /home/dmtsai/passwd.linux
# 处理过后,发现文件大小与原本的 /etc/passwd 就一致了!

其实这个指令也可以写在“正则表达式”里头!因为他也是由正则表达式的方式来取代数据的! 以上面的例子来说,使用 [] 可以设置一串字呢!也常常用来取代文件中的怪异符号! 例如上面第三个例子当中,可以去除 DOS 文件留下来的 ^M 这个断行的符号!这东西相当的有用!相信处理 Linux & Windows 系统中的人们最麻烦的一件事就是这个事情啦!亦即是 DOS 下面会自动的在每行行尾加入 ^M 这个断行符号!这个时候除了以前讲过的 dos2unix 之外,我们也可以使用这个 tr 来将 ^M 去除! ^M 可以使用 \r 来代替之!

col

col [-xb]

选项与参数:

  • -x:将 tab 键转换成对等的空白键
范例一:利用 cat -A 显示出所有特殊按键,最后以 col 将 [tab] 转成空白
cat -A /etc/man_db.conf <==此时会看到很多 ^I 的符号,那就是 tab
cat /etc/man_db.conf | col -x | cat -A | more
# 嘿嘿!如此一来, [tab] 按键会被取代成为空白键,输出就美观多了!

虽然 col 有他特殊的用途,不过,很多时候,他可以用来简单的处理将 [tab] 按键取代成为空白键! 例如上面的例子当中,如果使用 cat -A 则 [tab] 会以 ^I 来表示。 但经过 col -x 的处理,则会将 [tab] 取代成为对等的空白键!

join 处理两个文件之间的数据

join [-ti12] file1 file2

选项与参数:

  • -t:join 默认以空白字符分隔数据,并且比对“第一个字段”的数据,如果两个文件相同,则将两笔数据联成一行,且第一个字段放在第一个
  • -i:忽略大小写的差异;
  • -1:这个是数字的 1 ,代表“第一个文件要用那个字段来分析”的意思;
  • -2:代表“第二个文件要用那个字段来分析”的意思。
# 范例一:用 root 的身份,将 /etc/passwd 与 /etc/shadow 相关数据整合成一栏
head -n 3 /etc/passwd /etc/shadow
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
==> /etc/shadow <==
root:$6$wtbCCce/PxMeE5wm$KE2IfSJr...:16559:0:99999:7:::
bin:*:16372:0:99999:7:::
daemon:*:16372:0:99999:7:::
# 由输出的数据可以发现这两个文件的最左边字段都是相同帐号!且以 : 分隔
join -t ':' /etc/passwd /etc/shadow | head -n 3
root:x:0:0:root:/root:/bin/bash:$6$wtbCCce/PxMeE5wm$KE2IfSJr...:16559:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:16372:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:16372:0:99999:7:::
# 通过上面这个动作,我们可以将两个文件第一字段相同者整合成一列!
# 第二个文件的相同字段并不会显示(因为已经在最左边的字段出现了啊!)
# 范例二:我们知道 /etc/passwd 第四个字段是 GID ,那个 GID 记录在 /etc/group 当中的第三个字段,请问如何将两个文件整合?
head -n 3 /etc/passwd /etc/group
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
==> /etc/group <==
root:x:0:
bin:x:1:
daemon:x:2:
# 从上面可以看到,确实有相同的部分喔!赶紧来整合一下!
join -t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3
0:root:x:0:root:/root:/bin/bash:root:x:
1:bin:x:1:bin:/bin:/sbin/nologin:bin:x:
2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:
# 同样的,相同的字段部分被移动到最前面了!所以第二个文件的内容就没再显示。
# 请读者们配合上述显示两个文件的实际内容来比对!

这个 join 在处理两个相关的数据文件时,就真的是很有帮助的啦! 例如上面的案例当中,我的 /etc/passwd, /etc/shadow, /etc/group 都是有相关性的, 其中 /etc/passwd, /etc/shadow 以帐号为相关性,至于 /etc/passwd, /etc/group 则以所谓的 GID (帐号的数字定义) 来作为他的相关性。根据这个相关性, 我们可以将有关系的数据放置在一起!这在处理数据可是相当有帮助的! 但是上面的例子有点难,希望您可以静下心好好的看一看原因喔!

此外,需要特别注意的是,在使用 join 之前,你所需要处理的文件应该要事先经过排序 (sort) 处理! 否则有些比对的项目会被略过呢!特别注意了!

paste 直接将两行贴在一起,且中间以 [tab] 键隔开

paste [-d] file1 file2

选项与参数:

  • -d:后面可以接分隔字符。默认是以 [tab] 来分隔的!
  • -:如果 file 部分写成 - ,表示来自 standard input 的数据的意思。
# 范例一:用 root 身份,将 /etc/passwd 与 /etc/shadow 同一行贴在一起
paste /etc/passwd /etc/shadow
root:x:0:0:root:/root:/bin/bash root:$6$wtbCCce/PxMeE5wm$KE2IfSJr...:16559:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin bin:*:16372:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:16372:0:99999:7:::
# 注意喔!同一行中间是以 [tab] 按键隔开的!
# 范例二:先将 /etc/group 读出(用 cat),然后与范例一贴上一起!且仅取出前三行
cat /etc/group|paste /etc/passwd /etc/shadow - | head -n 3
# 这个例子的重点在那个 - 的使用!那玩意儿常常代表 stdin 喔!

expand 将 [tab] 按键转成空白键

expand [-t] file

选项与参数:

  • -t:后面可以接数字。一般来说,一个 tab 按键可以用 8 个空白键取代。我们也可以自行定义一个 [tab] 按键代表多少个字符呢!
# 范例一:将 /etc/man_db.conf 内行首为 MANPATH 的字样就取出;仅取前三行;
grep '^MANPATH' /etc/man_db.conf | head -n 3
MANPATH_MAP /bin /usr/share/man
MANPATH_MAP /usr/bin /usr/share/man
MANPATH_MAP /sbin /usr/share/man
# 行首的代表标志为 ^ ,这个我们留待下节介绍!先有概念即可!
# 范例二:承上,如果我想要将所有的符号都列出来?(用 cat)
grep '^MANPATH' /etc/man_db.conf | head -n 3 |cat -A
MANPATH_MAP^I/bin^I^I^I/usr/share/man$
MANPATH_MAP^I/usr/bin^I^I/usr/share/man$
MANPATH_MAP^I/sbin^I^I^I/usr/share/man$
# 发现差别了吗?没错~ [tab] 按键可以被 cat -A 显示成为 ^I
# 范例三:承上,我将 [tab] 按键设置成 6 个字符的话?
grep '^MANPATH' /etc/man_db.conf | head -n 3 | expand -t 6 - | cat -A
MANPATH_MAP /bin /usr/share/man$
MANPATH_MAP /usr/bin /usr/share/man$
MANPATH_MAP /sbin /usr/share/man$
123456123456123456123456123456123456123456123456...
# 仔细看一下上面的数字说明,因为我是以 6 个字符来代表一个 [tab] 的长度,所以,
# MAN... 到 /usr 之间会隔 12 (两个 [tab]) 个字符喔!如果 tab 改成 9 的话,
# 情况就又不同了!这里也不好理解~您可以多设置几个数字来查阅就晓得!

vi 与 vim

基本上 vi 共分为三种模式,分别是“一般指令模式”、“编辑模式”与“指令列命令模式”。 这三种模式的作用分别是:

  • 一般指令模式 (command mode)
    • 以 vi 打开一个文件就直接进入一般指令模式了(这是默认的模式,也简称为一般模式)。在这个模式中, 你可以使用“上下左右”按键来移动光标,你可以使用“删除字符”或“删除整列”来处理文件内容, 也可以使用“复制、贴上”来处理你的文件数据。
  • 编辑模式 (insert mode)
    • 在一般指令模式中可以进行删除、复制、贴上等等的动作,但是却无法编辑文件内容的! 要等到你按下 i, I, o, O, a, A, r, R 等任何一个字母之后才会进入编辑模式。注意了!通常在 Linux 中,按下这些按键时,在画面的左下方会出现“ INSERT 或 REPLACE ”的字样,此时才可以进行编辑。而如果要回到一般指令模式时, 则必须要按下“Esc”这个按键即可退出编辑模式。
  • 指令列命令模式 (command-line mode)
    • 在一般模式当中,输入 : / ? 三个中的任何一个按钮,就可以将光标移动到最下面那一列。在这个模式当中, 可以提供你“搜寻数据”的动作,而读取、存盘、大量取代字符、离开 vi 、显示行号等等的动作则是在此模式中达成的!

一般指令模式可用的按钮说明

  • 光标移动
    • h 或 向左方向键(←):光标向左移动一个字符
    • j 或 向下方向键(↓):光标向下移动一个字符
    • k 或 向上方向键(↑):光标向上移动一个字符
    • l 或 向右方向键(→):光标向右移动一个字符
    • 如果你将右手放在键盘上的话,你会发现 hjkl 是排列在一起的,因此可以使用这四个按钮来移动光标。 如果想要进行多次移动的话,例如向下移动 30 列,可以使用 30j30↓ 的组合按键, 亦即加上想要进行的次数(数字)后,按下动作即可!
    • [Ctrl] + [f]:屏幕“向下”移动一页,相当于 [Page Down]按键 (常用)
    • [Ctrl] + [b]:屏幕“向上”移动一页,相当于 [Page Up] 按键 (常用)
    • [Ctrl] + [d]:屏幕“向下”移动半页
    • [Ctrl] + [u]:屏幕“向上”移动半页
    • +:光标移动到非空白字符的下一列
    • -:光标移动到非空白字符的上一列
    • n<space>:那个 n 表示“数字”,例如 20 。按下数字后再按空白键,光标会向右移动这一列的 n 个字符。例如 20 则光标会向后面移动 20 个字符距离。
    • 0 或功能键[Home]:这是数字“ 0 ”:移动到这一列的最前面字符处 (常用)
    • $ 或功能键[End]:移动到这一列的最后面字符处(常用)
    • H:光标移动到这个屏幕的最上方那一列的第一个字符
    • M:光标移动到这个屏幕的中央那一列的第一个字符
    • L:光标移动到这个屏幕的最下方那一列的第一个字符
    • G:移动到这个文件的最后一列(常用)
    • nG:n 为数字。移动到这个文件的第 n 列。例如 20G 则会移动到这个文件的第 20 列(可配合 :set nu
    • gg:移动到这个文件的第一列,相当于 1G 啊! (常用)
    • n<Enter>:n 为数字。光标向下移动 n 列(常用)
  • 复制粘贴
    • x, X:在一列字当中,x 为向后删除一个字符 (相当于 [del] 按键), X 为向前删除一个字符(相当于 [backspace] 亦即是倒退键) (常用)
    • nx:n 为数字,连续向后删除 n 个字符。举例来说,我要连续删除 10 个字符, “10x”
    • dd:删除光标所在的那一整列(常用)
    • ndd:n 为数字。删除光标所在的向下 n 列,例如 20dd 则是删除 20 列 (常用)
    • d1G:删除光标所在到第一列的所有数据
    • dG:删除光标所在到最后一列的所有数据
    • d$:删除光标所在处,到该列的最后一个字符
    • d0:那个是数字的 0 ,删除光标所在处,到该列的最前面一个字符
    • yy:复制光标所在的那一列(常用)
    • nyy:n 为数字。复制光标所在的向下 n 列,例如 20yy 则是复制 20 列(常用)
    • y1G:复制光标所在列到第一列的所有数据
    • yG:复制光标所在列到最后一列的所有数据
    • y0:复制光标所在的那个字符到该列行首的所有数据
    • y$:复制光标所在的那个字符到该列行尾的所有数据
    • p, P:p 为将已复制的数据在光标下一列贴上,P 则为贴在光标上一列! 举例来说,我目前光标在第 20 列,且已经复制了 10 列数据。则按下 p 后, 那 10 列数据会贴在原本的 20 列之后,亦即由 21 列开始贴。但如果是按下 P 呢? 那么原本的第 20 列会被推到变成 30 列。 (常用)
    • J:将光标所在列与下一列的数据结合成同一列
    • c:重复删除多个数据,例如向下删除 10 列,[ 10cj ]
    • u:复原前一个动作。(常用)
    • [Ctrl]+r:重做上一个动作。(常用)这个 u 与 [Ctrl]+r 是很常用的指令!一个是复原,另一个则是重做一次~ 利用这两个功能按键,你的编辑,嘿嘿!很快乐的啦!
    • .:不要怀疑!这就是小数点!意思是重复前一个动作的意思。 如果你想要重复删除、重复贴上等等动作,按下小数点“.”就好了! (常用)
  • 搜寻取代
    • /word:向光标之下寻找一个名称为 word 的字串。例如要在文件内搜寻 vbird 这个字串,就输入 /vbird 即可! (常用)
    • ?word:向光标之上寻找一个字串名称为 word 的字串。
    • n:这个 n 是英文按键。代表“重复前一个搜寻的动作”。举例来说, 如果刚刚我们执行 /vbird 去向下搜寻 vbird 这个字串,则按下 n 后,会向下继续搜寻下一个名称为 vbird 的字串。如果是执行 ?vbird 的话,那么按下 n 则会向上继续搜寻名称为 vbird 的字串!
    • N:这个 N 是英文按键。与 n 刚好相反,为“反向”进行前一个搜寻动作。 例如 /vbird 后,按下 N 则表示“向上”搜寻 vbird 。
    • 使用 /word 配合 n 及 N 是非常有帮助的!可以让你重复的找到一些你搜寻的关键字!
    • :n1,n2s/word1/word2/g:n1 与 n2 为数字。在第 n1 与 n2 列之间寻找 word1 这个字串,并将该字串取代为 word2 !举例来说,在 100 到 200 列之间搜寻 vbird 并取代为 VBIRD 则::100,200s/vbird/VBIRD/g(常用)
    • :1,$s/word1/word2/g:从第一列到最后一列寻找 word1 字串,并将该字串取代为 word2 !(常用)
    • :1,$s/word1/word2/gc:从第一列到最后一列寻找 word1 字串,并将该字串取代为 word2 !且在取代前显示提示字符给使用者确认 (confirm) 是否需要取代!(常用)

进入插入或取代的编辑模式

  • i, I:进入插入模式(Insert mode)
    • i 为“从目前光标所在处插入”, I 为“在目前所在列的第一个非空白字符处开始插入”。 (常用)
  • a, A:进入插入模式(Insert mode)
    • a 为“从目前光标所在的下一个字符处开始插入”, A 为“从光标所在列的最后一个字符处开始插入”。(常用)
  • o, O:进入插入模式(Insert mode)
    • 这是英文字母 o 的大小写。o 为“在目前光标所在的下一列处插入新的一列”; O 为在目前光标所在处的上一列插入新的一列!(常用)
  • r, R:进入取代模式(Replace mode)
    • r 只会取代光标所在的那一个字符一次;R会一直取代光标所在的文字,直到按下 ESC 为止;(常用)
  • 上面这些按键中,在 vi 画面的左下角处会出现“–INSERT–”或“–REPLACE–”的字样。 由名称就知道该动作了吧!!特别注意的是,我们上面也提过了,你想要在文件里面输入字符时, 一定要在左下角处看到 INSERT 或 REPLACE 才能输入喔!
  • [Esc]:退出编辑模式,回到一般指令模式中(常用)

一般指令模式切换到指令列模式的可用按钮说明

  • 指令列模式的储存、离开等指令
    • :w:将编辑的数据写入硬盘文件中(常用)
    • :w!:若文件属性为“只读”时,强制写入该文件。不过,到底能不能写入, 还是跟你对该文件的文件权限有关啊!
    • :q:离开 vi (常用)
    • :q!:若曾修改过文件,又不想储存,使用 ! 为强制离开不储存盘案。
    • :wq:储存后离开,若为 :wq! 则为强制储存后离开 (常用)
    • ZZ:这是大写的 Z 喔!若文件没有更动,则不储存离开,若文件已经被更动过,则储存后离开!
    • :w [filename]:将编辑的数据储存成另一个文件(类似另存新文件)
    • :r [filename]:在编辑的数据中,读入另一个文件的数据。亦即将 “filename” 这个文件内容加到光标所在列后面
    • :n1,n2 w [filename]:将 n1 到 n2 的内容储存成 filename 这个文件。
    • :! command:暂时离开 vi 到指令列模式下执行 command 的显示结果!例如 :! ls /home 即可在 vi 当中察看 /home 下面以 ls 输出的文件信息!
  • vim 环境的变更
    • :set nu:显示行号,设置之后,会在每一列的字首显示该列的行号
    • :set nonu:与 set nu 相反,为取消行号!

区块选择(Visual Block)

  • v:字符选择,会将光标经过的地方反白选择!
  • V:列选择,会将光标经过的列反白选择!
  • [Ctrl]+v:区块选择,可以用长方形的方式选择数据
  • y:将反白的地方复制起来
  • d:将反白的地方删除掉
  • p:将刚刚复制的区块,在光标所在处贴上!

多文件编辑

通过 vim file1 file2 指令来使用一个 vim 打开两个文件

  • :n:编辑下一个文件
  • :N:编辑上一个文件
  • :files:列出目前这个 vim 的打开的所有文件

多窗口功能

如何分区窗口并放入文件呢? 很简单啊!在指令列模式输入“:sp {filename}”即可!那个 filename 可有可无, 如果想要在新窗口启动另一个文件,就加入文件名,否则仅输入 :sp 时, 出现的则是同一个文件在两个窗口间!

  • :sp [filename]:打开一个新窗口,如果有加 filename, 表示在新窗口打开一个新文件,否则表示两个窗口为同一个文件内容(同步显示)。
  • [ctrl]+w+j / [ctrl]+w+↓ :按键的按法是:先按下 [ctrl] 不放, 再按下 w 后放开所有的按键,然后再按下 j (或向下方向键),则光标可移动到下方的窗口。
  • [ctrl]+w+k / [ctrl]+w+↑:同上,不过光标移动到上面的窗口。
  • [ctrl]+w+q:其实就是 :q 结束离开啦! 举例来说,如果我想要结束下方的窗口,那么利用 [ctrl]+w+↓ 移动到下方窗口后,按下 :q 即可离开, 也可以按下 [ctrl]+w+q 啊!

vim 环境设置与记录

主要是修改 ~/.vimrc~/.viminfo

  • :set nu / :set nonu:就是设置与取消行号啊!
  • :set hlsearch / :set nohlsearch:hlsearch 就是 high light search(高亮度搜寻)。 这个就是设置是否将搜寻的字串反白的设置值。默认值是 hlsearch
  • :set autoindent / :set noautoindent:是否自动缩排?autoindent 就是自动缩排。
  • :set backup:是否自动储存备份文件?一般是 nobackup 的, 如果设置 backup 的话,那么当你更动任何一个文件时,则原始文件会被另存成一个文件名为 filename~ 的文件。 举例来说,我们编辑 hosts ,设置 :set backup,那么当更动 hosts 时,在同目录下,就会产生 hosts~ 文件名的文件,记录原始的 hosts 文件内容
  • :set ruler:还记得我们提到的右下角的一些状态列说明吗? 这个 ruler 就是在显示或不显示该设置值的啦!
  • :set showmode:这个则是,是否要显示 --INSERT-- 之类的字眼在左下角的状态列。
  • :set backspace=(012):一般来说, 如果我们按下 i 进入编辑模式后,可以利用倒退键 (backspace) 来删除任意字符的。 但是,某些 distribution 则不许如此。此时,我们就可以通过 backspace 来设置啰~ 当 backspace 为 2 时,就是可以删除任意值;0 或 1 时,仅可删除刚刚输入的字符, 而无法删除原本就已经存在的文字了!
  • :set all:显示目前所有的环境参数设置值。
  • :set:显示与系统默认值不同的设置参数, 一般来说就是你有自行变动过的设置参数啦!
  • :syntax on / :syntax off:是否依据程序相关语法显示不同颜色? 举例来说,在编辑一个纯文本文件时,如果开头是以 # 开始,那么该列就会变成蓝色。 如果你懂得写程序,那么这个 :syntax on 还会主动的帮你除错呢!但是, 如果你仅是编写纯文本,要避免颜色对你的屏幕产生的干扰,则可以取消这个设置 。
  • :set bg=dark / :set bg=light:可用以显示不同的颜色色调,默认是 light 。如果你常常发现注解的字体深蓝色实在很不容易看, 那么这里可以设置为 dark 喔!试看看,会有不同的样式呢!

总之,这些设置值很有用处的啦!但是…我是否每次使用 vim 都要重新设置一次各个参数值? 这不太合理吧?没错啊!所以,我们可以通过配置文件来直接规定我们习惯的 vim 操作环境呢! 整体 vim 的设置值一般是放置在 /etc/vimrc 这个文件,不过,不建议你修改他! 你可以修改 ~/.vimrc 这个文件 (默认不存在,请你自行手动创建!),将你所希望的设置值写入! 举例来说,可以是这样的一个文件:

很多朋友常常哀嚎,说他们的 vim 里面怎么无法显示正常的中文啊?其实这很有可能是因为编码的问题! 因为中文编码有 big5 与 utf8 两种,如果你的文件是使用 big5 编码制作的,但在 vim 的终端接口中你使用的是万国码(utf8), 由于编码的不同,你的中文文件内容当然就是一堆乱码了!怎么办?这时你得要考虑许多东西啦!有这些:

  1. 你的 Linux 系统默认支持的语系数据:这与 /etc/locale.conf 有关;
  2. 你的终端接口 (bash) 的语系: 这与 LANG, LC_ALL 这几个变量有关;
  3. 你的文件原本的编码;
  4. 打开终端机的软件,例如在 GNOME 下面的窗口接口。

事实上最重要的是上头的第三与第四点,只要这两点的编码一致,你就能够正确的看到与编辑你的中文文件。 否则就会看到一堆乱码啦!

Bash

默认的指令记忆功能可以到达 1000 个!也就是说,你曾经下达过的指令几乎都被记录下来了。
这么多的指令记录在哪里呢?在你的主文件夹内的 .bash_history 啦! 不过,需要留意的是,~/.bash_history 记录的是前一次登陆以前所执行过的指令, 而至于这一次登陆所执行的指令都被暂存在内存中,当你成功的登出系统后,该指令记忆才会记录到 .bash_history 当中!

bash 的配置文件主要分为 login shell 与 non-login shell。login shell 主要读取 /etc/profile~/.bash_profile, non-login shell 则仅读取 ~/.bashrc

命令别名设置功能 alias

假如我需要知道这个目录下面的所有文件 (包含隐藏文件) 及所有的文件属性,那么我就必须要下达 ls -al 这样的指令串,唉!真麻烦,有没有更快的取代方式?呵呵!就使用命令别名呀!例如鸟哥最喜欢直接以 lm 这个自订的命令来取代上面的命令,也就是说, lm 会等于 ls -al 这样的一个功能,嘿!那么要如何作呢?就使用 alias 即可!你可以在指令列输入 alias 就可以知道目前的命令别名有哪些了!也可以直接下达命令来设置别名呦:alias lm='ls -al'

查询指令是否为 Bash shell 的内置命令 type

type [-tpa] name 选项与参数:

  • 不加任何选项与参数时,type 会显示出 name 是外部指令还是 bash 内置指令
  • -t:当加入 -t 参数时,type 会将 name 以下面这些字眼显示出他的意义:
    • file:表示为外部指令;
    • alias:表示该指令为命令别名所设置的名称;
    • builtin:表示该指令为 bash 内置的指令功能;
  • -p:如果后面接的 name 为外部指令时,才会显示完整文件名;
  • -a:会由 PATH 变量定义的路径中,将所有含 name 的指令都列出来,包含 alias

指令的下达与快速编辑按钮

上面这个指令用途是将三个文件复制到 /root 这个目录下而已。不过,因为指令太长, 于是鸟哥就利用 \[Enter] 来将 [Enter] 这个按键“跳脱!”开来,让 [Enter] 按键不再具有“开始执行”的功能!好让指令可以继续在下一行输入。 需要特别留意, [Enter] 按键是紧接着反斜线 \ 的,两者中间没有其他字符。 因为 \ 仅跳脱“紧接着的下一个字符”而已!

另外,当你所需要下达的指令特别长,或者是你输入了一串错误的指令时,你想要快速的将这串指令整个删除掉,一般来说,我们都是按下删除键的。 有没有其他的快速组合键可以协助呢?是有的!常见的有下面这些:

  • [ctrl]+u / [ctrl]+k
    • 分别是从光标处向前删除指令串 ([ctrl]+u) 及向后删除指令串 ([ctrl]+k)。
  • [ctrl]+a / [ctrl]+e
    • 分别是让光标移动到整个指令串的最前面 ([ctrl]+a) 或最后面 ([ctrl]+e)。

Shell 相关的部分会另外进行学习,这里暂时略过

万用字符

  • *:代表“ 0 个到无穷多个”任意字符
  • ?:代表“一定有一个”任意字符
  • [ ]:同样代表“一定有一个在括号内”的字符(非任意字符)。例如 [abcd] 代表“一定有一个字符, 可能是 a, b, c, d 这四个任何一个”
  • [ - ]:若有减号在中括号内时,代表“在编码顺序内的所有字符”。例如 [0-9] 代表 0 到 9 之间的所有数字,因为数字的语系编码是连续的!
  • [^ ]:若中括号内的第一个字符为指数符号(^),那表示“反向选择”,例如 [^abc] 代表 一定有一个字符,只要是非 a, b, c 的其他字符就接受的意思。

特殊符号

  • # 注解符号:这个最常被使用在 script 当中,视为说明!在后的数据均不执行
  • \ 跳脱符号:将“特殊字符或万用字符”还原成一般字符
  • | 管线 (pipe):分隔两个管线命令的界定(后两节介绍);
  • ; 连续指令下达分隔符号:连续性命令的界定 (注意!与管线命令并不相同)
  • ~ 使用者的主文件夹
  • $ 取用变量前置字符:亦即是变量之前需要加的变量取代值
  • & 工作控制 (job control):将指令变成背景下工作
  • ! 逻辑运算意义上的“非” not 的意思!
  • / 目录符号:路径分隔的符号
  • >, >> 数据流重导向:输出导向,分别是“取代”与“累加”
  • <, << 数据流重导向:输入导向 (这两个留待下节介绍)
  • ' ' 单引号,不具有变量置换的功能($ 变为纯文本)
  • " " 具有变量置换的功能!($ 可保留相关功能)
  • ` ` 两个 ` 中间为可以先执行的指令,亦可使用 $( )
  • ( ) 在中间为子 shell 的起始与结束
  • { } 在中间为命令区块的组合!

重定向

简单的说,标准输出指的是“指令执行所回传的正确的讯息”,而标准错误输出可理解为“ 指令执行失败后,所回传的错误讯息”。举个简单例子来说,我们的系统默认有 /etc/crontab 但却无 /etc/vbirdsay, 此时若下达 cat /etc/crontab /etc/vbirdsay 这个指令时,cat 会进行:

  • 标准输出:读取 /etc/crontab 后,将该文件内容显示到屏幕上;
  • 标准错误输出:因为无法找到 /etc/vbirdsay,因此在屏幕上显示错误讯息

不管正确或错误的数据都是默认输出到屏幕上,所以屏幕当然是乱乱的!那能不能通过某些机制将这两股数据分开呢? 当然可以啊!那就是数据流重导向的功能啊!数据流重导向可以将 standard output (简称 stdout) 与 standard error output (简称 stderr) 分别传送到其他的文件或设备去,而分别传送所用的特殊字符则如下所示:

  1. 标准输入  (stdin) :代码为 0 ,使用 <<<
  2. 标准输出  (stdout):代码为 1 ,使用 >(覆盖) 或 >>(累加) ;
  3. 标准错误输出(stderr):代码为 2 ,使用 2>(覆盖) 或 2>>(累加) ;

想像一下,如果我知道错误讯息会发生,所以要将错误讯息忽略掉而不显示或储存呢? 这个时候黑洞设备 /dev/null 就很重要了!这个 /dev/null 可以吃掉任何导向这个设备的信息喔!

如:find /home -name .bashrc 2> /dev/null

命令执行的判断依据: ; , &&, ||

  • cmd ; cmd 不考虑指令相关性的连续指令下达
  • $? (指令回传值) 与 && 或 ||

管线命令 pipe

在每个管线后面接的第一个数据必定是“指令”喔!而且这个指令必须要能够接受 standard input 的数据才行,这样的指令才可以是为“管线命令”,例如 less, more, head, tail 等都是可以接受 standard input 的管线命令啦。至于例如 ls, cp, mv 等就不是管线命令了!因为 ls, cp, mv 并不会接受来自 stdin 的数据。 也就是说,管线命令主要有两个比较需要注意的地方:

  • 管线命令仅会处理 standard output,对于 standard error output 会予以忽略
  • 管线命令必须要能够接受来自前一个指令的数据成为 standard input 继续处理才行。

关于减号 - 的用途

管线命令在 bash 的连续的处理程序中是相当重要的!另外,在 log file 的分析当中也是相当重要的一环, 所以请特别留意!另外,在管线命令当中,常常会使用到前一个指令的 stdout 作为这次的 stdin , 某些指令需要用到文件名称 (例如 tar) 来进行处理时,该 stdin 与 stdout 可以利用减号 “-“ 来替代, 举例来说:

``bash
mkdir /tmp/homeback
tar -cvf - /home | tar -xvf - -C /tmp/homeback
```

上面这个例子是说:“我将 /home 里面的文件给他打包,但打包的数据不是纪录到文件,而是传送到 stdout; 经过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf - ”。后面的这个 - 则是取用前一个指令的 stdout,因此,我们就不需要使用 filename 了!这是很常见的例子喔!注意注意!

Linux 目录的含义

  • bin
    • 系统有很多放置可执行文件的目录,但/bin比较特殊。因为/bin放置的是在单人维护模式下还能够被操作的指令。 在/bin下面的指令可以被root与一般帐号所使用,主要有:cat, chmod, chown, date, mv, mkdir, cp, bash等等常用的指令。
  • /boot
    • 这个目录主要在放置开机会使用到的文件,包括Linux核心文件以及开机菜单与开机所需配置文件等等。 Linux kernel常用的文件名为:vmlinuz,如果使用的是grub2这个开机管理程序, 则还会存在/boot/grub2/这个目录喔!
  • /dev
    • 在Linux系统上,任何设备与周边设备都是以文件的型态存在于这个目录当中的。 你只要通过存取这个目录下面的某个文件,就等于存取某个设备啰~ 比要重要的文件有 /dev/null, /dev/zero, /dev/tty, /dev/loop*, /dev/sd* 等等
  • /etc
    • 系统主要的配置文件几乎都放置在这个目录内,例如人员的帐号密码档、 各种服务的启始档等等。一般来说,这个目录下的各文件属性是可以让一般使用者查阅的, 但是只有root有权力修改。FHS建议不要放置可可执行文件(binary)在这个目录中喔。比较重要的文件有: /etc/modprobe.d/, /etc/passwd, /etc/fstab, /etc/issue 等等。另外 FHS 还规范几个重要的目录最好要存在 /etc/ 目录下喔:
    • /etc/opt(必要):这个目录在放置第三方协力软件 /opt 的相关配置文件
    • /etc/X11/(建议):与 X Window 有关的各种配置文件都在这里,尤其是 xorg.conf 这个 X Server 的配置文件。
    • /etc/sgml/(建议):与 SGML 格式有关的各项配置文件
    • /etc/xml/(建议):与 XML 格式有关的各项配置文件
  • /lib
    • 系统的函数库非常的多,而/lib放置的则是在开机时会用到的函数库, 以及在/bin或/sbin下面的指令会调用的函数库而已。 什么是函数库呢?你可以将他想成是“外挂”,某些指令必须要有这些“外挂”才能够顺利完成程序的执行之意。 另外 FSH 还要求下面的目录必须要存在:
    • /lib/modules/:这个目录主要放置可抽换式的核心相关模块(驱动程序)喔!
  • /media
    • media是“媒体”的英文,顾名思义,这个/media下面放置的就是可移除的设备啦! 包括软盘、光盘、DVD等等设备都暂时挂载于此。常见的文件名有:/media/floppy,/media/cdrom等等。
  • /mnt
    • 如果你想要暂时挂载某些额外的设备,一般建议你可以放置到这个目录中。 在古早时候,这个目录的用途与/media相同啦!只是有了/media之后,这个目录就用来暂时挂载用了。
  • /opt
    • 这个是给第三方协力软件放置的目录。什么是第三方协力软件啊? 举例来说,KDE这个桌面管理系统是一个独立的计划,不过他可以安装到Linux系统中,因此KDE的软件就建议放置到此目录下了。 另外,如果你想要自行安装额外的软件(非原本的distribution提供的),那么也能够将你的软件安装到这里来。 不过,以前的Linux系统中,我们还是习惯放置在/usr/local目录下呢!
  • /run
    • 早期的 FHS 规定系统开机后所产生的各项信息应该要放置到 /var/run 目录下,新版的 FHS 则规范到 /run 下面。 由于 /run 可以使用内存来仿真,因此性能上会好很多!
  • /sbin
    • Linux有非常多指令是用来设置系统环境的,这些指令只有root才能够利用来“设置”系统,其他使用者最多只能用来“查询”而已。 放在/sbin下面的为开机过程中所需要的,里面包括了开机、修复、还原系统所需要的指令。 至于某些服务器软件程序,一般则放置到/usr/sbin/当中。至于本机自行安装的软件所产生的系统可执行文件(system binary), 则放置到/usr/local/sbin/当中了。常见的指令包括:fdisk, fsck, ifconfig, mkfs等等。
  • /srv
    • srv可以视为“service”的缩写,是一些网络服务启动之后,这些服务所需要取用的数据目录。 常见的服务例如WWW, FTP等等。举例来说,WWW服务器需要的网页数据就可以放置在/srv/www/里面。 不过,系统的服务数据如果尚未要提供给网际网络任何人浏览的话,默认还是建议放置到 /var/lib 下面即可。
  • /tmp
    • 这是让一般使用者或者是正在执行的程序暂时放置文件的地方。 这个目录是任何人都能够存取的,所以你需要定期的清理一下。当然,重要数据不可放置在此目录啊! 因为FHS甚至建议在开机时,应该要将/tmp下的数据都删除唷!
  • /usr
    • 第二层 FHS 设置,后续介绍
  • /var
    • 第二层 FHS 设置,主要为放置变动性的数据,后续介绍

FHS 建议可以存在的目录

  • /home
    • 这是系统默认的使用者主文件夹(home directory)。在你新增一个一般使用者帐号时, 默认的使用者主文件夹都会规范到这里来。比较重要的是,主文件夹有两种代号喔:
    • ~:代表目前这个使用者的主文件夹
    • ~dmtsai:则代表 dmtsai 的主文件夹!
  • /lib<qual>
    • 用来存放与 /lib 不同的格式的二进制函数库,例如支持 64 位的 /lib64 函数库等
  • /root
    • 系统管理员(root)的主文件夹。之所以放在这里,是因为如果进入单人维护模式而仅挂载根目录时, 该目录就能够拥有root的主文件夹,所以我们会希望root的主文件夹与根目录放置在同一个分区中。

事实上FHS针对根目录所定义的标准就仅有上面的咚咚,不过我们的Linux下面还有许多目录你也需要了解一下的。 下面是几个在Linux当中也是非常重要的目录喔

  • /lost+found
    • 这个目录是使用标准的ext2/ext3/ext4文件系统格式才会产生的一个目录,目的在于当文件系统发生错误时, 将一些遗失的片段放置到这个目录下。不过如果使用的是 xfs 文件系统的话,就不会存在这个目录了!
  • /proc
    • 这个目录本身是一个“虚拟文件系统(virtual filesystem)”喔!他放置的数据都是在内存当中, 例如系统核心、行程信息(process)、周边设备的状态及网络状态等等。因为这个目录下的数据都是在内存当中, 所以本身不占任何硬盘空间啊!比较重要的文件例如:/proc/cpuinfo, /proc/dma, /proc/interrupts, /proc/ioports, /proc/net/* 等等。
  • /sys
    • 这个目录其实跟/proc非常类似,也是一个虚拟的文件系统,主要也是记录核心与系统硬件信息较相关的信息。 包括目前已载入的核心模块与核心侦测到的硬件设备信息等等。这个目录同样不占硬盘容量喔!

早期 Linux 在设计的时候,若发生问题时,救援模式通常仅挂载根目录而已,因此有五个重要的目录被要求一定要与根目录放置在一起, 那就是 /etc, /bin, /dev, /lib, /sbin 这五个重要目录。现在许多的 Linux distributions 由于已经将许多非必要的文件移出 /usr 之外了, 所以 /usr 也是越来越精简,同时因为 /usr 被建议为“即使挂载成为只读,系统还是可以正常运行”的模样,所以救援模式也能同时挂载 /usr 喔!

/usr 介绍

依据FHS的基本定义,/usr里面放置的数据属于可分享的与不可变动的(shareable, static)。usr是Unix Software Resource的缩写, 也就是“Unix操作系统软件资源”所放置的目录,而不是使用者的数据啦!这点要注意。 FHS建议所有软件开发者,应该将他们的数据合理的分别放置到这个目录下的次目录,而不要自行创建该软件自己独立的目录。

一般来说,/usr的次目录建议有下面这些:

  • /usr/bin/
    • 所有一般用户能够使用的指令都放在这里!目前新的 CentOS 7 已经将全部的使用者指令放置于此,而使用链接文件的方式将 /bin 链接至此! 也就是说, /usr/bin 与 /bin 是一模一样了!另外,FHS 要求在此目录下不应该有子目录!
  • /usr/lib/
    • 基本上,与 /lib 功能相同,所以 /lib 就是链接到此目录中的!
  • /usr/local/
    • 系统管理员在本机自行安装自己下载的软件(非distribution默认提供者),建议安装到此目录, 这样会比较便于管理。举例来说,你的distribution提供的软件较旧,你想安装较新的软件但又不想移除旧版, 此时你可以将新版软件安装于/usr/local/目录下,可与原先的旧版软件有分别啦! 你可以自行到/usr/local去看看,该目录下也是具有bin, etc, include, lib…的次目录喔!
  • /usr/sbin/
    • 非系统正常运行所需要的系统指令。最常见的就是某些网络服务器软件的服务指令(daemon)啰!不过基本功能与 /sbin 也差不多, 因此目前 /sbin 就是链接到此目录中的。
  • /usr/share/
    • 主要放置只读架构的数据文件,当然也包括共享文件。在这个目录下放置的数据几乎是不分硬件架构均可读取的数据, 因为几乎都是文字文件嘛!在此目录下常见的还有这些次目录:
    • /usr/share/man:线上说明文档
    • /usr/share/doc:软件杂项的文件说明
    • /usr/share/zoneinfo:与时区有关的时区文件

FHS 建议可以存在的目录

  • /usr/games/
    • 与游戏比较相关的数据放置处
  • /usr/include/
    • c/c++等程序语言的文件开始(header)与包含档(include)放置处,当我们以tarball方式 (*.tar.gz 的方式安装软件)安装某些数据时,会使用到里头的许多包含档喔!
  • /usr/libexec/
    • 某些不被一般使用者惯用的可执行文件或脚本(script)等等,都会放置在此目录中。例如大部分的 X 窗口下面的操作指令, 很多都是放在此目录下的。
  • /usr/lib<qual>/
    • /lib<qual>/ 功能相同,因此目前 /lib<qual> 就是链接到此目录中
  • /usr/src/
    • 一般源代码建议放置到这里,src有source的意思。至于核心源代码则建议放置到/usr/src/linux/目录下。

/var 介绍

如果/usr是安装时会占用较大硬盘容量的目录,那么/var就是在系统运行后才会渐渐占用硬盘容量的目录。 因为/var目录主要针对常态性变动的文件,包括高速缓存(cache)、登录文件(log file)以及某些软件运行所产生的文件, 包括程序文件(lock file, run file),或者例如MySQL数据库的文件等等。常见的次目录有:

  • /var/cache/
    • 应用程序本身运行过程中会产生的一些暂存盘;
  • /var/lib/
    • 程序本身执行的过程中,需要使用到的数据文件放置的目录。在此目录下各自的软件应该要有各自的目录。 举例来说,MySQL的数据库放置到/var/lib/mysql/而rpm的数据库则放到/var/lib/rpm去!
  • /var/lock/
    • 某些设备或者是文件资源一次只能被一个应用程序所使用,如果同时有两个程序使用该设备时, 就可能产生一些错误的状况,因此就得要将该设备上锁(lock),以确保该设备只会给单一软件所使用。 举例来说,烧录机正在烧录一块光盘,你想一下,会不会有两个人同时在使用一个烧录机烧片? 如果两个人同时烧录,那片子写入的是谁的数据?所以当第一个人在烧录时该烧录机就会被上锁, 第二个人就得要该设备被解除锁定(就是前一个人用完了)才能够继续使用啰。目前此目录也已经挪到 /run/lock 中!
  • /var/log/
    • 重要到不行!这是登录文件放置的目录!里面比较重要的文件如/var/log/messages, /var/log/wtmp(记录登陆者的信息)等。
  • /var/mail/
    • 放置个人电子邮件信箱的目录,不过这个目录也被放置到/var/spool/mail/目录中! 通常这两个目录是互为链接文件啦!
  • /var/run/
    • 某些程序或者是服务启动后,会将他们的PID放置在这个目录下喔!至于PID的意义我们会在后续章节提到的。 与 /run 相同,这个目录链接到 /run 去了!
  • /var/spool/
    • 这个目录通常放置一些伫列数据,所谓的“伫列”就是排队等待其他程序使用的数据啦! 这些数据被使用后通常都会被删除。举例来说,系统收到新信会放置到/var/spool/mail/中, 但使用者收下该信件后该封信原则上就会被删除。信件如果暂时寄不出去会被放到/var/spool/mqueue/中, 等到被送出后就被删除。如果是工作调度数据(crontab),就会被放置到/var/spool/cron/目录中!
捧个钱场?