初识Linux(三)------ Linux 文件与目录管理
在前一章我们认识了Linux系统下的文件权限概念以及目录的配置说明。 在这个章节当中,我们就直接来进一步的操作与管理文件及目录,包括在不同的目录间变换、 创建与删除目录、创建与删除文件,还有寻找文件、查阅文件内容等等,都会在这个章节作个简单的介绍。
1. 目录与路径
1.1 目录的相关操作
比较特殊的目录
需要特别注意的是:在所有目录下面都会存在的两个目录,分别是“.”与“..” 分别代表此层与上层目录的意思。
几个常见的处理目录的指令:
- cd:变换目录
- pwd:显示目前的目录
- mkdir:创建一个新的目录
- rmdir:删除一个空的目录
Linux 的默认命令行界面 (bash shell) 具有文件补齐功能, 可以利用 [tab] 按键来达成你的目录完整性!
1.1.1 cd (change directory, 变换目录)
[root@study ~]# cd [相对路径或绝对路径] [root@study ~]# cd ~dmtsai # 代表去到 dmtsai 这个使用者的主文件夹,亦即 /home/dmtsai
[root@study dmtsai]# cd ~ # 表示回到自己的主文件夹,即是 /root 这个目录
[root@study ~]# cd # 没有加上任何路径,也还是代表回到自己主文件夹的意思
[root@study ~]# cd .. # 表示去到目前的上层目录,即是 /root 的上层目录的意思;
[root@study /]# cd - # 表示回到刚刚的那个目录,也就是 /root
[root@study ~]# cd /var/spool/mail # 这个就是绝对路径的写法!直接指定要去的完整路径名称
[root@study mail]# cd ../postfix # 这个是相对路径的写法,由/var/spool/mail 到/var/spool/postfix
1.1.2 pwd (Print Working Directory,显示目前所在的目录)
[root@study ~]# pwd [-P] 选项与参数: -P :显示出真实路径,而非使用链接 (link) 路径。 范例:单纯显示出目前的工作目录: [root@study ~]# pwd /root <== 显示出目录啦~ 范例:显示出实际的工作目录,而非链接文件本身的目录名而已 [root@study ~]# cd /var/mail <==注意,/var/mail是一个链接文件
[root@study mail]# pwd /var/mail <==列出目前的工作目录 [root@study mail]# pwd -P /var/spool/mail <==和没有加 -P 差很多~
[root@study mail]# ls -ld /var/mail lrwxrwxrwx. 1 root root 10 May 4 17:51 /var/mail -> spool/mail # 看到这里应该知道为啥了吧?因为 /var/mail 是链接文件,链接到 /var/spool/mail # 所以,加上 pwd -P 的选项后,会不以链接文件的数据显示,而是显示正确的完整路径
1.1.3 mkdir (make directory,创建新目录)
[root@study ~]# mkdir [-mp] 目录名称 选项与参数: -m :设置文件的权限喔!直接设置,不需要看默认权限 (umask) -p :将所需要的目录(包含上层目录)递归创建 范例:在/tmp下面尝试创建数个新目录: [root@study ~]# cd /tmp
[root@study tmp]# mkdir test <==创建一名为 test 的新目录
[root@study tmp]# mkdir test1/test2/test3/test4 mkdir: cannot create directory ‘test1/test2/test3/test4’: No such file or directory # 失败
[root@study tmp]# mkdir -p test1/test2/test3/test4 # 原来是要建 test4 上层没先建 test3 之故!加了这个 -p 的选项,可以自行帮你创建多层目录! 范例:创建权限为rwx--x--x的目录 [root@study tmp]# mkdir -m 711 test2
[root@study tmp]# ls -ld test* drwxr-xr-x. 2 root root 6 Jun 4 19:03 test drwxr-xr-x. 3 root root 18 Jun 4 19:04 test1 drwx--x--x. 2 root root 6 Jun 4 19:05 test2 # 仔细看上面的权限部分,如果没有加上 -m 来强制设置属性,系统会使用默认属性。
1.1.4 rmdir (remove directory,删除“空”的目录)
[root@study ~]# rmdir [-p] 目录名称 选项与参数: -p :连同“上层”“空的”目录也一起删除 范例:将于mkdir范例中创建的目录(/tmp下面)删除掉 [root@study tmp]# ls -ld test* <==看看有多少目录存在? drwxr-xr-x. 2 root root 6 Jun 4 19:03 test drwxr-xr-x. 3 root root 18 Jun 4 19:04 test1 drwx--x--x. 2 root root 6 Jun 4 19:05 test2 [root@study tmp]# rmdir test <==可直接删除掉,没问题
[root@study tmp]# rmdir test1 <==因为有内容,所以无法删除! rmdir: failed to remove ‘test1’: Directory not empty
[root@study tmp]# rmdir -p test1/test2/test3/test4
[root@study tmp]# ls -ld test* <==下面的输出中test与test1不见了 drwx--x--x. 2 root root 6 Jun 4 19:05 test2 # 利用 -p 这个选项,立刻就可以将 test1/test2/test3/test4 一次删除~ # 不过要注意的是,这个 rmdir 仅能“删除空的目录”,如果想连内容一块删掉则需要 rm 命令
1.1.5 可执行文件路径的变量: $PATH
经过前一章FHS的说明后,我们知道查阅文件属性的指令ls完整文件名为:/bin/ls(这是绝对路径), 那你会不会觉得很奇怪:“为什么我可以在任何地方执行/bin/ls这个指令呢? ” 为什么我在任何目录下输入 ls 就一定可以显示出一些信息而不会说找不到该 /bin/ls 指令呢? 这是因为环境变量 PATH 的帮助所致。
当我们在执行一个指令的时候,举例来说“ls”好了,系统会依照PATH的设置去每个PATH定义的目录下搜寻文件名为 ls 的可执行文件, 如果在PATH定义的目录中含有多个文件名为 ls 的可执行文件,那么先搜寻到的同名指令先被执行。
范例:用root的身份列出路径 [root@study ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin 范例:用dmtsai的身份列出路径 [dmtsai@study ~]$ echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin # 记不记得前一章说过,目前 /bin 是链接到 /usr/bin 当中的 # echo有“显示、印出”的意思,而 PATH 前面加的 $ 表示后面接的是变量,所以会显示出目前的 PATH
PATH(一定是大写)这个变量的内容是由一堆目录所组成的,每个目录中间用冒号(:)来隔开, 每个目录是有“顺序”之分的。仔细看一下上面的输出,你可以发现到无论是root还是dmtsai都有 /bin 或 /usr/bin 这个目录在PATH变量内,所以当然就能够在任何地方执行ls来找到/bin/ls可执行文件。因为 /bin 在 CentOS 7 当中,就是链接到 /usr/bin 去的,所以这两个目录内容会一模一样。
- 不同身份使用者默认的PATH不同,默认能够随意执行的指令也不同(如root与dmtsai);
- PATH是可以修改的;
- 使用绝对路径或相对路径直接指定某个指令的文件名来执行,会比搜寻PATH来的正确;
- 指令应该要放置到正确的目录下,执行才会比较方便;
- 本目录(.)最好不要放到PATH当中
1.2 文件与目录管理
1.2.1 文件与目录的查看: ls
[root@ ~]# ls [-aAdfFhilnrRSt] 文件名或目录名称.. [root@ ~]# ls [--color={never,auto,always}] 文件名或目录名称.. [root@ ~]# ls [--full-time] 文件名或目录名称.. 选项与参数: -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)
当只有 ls 时,默认显示的只有:非隐藏文件的文件名、 以文件名进行排序及文件名代表的颜色。
1.2.2 复制、删除与移动: cp, rm, mv
cp (copy,复制文件或目录)
[root@ ~]# cp [-adfilprsu] 源文件(source) 目标文件(destination) [root@ ~]# cp [options] source1 source2 source3 .... directory 选项与参数: -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 等也复制了。 最后需要注意的,如果来源文件有两个以上,则最后一个目的文件一定要是“目录”才行!
cp 这个指令的用途很多, 除了单纯的复制之外,还可以创建链接文件 ,比对两文件的新旧而予以更新, 以及复制整个目录等等的功能。
一般来说,如果我们去复制别人的数据 (当然,该文件你必须要有 read 的权限才行啊! ^_^) 时, 总是希望复制到的数据最后是我们自己的,所以,在默认的条件中, cp 的来源文件与目的文件的权限是不同的,目的文件的拥有者通常会是指令操作者本身。
由于具有这个特性,因此当我们在进行备份的时候,某些需要特别注意的特殊权限文件, 例如密码文件(/etc/shadow) 以及一些配置文件,就不能直接以 cp 来复制,而必须要加上 -a 或者是 -p 等等可以完整复制文件权限的选项才行!另外,如果你想要复制文件给其他的使用者, 也必须要注意到文件的权限(包含读、写、执行以及文件拥有者等等)。 否则,其他人还是无法针对你给的文件进行修改。
范例一:用root身份,将主文件夹下的 .bashrc 复制到 /tmp 下,并更名为 bashrc
[root@study ~]# cp ~/.bashrc /tmp/bashrc
[root@study ~]# cp -i ~/.bashrc /tmp/bashrc
cp: overwrite `/tmp/bashrc'? n <==n不覆盖,y为覆盖
# 重复作两次动作,由于 /tmp 下面已经存在 bashrc 了,加上 -i 选项后,
# 则在覆盖前会询问使用者是否确定!可以按下 n 或者 y 来二次确认呢!
范例二:变换目录到/tmp,并将/var/log/wtmp复制到/tmp且观察属性: [root@study ~]# cd /tmp [root@study tmp]# cp /var/log/wtmp . <==想要复制到目前的目录,最后的 . 不要忘 [root@study tmp]# ls -l /var/log/wtmp wtmp -rw-rw-r--. 1 root utmp 28416 Jun 11 18:56 /var/log/wtmp -rw-r--r--. 1 root root 28416 Jun 11 19:01 wtmp # 注意上面的特殊字体,在不加任何选项的情况下,文件的某些属性/权限会改变; # 这是个很重要的特性!要注意!还有,连文件创建的时间也不一样了! # 那如果你想要将文件的所有特性都一起复制过来该怎办?可以加上 -a !如下所示: [root@study tmp]# cp -a /var/log/wtmp wtmp_2 [root@study tmp]# ls -l /var/log/wtmp wtmp_2 -rw-rw-r--. 1 root utmp 28416 Jun 11 18:56 /var/log/wtmp -rw-rw-r--. 1 root utmp 28416 Jun 11 18:56 wtmp_2
范例三:复制 /etc/ 这个目录下的所有内容到 /tmp 下面 [root@study tmp]# cp /etc/ /tmp cp: omitting directory `/etc' <== 如果是目录则不能直接复制,要加上 -r 的选项 [root@study tmp]# cp -r /etc/ /tmp # 还是要再次的强调! -r 是可以复制目录,但是,文件与目录的权限可能会被改变 # 所以,也可以利用“ cp -a /etc /tmp ”来下达指令!尤其是在备份的情况下!
范例四:将范例一复制的 bashrc 创建一个链接文件 (symbolic link) [root@study tmp]# ls -l bashrc -rw-r--r--. 1 root root 176 Jun 11 19:01 bashrc <==先观察一下文件情况
[root@study tmp]# cp -s bashrc bashrc_slink [root@study tmp]# cp -l bashrc bashrc_hlink [root@study tmp]# ls -l bashrc* -rw-r--r--. 2 root root 176 Jun 11 19:01 bashrc <==与原始文件不太一样了! -rw-r--r--. 2 root root 176 Jun 11 19:01 bashrc_hlink lrwxrwxrwx. 1 root root 6 Jun 11 19:06 bashrc_slink -> bashrc
在范例四中,使用 -l 及 -s 都会创建所谓的链接文件(link file),但是这两种链接文件却有不一样的情况。 那个 -l 就是所谓的硬链接(hard link),bashrc_hlink文件与bashrc的属性与权限完全一模一样,与尚未进行链接前的差异则是第二栏的link数由1变成2了。
至于 -s 则是符号链接(symbolic link), 简单来说,bashrc_slink 是一个“快捷方式”,这个快捷方式会链接到bashrc去!所以你会看到文件名右侧会有个指向(->)的符号。
范例五:若 ~/.bashrc 比 /tmp/bashrc 新才复制过来 [root@study tmp]# cp -u ~/.bashrc /tmp/bashrc # 这个 -u 的特性,是在目标文件与来源文件有差异时,才会复制的。 # 所以,比较常被用于“备份”的工作当中! ^_^ 范例六:将范例四造成的 bashrc_slink 复制成为 bashrc_slink_1 与bashrc_slink_2 [root@study tmp]# cp bashrc_slink bashrc_slink_1 [root@study tmp]# cp -d bashrc_slink bashrc_slink_2
[root@study tmp]# ls -l bashrc bashrc_slink* -rw-r--r--. 2 root root 176 Jun 11 19:01 bashrc lrwxrwxrwx. 1 root root 6 Jun 11 19:06 bashrc_slink -> bashrc -rw-r--r--. 1 root root 176 Jun 11 19:09 bashrc_slink_1 <==与原始文件相同 lrwxrwxrwx. 1 root root 6 Jun 11 19:10 bashrc_slink_2 -> bashrc <==是链接文件! # 这个例子也是很有趣,原本复制的是链接文件,但是却将链接文件的实际文件复制过来了 # 也就是说,如果没有加上任何选项时,cp复制的是原始文件,而非链接文件的属性! # 若要复制链接文件的属性,就得要使用 -d 的选项了!如 bashrc_slink_2 所示。 范例七:将主文件夹的 .bashrc 及 .bash_history 复制到 /tmp 下面 [root@study tmp]# cp ~/.bashrc ~/.bash_history /tmp # 可以将多个数据一次复制到同一个目录去!最后面一定是目录!
例题:
能否使用 dmtsai 的身份,完整的复制/var/log/wtmp文件到/tmp下面,并更名为dmtsai_wtmp呢?[dmtsai@study ~]$ cp -a /var/log/wtmp /tmp/dmtsai_wtmp [dmtsai@study ~]$ ls -l /var/log/wtmp /tmp/dmtsai_wtmp -rw-rw-r--. 1 root utmp 28416 6月 11 18:56 /var/log/wtmp -rw-rw-r--. 1 dmtsai dmtsai 28416 6月 11 18:56 /tmp/dmtsai_wtmp由于 dmtsai 的身份并不能随意修改文件的拥有者与群组,因此虽然能够复制wtmp的相关权限与时间等属性, 但是与拥有者、群组相关的,原本 dmtsai 身份无法进行的动作,即使加上 -a 选项,也是无法达成完整复制权限的。
总之,由于 cp 有种种的文件属性与权限的特性,所以,在复制时,必须要清楚的了解到:
- 是否需要完整的保留源文件的信息?
- 源文件是否为链接文件 (symbolic link file)?
- 源文件是否为特殊的文件,例如 FIFO, socket 等?
- 源文件是否为目录?
rm (remove,移除文件或目录)
[root@study ~]# rm [-fir] 文件或目录 选项与参数: -f :就是 force 的意思,忽略不存在的文件,不会出现警告讯息; -i :互动模式,在删除前会询问使用者是否执行 -r :递归删除,最常用在目录的删除,这是非常危险的选项!!!
要注意的是,通常在Linux系统下,为了怕文件被 root 误删,所以很多 distributions 都已经默认加入 -i 这个选项了!而如果要连目录下的东西都一起删除掉的话, 例如子目录里面还有子目录时,那就要使用 -r 这个选项了。不过,使用“ rm -r ”这个指令之前,请千万注意了,当该目录或文件被删除时,系统不会再次询问你是否要删除!
范例一:通过万用字符*的帮忙,将/tmp下面开头为bashrc的文件名通通删除: [root@study tmp]# rm -i bashrc* # 注意那个星号,代表的是 0 到无穷多个任意字符 范例二:将 cp 范例中所创建的 /tmp/etc/ 这个目录删除 [root@study tmp]# rmdir /tmp/etc rmdir: failed to remove '/tmp/etc': Directory not empty <== 删不掉啊!因为这不是空的目录
[root@study tmp]# rm -r /tmp/etc rm: descend into directory `/tmp/etc'? y rm: remove regular file `/tmp/etc/fstab'? y rm: remove regular empty file `/tmp/etc/crypttab'? ^C <== 按下 [crtl]+c 中断 .....(中间省略)..... # 因为身份是 root ,默认已经加入了 -i 的选项,所以你要一直按 y 才会删除! # 如果不想要继续按 y ,可以按下“ [ctrl]-c ”来结束 rm 的工作。 # 这是一种保护的动作,如果确定要删除掉此目录而不要询问,可以这样做:
[root@study tmp]# \rm -r /tmp/etc # 在指令前加上反斜线,可以忽略掉 alias 的指定选项。至于 alias 我们在bash再谈 范例三:删除一个带有 - 开头的文件 [root@study tmp]# touch ./-aaa- <==touch这个指令可以创建空文件
[root@study tmp]# ls -l -rw-r--r--. 1 root root 0 Jun 11 19:22 -aaa- <==文件大小为0,所以是空文件
[root@study tmp]# rm -aaa- rm: invalid option -- 'a' <== 因为 "-" 是选项嘛!所以系统误判了! Try 'rm ./-aaa-' to remove the file `-aaa-'. <== 新的 bash 有给建议的 Try 'rm --help' for more information.
[root@study tmp]# rm ./-aaa-
#只能用避过首位字符是 "-" 的方法,就是加上本目录“ ./ ”即可!如果 man rm 的话,其实还有一种方法,那就是“ rm -- -aaa- ”也可以
mv (move,移动文件与目录,或更名)
[root@study ~]# mv [-fiu] source destination [root@study ~]# mv [options] source1 source2 source3 .... directory 选项与参数: -f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖; -i :若目标文件 (destination) 已经存在时,就会询问是否覆盖; -u :若目标文件已经存在,且 source 比较新,才会更新 (update)
当要移动文件或目录的时,这个指令就很重要。同样的,也可以使用 -u ( update )来比较新旧文件,看看是否需要更新。另外一个用途就是“变更文件名”,在 Linux 指令当中,还有个 rename , 可以用来更改大量文件的文件名。
范例一:复制一文件,创建一目录,将文件移动到目录中 [root@study ~]# cd /tmp [root@study tmp]# cp ~/.bashrc bashrc [root@study tmp]# mkdir mvtest [root@study tmp]# mv bashrc mvtest 范例二:将刚刚的目录名称更名为 mvtest2 [root@study tmp]# mv mvtest mvtest2 # 其实在 Linux 下面还有个有趣的指令,名称为 rename , # 该指令专职进行多个文件名的同时更名,并非针对单一文件名变更 范例三:再创建两个文件,再全部移动到 /tmp/mvtest2 当中 [root@study tmp]# cp ~/.bashrc bashrc1 [root@study tmp]# cp ~/.bashrc bashrc2 [root@study tmp]# mv bashrc1 bashrc2 mvtest2 # 注意到这边,如果有多个源文件或目录,则最后一个目标文件一定是“目录!” # 意思是说,将所有的数据移动到该目录的意思
1.2.3 查看路径的文件名称与目录名称
每个文件的完整文件名包含了前面的目录与最终的文件名,而每个文件名的长度都可以到达 255 个字符, 有时无法知道哪个是文件名,哪个是目录名。一种方式是利用斜线 / 来分辨;另一种是 basename 与 dirname 。
[root@study ~]# basename /etc/sysconfig/network network <== 取得文件名~ [root@study ~]# dirname /etc/sysconfig/network /etc/sysconfig <== 取得目录名
2. 文件内容查阅
先看指令:
- cat 由第一行开始显示文件内容
- tac 从最后一行开始显示,可以看出 tac 是 cat 的倒着写!
- nl 显示的时候,顺道输出行号!
- more 一页一页的显示文件内容
- less 与 more 类似,但是比 more 更好的是,他可以往前翻页!
- head 只看头几行
- tail 只看最后几行
- od 以二进制的方式读取文件内容!
2.1 直接查看文件
cat (concatenate)
# cat [-AbEnTv] 选项与参数: -A :相当于 -vET 的整合选项,可列出一些特殊字符而不是空白而已; -b :列出行号,仅针对非空白行做行号显示,空白行不标行号! -E :将结尾的断行字符 $ 显示出来; -n :打印出行号,连同空白行也会有行号,与 -b 的选项不同; -T :将 [tab] 按键以 ^I 显示出来; -v :列出一些看不出来的特殊字符
tac (反向显示)
由最后一行到第一行反向在屏幕上显示出来 。
nl (添加行号打印)
# nl [-bnw] 文件 选项与参数: -b :指定行号指定的方式,主要有两种: -b a :表示不论是否为空行,也同样列出行号(类似 cat -n); -b t :如果有空行,空的那一行不要列出行号(默认值); -n :列出行号表示的方法,主要有三种: -n ln :行号在屏幕的最左方显示; -n rn :行号在自己字段的最右方显示,且不加 0 ; -n rz :行号在自己字段的最右方显示,且加 0 ; -w :行号字段的占用的字符数。
nl 可以将输出的文件内容自动的加上行号!其默认的结果与 cat -n 有点不太一样, nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 等等的功能。
范例一:用 nl 列出 /etc/issue 的内容 [root@study ~]# nl /etc/issue 1 \S 2 Kernel \r on an \m # 注意看,这个文件其实有三行,第三行为空白(没有任何字符), # 因为他是空白行,所以 nl 不会加上行号喔!如果确定要加上行号,可以这样做: [root@study ~]# nl -b a /etc/issue 1 \S 2 Kernel \r on an \m 3 # 行号加上了,那么如果要让行号前面自动补上 0 呢?可这样
[root@study ~]# nl -b a -n rz /etc/issue 000001 \S 000002 Kernel \r on an \m 000003 # 自动在自己字段的地方补上 0 了~默认字段是六位数,如果想要改成 3 位数? [root@study ~]# nl -b a -n rz -w 3 /etc/issue 001 \S 002 Kernel \r on an \m 003 # 变成仅有 3 位数
2.2 翻页查看文件
more (一页一页翻动)
[root@study ~]# more /etc/man_db.conf # # # This file is used by the man-db package to configure the man and cat paths. # It is also used to provide a manpath for those without one by examining # their PATH environment variable. For details see the manpath(5) man page. # .....(中间省略)..... --More--(28%) <== 重点在这一行,光标也会在这里等待你的指令
如果 more 后面接的文件内容行数大于屏幕输出的行数时, 就会出现类似上面的提示。重点在最后一行,最后一行会显示出目前显示的百分比, 而且还可以在最后一行输入一些有用的指令。在 more 这个程序的运行过程中,你有几个按键可以按的:
- 空格键 (space):代表向下翻一页;
- Enter :代表向下翻“一行”;
- / 字串 :代表在这个显示的内容当中,向下搜寻“字串”这个关键字;
- :f :立刻显示出文件名以及目前显示的行数;
- q :代表立刻离开 more ,不再显示该文件内容。
- b 或 [ctrl]-b :代表往回翻页,不过这动作只对文件有用,对管道无用。
范例:在该文件内搜寻 MANPATH 这个字串 [root@study ~]# more /etc/man_db.conf # # # This file is used by the man-db package to configure the man and cat paths. # It is also used to provide a manpath for those without one by examining # their PATH environment variable. For details see the manpath(5) man page. # ....(中间省略).... /MANPATH <== 输入了 / 之后,光标就会自动跑到最下面一行等待输入!
输入了字串并按下[enter]之后, more 就会开始向下搜寻该字串。而重复搜寻同一个字串, 可以直接按下 n 即可。最后,不想要看了,就按下 q 即可离开 more 。
less (一页一页翻动)
在 more 的时候,没有办法向前面翻, 只能往后面看,但若使用了 less 时,就可以使用 [pageup] [pagedown] 等按键的功能来往前往后翻看文件。
除此之外,在 less 里头可以拥有更多的“搜寻”功能,不止可以向下搜寻,也可以向上搜寻。基本上,可以输入的指令有:
- 空白键 :向下翻动一页;
- [pagedown]:向下翻动一页;
- [pageup] :向上翻动一页;
- /字串 :向下搜寻“字串”的功能;
- ?字串 :向上搜寻“字串”的功能;
- n :重复前一个搜寻 (与 / 或 ? 有关!)
- N :反向的重复前一个搜寻 (与 / 或 ? 有关!)
- g :前进到这个数据的第一行去;
- G :前进到这个数据的最后一行去 (注意大小写);
- q :离开 less 这个程序;
2.3 数据截取
head (取出前面几行)
[root@study ~]# head [-n number] 文件 选项与参数: -n :后面接数字,代表显示几行的意思 [root@study ~]# head /etc/man_db.conf # 默认的情况中,显示前面十行!若要显示前 20 行,就得要这样: [root@study ~]# head -n 20 /etc/man_db.conf
范例:如果后面100行的数据都不打印,只打印/etc/man_db.conf的前面几行,该如何是好?
[root@study ~]# head -n -100 /etc/man_db.conf
如果 n 后接的是负数,例如上面范例的-n -100时,代表列前的所有行数, 但不包括后面100行。
tail (取出后面几行)
[root@study ~]# tail [-n number] 文件 选项与参数: -n :后面接数字,代表显示几行的意思 -f :表示持续侦测后面所接的文件名,要等到按下[ctrl]-c才会结束tail的侦测 [root@study ~]# tail /etc/man_db.conf # 默认的情况中,显示最后的十行!若要显示最后的 20 行,就得要这样: [root@study ~]# tail -n 20 /etc/man_db.conf 范例一:如果不知道/etc/man_db.conf有几行,却只想列出100行以后的数据时? [root@study ~]# tail -n +100 /etc/man_db.conf 范例二:持续检测/var/log/messages的内容 [root@study ~]# tail -f /var/log/messages <==要等到输入[crtl]-c之后才会离开tail这个指令的侦测
当指令“tail -n +100 /etc/man_db.conf” 代表该文件从100行以后都会被列出来,例如,在man_db.conf共有131行,因此第100~131行就会被列出来啦! 前面的99行都不会被显示出来。
至于范例二中,由于/var/log/messages随时会有数据写入,想要让该文件有数据写入时就立刻显示到屏幕上, 就利用 -f 这个选项,他可以一直检测/var/log/messages这个文件,新加入的数据都会被显示到屏幕上。 直到你按下[crtl]-c才会离开。
例题:
假如我想要显示 /etc/man_db.conf 的第 11 到第 20 行呢?
答:
“ head -n 20 /etc/man_db.conf | tail -n 10 ”,这样就可以得到第 11 到第 20 行之间的内容了!这两个指令中间有个管道 | 的符号存在,这个的意思是:前面的指令所输出的信息,再通过管道交给后续的指令继续处理。
承上一题,那如果我想要列出正确的行号呢?就是屏幕上仅列出 /etc/man_db.conf 的第 11 到第 20 行,且有行号存在?
答:
可以通过 cat -n 来带出行号,然后再通过 head/tail 来截取数据即可,如下:
cat -n /etc/man_db.conf | head -n 20 | tail -n 10
2.4 非纯文本文件: od
上面提到的,都是在查阅纯文本文件的内容。那么万一我们想要查阅非文本文件,举例来说,查看 /usr/bin/passwd 这个可执行文件的内容时, 由于可执行文件通常是二进制文件,使用上面提到的指令来读取文件内容时, 会显示类似乱码的数据。这时我们可以利用 od 这个指令来读取。
[root@study ~]# od [-t TYPE] 文件 选项或参数: -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 ;
范例一:请将/usr/bin/passwd的内容使用ASCII方式来展现! [root@study ~]# od -t c /usr/bin/passwd 0000000 177 E L F 002 001 001 \0 \0 \0 \0 \0 \0 \0 \0 \0 0000020 003 \0 > \0 001 \0 \0 \0 364 3 \0 \0 \0 \0 \0 \0 0000040 @ \0 \0 \0 \0 \0 \0 \0 x e \0 \0 \0 \0 \0 \0 0000060 \0 \0 \0 \0 @ \0 8 \0 \t \0 @ \0 035 \0 034 \0 0000100 006 \0 \0 \0 005 \0 \0 \0 @ \0 \0 \0 \0 \0 \0 \0 .....(后面省略).... # 最左边第一行第一列是以 8 进位来表示Bytes数。以上面范例来说,第二行第一列0000020代表开头是第16个 byes(2x8)的内容之意。 范例二:请将/etc/issue这个文件的内容以8进制列出储存值与ASCII的对照表 [root@study ~]# od -t oCc /etc/issue 0000000 134 123 012 113 145 162 156 145 154 040 134 162 040 157 156 040 \ S \n K e r n e l \ r o n 0000020 141 156 040 134 155 012 012 a n \ m \n \n 0000027 # 如上所示,可以发现每个字符可以对应到的数值,要注意的是,该数值是 8 进制 # 例如 S 对应的记录数值为 123 ,转成十进制:1x8^2+2x8+3=83。
例题:
如何通过 od 找到 password 这几个字的 ASCII 表对照?
答:
echo password | od -t oCc
echo 可以在屏幕上面显示任何信息,而这个信息不由屏幕输出,而是传给 od 去继续处理!就可以得到 ASCII code 对照了。
2.5 修改文件时间或创建新文件: touch
在linux下,每个文件都会记录许多的时间参数, 其实是有三个主要的变动时间,那么三个时间的意义是
- modification time (mtime):
当该文件的“内容数据”变更时,就会更新这个时间!内容数据指的是文件的内容,而不是文件的属性或权限。
- status time (ctime):
当该文件的“状态 (status)”改变时,就会更新这个时间,举例来说,像是权限与属性被更改了,都会更新这个时间。
- access time (atime):
当该文件的内容被读取时,就会更新这个读取时间 (access)。举例来说,我们使用 cat 去读取 /etc/man_db.conf , 就会更新该文件的 atime 。
范例:显示文件的三个时间
[root@study ~]# date; ls -l /etc/man_db.conf ; ls -l --time=atime /etc/man_db.conf ; \ > ls -l --time=ctime /etc/man_db.conf # 这两行其实是同一行喔!用分号隔开
Tue Jun 16 00:43:17 CST 2015 # 目前的时间 -rw-r--r--. 1 root root 5171 Jun 10 2014 /etc/man_db.conf # 在 2014/06/10 创建的内容(mtime) -rw-r--r--. 1 root root 5171 Jun 15 23:46 /etc/man_db.conf # 在 2015/06/15 读取过内容(atime) -rw-r--r--. 1 root root 5171 May 4 17:54 /etc/man_db.conf # 在 2015/05/04 更新过状态(ctime) # 将三个指令同时依序执行,三个指令中间用分号 (;) 隔开即可
在默认的情况下,ls 显示出来的是该文件的 mtime ,也就是这个文件的内容上次被更动的时间。
使用 touch 可以修改时间。
[root@study ~]# touch [-acdmt] 文件 选项与参数: -a :仅修订 access time; -c :仅修改文件的时间,若该文件不存在则不创建新文件; -d :后面可以接欲修订的日期而不用目前的日期,也可以使用 --date="日期或时间" -m :仅修改 mtime ; -t :后面可以接欲修订的时间而不用目前的时间,格式为[YYYYMMDDhhmm]
范例一:新建一个空的文件并观察时间 [dmtsai@study ~]# cd /tmp [dmtsai@study tmp]# touch testtouch [dmtsai@study tmp]# ls -l testtouch -rw-rw-r--. 1 dmtsai dmtsai 0 Jun 16 00:45 testtouch # 注意到,这个文件的大小是 0 范例四:将 bashrc 日期改为 2014/06/15 2:02 [dmtsai@study tmp]# touch -t 201406150202 bashrc [dmtsai@study tmp]# date; ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc Tue Jun 16 00:54:07 CST 2015 -rw-r--r--. 1 dmtsai dmtsai 231 Jun 15 2014 bashrc -rw-r--r--. 1 dmtsai dmtsai 231 Jun 15 2014 bashrc -rw-r--r--. 1 dmtsai dmtsai 231 Jun 16 00:54 bashrc # 注意,日期在 atime 与 mtime 都改变了,但是 ctime 则是记录目前的时间!
要注意的是,即使我们复制一个文件时,复制所有的属性,但也没有办法复制 ctime 这个属性的。
“ll” 这个指令(两个英文L的小写),这个指令其实就是“ls -l”的意思, ll 本身不存在,是被“做出来”的一个命令别名。
3. 文件与目录的默认权限与隐藏权限
除了基本r, w, x权限外,在Linux传统的Ext2/Ext3/Ext4文件系统下,我们还可以设置其他的系统隐藏属性, 这部份可使用 chattr 来设置,而以 lsattr 来查看,最重要的属性就是可以设置其不可修改的特性!让连文件的拥有者都不能进行修改! 这个属性可是相当重要的,尤其是在安全机制上面 (security)!在 CentOS 7.x 当中利用 xfs 作为默认文件系统, 但是 xfs 就没有支持所有的 chattr 的参数了,仅有支持部分参数。
3.1 文件默认权限:umask
umask 就是指定 当前使用者在创建文件或目录时候的权限默认值。
[root@study ~]# umask 0022 <==与一般权限有关的是后面三个数字! [root@study ~]# umask -S u=rwx,g=rx,o=rx
查阅的方式有两种,一种可以直接输入 umask ,就可以看到数字的权限设置, 一种则是加入 -S (Symbolic) 这个选项,就会以符号类型的方式来显示出权限。奇怪的是,怎么 umask 会有四个数字啊?不是只有三个吗?第一个数字是特殊权限用的。
要注意的是,umask 的分数指的是“该默认值需要减掉的权限, r、w、x 分别是 4、2、1 分。以上面的例子来说明的话,因为 umask 为 022 ,所以 user 并没有被拿掉任何权限,不过 group 与 others 的权限被拿掉了 2 (也就是 w 这个权限)。
在默认权限的属性上,目录与文件是不一样的。我们知道 x 权限对于目录是非常重要的,但是一般文件的创建则不应该有执行的权限,因为一般文件通常是用在于数据的记录,当然不需要执行的权限了。 因此,默认的情况如下:
- 若使用者创建为“文件”则默认“没有可执行( x )权限”,亦即只有 rw 这两个项目,也就是最大为 666 分,默认权限如下:
-rw-rw-rw-
- 若使用者创建为“目录”,则由于 x 与是否可以进入此目录有关,因此默认为所有权限均开放,亦即为 777 分,默认权限如下:
drwxrwxrwx
如何设置 umask,直接在 umask 后面输入数字(例如 002)就好了。
例题:
假设你的 umask 为 003 ,请问该 umask 情况下,创建的文件与目录权限为?
答:
umask 为 003 ,所以拿掉的权限为 --------wx,因此:
文件: (-rw-rw-rw-) - (--------wx) = -rw-rw-r--
目录: (drwxrwxrwx) - (d-------wx) = drwxrwxr--
在默认的情况中, root 的 umask 会拿掉比较多的属性,root 的 umask 默认是 022 , 这是基于安全的考虑。至于一般身份使用者,通常他们的 umask 为 002 ,亦即保留同群组的写入权力。其实,关于默认 umask 的设置可以参考 /etc/bashrc 这个文件的内容,不过,不建议修改该文件。
3.2 文件隐藏属性
要先强调的是,下面的chattr指令只能在Ext2/Ext3/Ext4的 Linux 传统文件系统上面完整生效, 其他的文件系统可能就无法完整的支持这个指令了,例如 xfs 仅支持部份参数。
chattr (设置文件隐藏属性)
[root@study ~]# chattr [+-=][ASacdistu] 文件或目录名称 选项与参数: + :增加某一个特殊参数,其他原本存在参数则不动。 - :移除某一个特殊参数,其他原本存在参数则不动。 = :设置一定,且仅有后面接的参数 A :当设置了 A 这个属性时,若你有存取此文件(或目录)时,他的存取时间 atime 将不会被修改, 可避免 I/O 较慢的机器过度的存取磁盘。(目前建议使用文件系统挂载参数处理这个项目) S :一般文件是非同步写入磁盘的(原理请参考前一章sync的说明),如果加上 S 这个属性时, 当你进行任何文件的修改,该更动会“同步”写入磁盘中。 a :当设置 a 之后,这个文件将只能增加数据,而不能删除也不能修改数据,只有root 才能设置这属性 c :这个属性设置之后,将会自动的将此文件“压缩”,在读取的时候将会自动解压缩, 但是在储存的时候,将会先进行压缩后再储存(看来对于大文件似乎蛮有用的!) d :当 dump 程序被执行的时候,设置 d 属性将可使该文件(或目录)不会被 dump 备份 i :这个 i 可就很厉害了!他可以让一个文件“不能被删除、改名、设置链接也无法写入或新增数据!” 对于系统安全性有相当大的助益!只有 root 能设置此属性 s :当文件设置了 s 属性时,如果这个文件被删除,他将会被完全的移除出这个硬盘空间, 所以如果误删了,完全无法救回来了喔! u :与 s 相反的,当使用 u 来设置文件时,如果该文件被删除了,则数据内容其实还存在磁盘中, 可以使用来恢复该文件! 注意1:属性设置常见的是 a 与 i 的设置值,而且很多设置值必须要身为 root 才能设置 注意2:xfs 文件系统仅支持 AadiS 而已
lsattr (显示文件隐藏属性)
[root@study ~]# lsattr [-adR] 文件或目录 选项与参数: -a :将隐藏文件的属性也秀出来; -d :如果接的是目录,仅列出目录本身的属性而非目录内的文件名; -R :连同子目录的数据也一并列出来! 范例: [root@study tmp]# chattr +aiS attrtest [root@study tmp]# lsattr attrtest --S-ia---------- attrtes
3.3 文件特殊权限: SUID, SGID, SBIT
[root@study ~]# ls -ld /tmp ; ls -l /usr/bin/passwd drwxrwxrwt. 14 root root 4096 Jun 16 01:27 /tmp -rwsr-xr-x. 1 root root 27832 Jun 10 2014 /usr/bin/passwd
不是应该只有 rwx 吗?还有其他的特殊权限( s 跟 t )啊? 这是因为 s 与 t 这两个权限的意义与系统的帐号 及系统的程序(process)较为相关。
Set UID
当 s 这个标志出现在文件拥有者的 x 权限上时,例如刚刚提到的 /usr/bin/passwd 这个文件的权限状态:“-rwsr-xr-x”,此时就被称为 Set UID,简称为 SUID 的特殊权限。 那么SUID的权限对于一个文件的特殊功能是什么呢?基本上SUID有这样的限制与功能:
- SUID 权限仅对二进制程序(binary program)有效;
- 执行者对于该程序需要具有 x 的可执行权限;
- 本权限仅在执行该程序的过程中有效 (run-time);
- 执行者将具有该程序拥有者 (owner) 的权限。
举个例子来说明好了。 我们的 Linux 系统中,所有帐号的密码都记录在 /etc/shadow 这个文件里面,这个文件的权限为:“---------- 1 root root”,意思是这个文件仅有root可读且仅有root可以强制写入而已。 既然这个文件仅有 root 可以修改,那么个人的 dmtsai 这个一般帐号使用者能否自行修改自己的密码呢? 你可以使用你自己的帐号输入“passwd”这个指令来看看,嘿嘿!一般使用者当然可以修改自己的密码了!
有冲突啊!明明 /etc/shadow 就不能让 dmtsai 这个一般帐户去存取的,为什么 dmtsai 还能够修改这个文件内的密码呢? 这就是 SUID 的功能啦!借由上述的功能说明,我们可以知道
- dmtsai 对于 /usr/bin/passwd 这个程序来说是具有 x 权限的,表示 dmtsai 能执行 passwd;
- passwd 的拥有者是 root 这个帐号;
- dmtsai 执行 passwd 的过程中,会“暂时”获得 root 的权限;
- /etc/shadow 就可以被 dmtsai 所执行的 passwd 所修改。
但如果 dmtsai 使用 cat 去读取 /etc/shadow 时,他能够读取吗?因为 cat 不具有 SUID 的权限,所以 dmtsai 执行 “cat /etc/shadow” 时,是不能读取 /etc/shadow 的。我们用一张示意图来说明如下:
另外,SUID 仅可用在二进制程序上, 不能够用在 shell 脚本上面!这是因为 shell script 只是将很多的二进制可执行文件调用执行而已!所以 SUID 的权限部分,还是得要看 shell 脚本调用进来的程序的设置, 而不是 shell 脚本本身。当然,SUID 对于目录也是无效的~这点要特别留意。
Set GID
当 s 标志在文件拥有者的 x 项为 SUID,那 s 在群组的 x 时则称为 Set GID(SGID)。
[root@study ~]# ls -l /usr/bin/locate -rwx--s--x. 1 root slocate 40496 Jun 10 2014 /usr/bin/locate
与 SUID 不同的是,SGID 可以针对文件或目录来设置!如果是对文件来说, SGID 有如下的功能:
- SGID 对二进制程序有用;
- 程序执行者对于该程序来说,需具备 x 的权限;
- 执行者在执行的过程中将会获得该程序群组的支持!
举例来说, /usr/bin/locate 这个程序可以去搜寻 /var/lib/mlocate/mlocate.db 这个文件的内容 , mlocate.db 的权限如下:
[root@study ~]# ll /usr/bin/locate /var/lib/mlocate/mlocate.db -rwx--s--x. 1 root slocate 40496 Jun 10 2014 /usr/bin/locate -rw-r-----. 1 root slocate 2349055 Jun 15 03:44 /var/lib/mlocate/mlocate.db
与 SUID 非常的类似,若我使用 dmtsai 这个帐号去执行 locate 时,那 dmtsai 将会取得 slocate 群组的支持, 因此就能够去读取 mlocate.db 。
除了二进制程序之外,事实上 SGID 也能够用在目录上,这也是非常常见的一种用途! 当一个目录设置了 SGID 的权限后,他将具有如下的功能:
- 使用者若对于此目录具有 r 与 x 的权限时,该使用者能够进入此目录;
- 使用者在此目录下的有效群组(effective group)将会变成该目录的群组;
- 用途:若使用者在此目录下具有 w 的权限(可以新建文件),则使用者所创建的新文件,该新文件的群组与此目录的群组相同。
Sticky Bit
这个 Sticky Bit, SBIT 目前只针对目录有效,对于文件已经没有效果了。SBIT 对于目录的作用是:
- 当使用者对于此目录具有 w, x 权限,亦即具有写入的权限时;
- 当使用者在该目录下创建文件或目录时,仅有自己与 root 才有权力删除该文件
举例来说, /tmp 本身的权限是“drwxrwxrwt”, 在这样的权限内容下,任何人都可以在 /tmp 内新增、修改文件,但仅有该文件/目录创建者与 root 能够删除自己的目录或文件。
SUID/SGID/SBIT 权限设置
数字体态更改权限的方式为“三个数字”的组合, 那么如果在这三个数字之前再加上一个数字的话,最前面的那个数字就代表这几个权限了。
- 4 为 SUID
- 2 为 SGID
- 1 为 SBIT
假设要将一个文件权限改为“-rwsr-xr-x”时,由于 s 在使用者权限中,所以是 SUID ,因此, 在原先的 755 之前还要加上 4 ,也就是:“ chmod 4755 filename ”来设置。
[root@study tmp]# touch test <==创建一个测试用空档 [root@study tmp]# chmod 4755 test; ls -l test <==加入具有 SUID 的权限 -rwsr-xr-x 1 root root 0 Jun 16 02:53 test
[root@study tmp]# chmod 6755 test; ls -l test <==加入具有 SUID/SGID 的权限 -rwsr-sr-x 1 root root 0 Jun 16 02:53 test
[root@study tmp]# chmod 1755 test; ls -l test <==加入 SBIT 的功能! -rwxr-xr-t 1 root root 0 Jun 16 02:53 test
[root@study tmp]# chmod 7666 test; ls -l test <==具有空的 SUID/SGID 权限 -rwSrwSrwT 1 root root 0 Jun 16 02:53 test
最后一个例子就要特别小心,怎么会出现大写的 S 与 T 呢?不都是小写的吗? 因为 s 与 t 都是取代 x 这个权限的,但是我们是下达 7666 !也就是说, user, group 以及 others 都没有 x 这个可执行的标志( 因为 666 ),所以,这个 S, T 代表的就是“空的”啦!怎么说? SUID 是表示“该文件在执行的时候,具有文件拥有者的权限”,但是文件拥有者都无法执行了,哪里来的权限给其他人使用?当然就是空的啦! ^_^
除了数字法之外,也可以通过符号法来处理。其中 SUID 为 u+s ,而 SGID 为 g+s ,SBIT 则是 o+t 。
# 设置权限成为 -rws--x--x 的模样: [root@study tmp]# chmod u=rwxs,go=x test; ls -l test -rws--x--x 1 root root 0 Jun 16 02:53 test # 承上,加上 SGID 与 SBIT 在上述的文件权限中! [root@study tmp]# chmod g+s,o+t test; ls -l test -rws--s--t 1 root root 0 Jun 16 02:53 test
3.4 观察文件类型:file
如果你想要知道某个文件的基本数据,例如是属于 ASCII 或者是 data 文件,或者是 binary , 且其中有没有使用到动态函数库 (share library) 等等的信息,就可以利用 file 这个指令来查看,举例来说:
[root@study ~]# file ~/.bashrc /root/.bashrc: ASCII text <==告诉我们是 ASCII 的纯文本文件啊!
[root@study ~]# file /usr/bin/passwd /usr/bin/passwd: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0xbf35571e607e317bf107b9bcf65199988d0ed5ab, stripped # 可执行文件的数据可就多的不得了!包括这个文件的 suid 权限、相容于 Intel x86-64 等级的硬件平台 # 使用的是 Linux 核心 2.6.32 的动态函数库链接等等。
[root@study ~]# file /var/lib/mlocate/mlocate.db /var/lib/mlocate/mlocate.db: data <== 这是 data 文件!
4. 命令与文件的查找
4.1 脚本文件的查找
在命令行模式当中,连续输入两次 [tab] 键就能够知道用户有多少命令可以运行。 那你知不知道这些命令的完整文件名放在哪里?举例来说,ls 这个常用的命令放在哪里呢? 就通过 which 或 type 来查找。
which (查找执行文件)
[root@study ~]# which [-a] command
选项或参数:
-a :将所有由 PATH 目录中可以找到的指令均列出,而不止第一个被找到的指令名称
范例一:查找 ifconfig 这个命令的完整文件名 [root@study ~]# which ifconfig /sbin/ifconfig 范例二:用 which 去找出 which 的文件名 [root@study ~]# which which alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde' /bin/alias /usr/bin/which # 有两个 which ,其中一个是 alias ,那就是所谓的“命令别名”,意思是输入 which 会等于后面接的那串指令 范例三:请找出 history 这个命令的完整文件名 [root@study ~]# which history /usr/bin/which: no history in (/usr/local/sbin:/usr/local/bin:/sbin:/bin: /usr/sbin:/usr/bin:/root/bin) [root@study ~]# history --help -bash: history: --: invalid option history: usage: history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg # 怎么可能没有 history ,明明能够用 root 执行 history
这个命令是根据“PATH”这个环境变量所规范的路径,去查找“执行文件”的文件名,所以,重点是找出“执行文件”,且 which 后面接的是“完整文件名”。若加上 -a 选项,则可以列出所有的可以找到的同名执行文件。
最后一个范例,怎么 history 这个常用的指令竟然找不到?这是因为 history 是“bash 内置的指令”, 但是 which 默认是找 PATH 内所规范的目录,可以通过 type 这个指令查找。
4.2 文件的查找
通常 find 命令不很常用,因为速度慢之外, 也很影响硬盘性能。一般都是先使用 whereis 或者是 locate 来检查,如果真的找不到了,才以 find 来查找, 因为 whereis 只找系统中某些特定目录下面的文件,locate 则是利用数据库来查找文件名,当然两者就相当的快速, 并且没有实际的搜索硬盘内的文件系统状态,比较省时间。
whereis (由一些特定的目录中寻找文件文件名)
[root@study ~]# whereis [-bmsu] 文件或目录名 选项与参数: -l :可以列出 whereis 会去查询的几个主要目录而已 -b :只找 binary 格式的文件 -m :只找在说明文档 manual 路径下的文件 -s :只找 source 来源文件 -u :搜寻不在上述三个项目当中的其他特殊文件
whereis 主要是针对 /bin /sbin 下面的可执行文件, 以及 /usr/share/man 下面的 man page 文件。
locate / updatedb
[root@study ~]# locate [-ir] keyword 选项与参数: -i :忽略大小写的差异; -c :不输出文件名,仅计算找到的文件数量 -l :仅输出几行的意思,例如输出五行则是 -l 5 -S :输出 locate 所使用的数据库文件的相关信息,包括该数据库纪录的文件/目录数量等 -r :后面可接正则表达式的显示方式
locate 查找的数据是由“已创建的数据库 /var/lib/mlocate/” 里面的数据所查找到的。
因此就会有限制,因为他是经由数据库来查找的,而数据库的更新默认是在每天执行一次 (每个 distribution 都不同,CentOS 7.x 是每天更新数据库一次!),所以当你新创建起来的文件, 却还在数据库更新之前查找该文件,那么 locate 就会找不到。
输入“ updatedb ”就可以手动更新数据库。 updatedb 指令会去读取 /etc/updatedb.conf 这个配置文件的设置,然后再去硬盘里面进行查找文件名的动作, 最后就更新整个数据库文件,这个过程有点慢。
find
[root@study ~]# find [PATH] [option] [action] 选项与参数: 1. 与时间有关的选项:共有 -atime, -ctime 与 -mtime ,以 -mtime 说明 -mtime n :n 为数字,意义为在 n 天之前的“一天之内”被更动过内容的文件; -mtime +n :列出在 n 天之前(不含 n 天本身)被更动过内容的文件文件名; -mtime -n :列出在 n 天之内(含 n 天本身)被更动过内容的文件文件名。 -newer file :file 为一个存在的文件,列出比 file 还要新的文件文件名
范例一:将系统上面前 24 小时内有更动过内容 (mtime) 的文件列出 [root@study ~]# find / -mtime 0 # 0 代表当前的时间,所以,从现在开始到 24 小时前,有变动过内容的文件都会被列出来! # 那如果是3天前的呢: find / -mtime 3 有变动过的文件都被列出的意思! 范例二:寻找 /etc 下面的文件,如果文件日期比 /etc/passwd 新就列出 [root@study ~]# find /etc -newer /etc/passwd # -newer 用在分辨两个文件之间的新旧关系是很有用的
图中最右边为目前的时间,越往左边则代表越早之前的时间轴啦。由图中我们可以清楚的知道:
- +4代表大于等于5天前的文件名:ex> find /var -mtime +4
- -4代表小于等于4天内的文件文件名:ex> find /var -mtime -4
- 4则是代表4-5那一天的文件文件名:ex> find /var -mtime 4
选项与参数: 2. 与使用者或群组名称有关的参数: -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 搜寻。
范例三:搜寻 /home 下面属于 dmtsai 的文件 [root@study ~]# find /home -user dmtsai # 这个东西也很有用的~当我们要找出任何一个使用者在系统当中的所有文件时, # 就可以利用这个指令将属于某个使用者的所有文件都找出来 范例四:搜寻系统中不属于任何人的文件 [root@study ~]# find / -nouser
选项与参数: 3. 与文件权限及名称有关的参数: -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.... 的属性存在!
范例五:找出文件名为 passwd 这个文件 [root@study ~]# find / -name passwd 范例五-1:找出文件名包含了 passwd 这个关键字的文件 [root@study ~]# find / -name "*passwd*" # 利用这个 -name 可以搜寻文件名啊!默认是完整文件名,如果想要找关键字, # 可以使用类似 * 的任意字符来处理 范例六:找出 /run 目录下,文件类型为 Socket 的文件名有哪些? [root@study ~]# find /run -type s # 这个 -type 的属性也很有帮助喔!尤其是要找出那些怪异的文件, # 例如 socket 与 FIFO 文件,可以用 find /run -type p 或 -type s 来找! 范例七:搜寻文件当中含有 SGID 或 SUID 或 SBIT 的属性 [root@study ~]# find / -perm /7000 # 所谓的 7000 就是 ---s--s--t ,那么只要含有 s 或 t 的就列出, # 使用 -7000 表示要同时含有 ---s--s--t 的所有三个权限
[root@study ~]# find /usr/bin /usr/sbin -perm /6000
find 后面可以接多个目录来进行查找,find 就会查找目录。
选项与参数: 4. 额外可进行的动作: -exec command :command 为其他指令,-exec 后面可再接额外的指令来处理搜寻到的结果。 -print :将结果打印到屏幕上,这个动作是默认动作!
范例八:将上个范例找到的文件使用 ls -l 列出来~ [root@study ~]# find /usr/bin /usr/sbin -perm /7000 -exec ls -l {} \; # 注意到,那个 -exec 后面的 ls -l 就是额外的指令,指令不支持命令别名, # 所以仅能使用 ls -l 不可以使用 ll,注意注意! 范例九:找出系统中,大于 1MB 的文件 [root@study ~]# find / -size +1M
- {} 代表的是“由 find 找到的内容”,如上图所示,find 的结果会被放置到 {} 位置中;
- -exec 一直到 \; 是关键字,代表 find 额外动作的开始 (-exec) 到结束 (\;) ,在这中间的就是 find 指令内的额外动作。 在本例中就是“ ls -l {} ”
- 因为“ ; ”在 bash 环境下是有特殊意义的,因此利用反斜线来转义。
突然有一天假期结束,时来运转,人生才是真正开始了。