Linux 的档案与目录管理--1
目录与路径
绝对路径与相对路径
开始目录切换前,需要先了解所谓的【路径(PATH)】
- 绝对路径:路径的写法【一定由根目录/写起】,如:/usr/share/doc 这个目录。
- 相对路径:路径的写法【不是由/写起】,如:由 /usr/share/doc 要到 /usr/share/man 底下时,可以写成:【cd ../man】这就是相对路径的写法。相对路径意思是指【相对于目前工作目录的路径】。
用途:
相对路径:假如我们需要在 /usr/local/packages/etc, /usr/local/packages/bin, /usr/local/packages/man 三个目录之间进行切换的时候,相对路径就非常方便了,怎么用呢?自己试试把。
绝对路径:【绝对路径的准确度要比较好】一般来说,我们在写程序(shell scripts)来管理系统的条件下,务必使用绝对路径的写法。
目录的相关操作
特殊符号:
.
代表此层目录
..
代表上一层目录
-
代表前一个工作目录
~
代表【目前使用者身份】所在的家目录
~hare
代表 hare 这个使用者的家目录
Tips:在所有的目录底下都会存在两个目录,分别是【.】与【..】分别代表此层目录和上层目录。
常见处理目录的指令
- cd(change directory,变换目录)
cd [相对路径或绝对路径]
cd ~hare
表示去到 hare 的家目录cd ~
表示去自己的家目录cd
也表示回自己的家目录cd ..
表示到上一层目录,如果是在 / 目录下进行此操作,便还是在 / 目录下。cd -
表示回到刚刚的那个目录cd /var/spool/mail
绝对路径写法,去这个目录cd ../postfix
相对路径的写法,表示从当前目录去到上一层目录的 postfix 目录- Tips:利用相对路径的写法必须要确认你目前的路径才能正确的去到想要去的目录。
- Tips:在输入路径的时候,可以打出一两个字符后尽可能多的用 [Tab] 键的自动补全功能,这样会减少出错的机会。
- pwd(Print Working Directory,显示目前所在的目录)
pwd [-P]
-P(大P)表示需要显示真实路径,而不是链接路径。
- mkdir(make directory,建立新目录)
mkdir [-mp] 目录名称
-m 设定档案权限,无需在意预设权限(umask); -p 递归创建目录,看下面例子。mkdir -m 711 test
代表创建目录 test 并且设置权限为 711mkdir -p ./test1/test2/test3
代表一次性创建 test1、test2、test3 这3个目录,并且是2在1下面,3在2下面。- Tips:在预设的情况下,你需要的目录得一层层的建立,加上-p 就可以一次性建立多层目录,并且,如果该目录已经存在,系统也不会提示错误信息。
- rmdir(删除【空】的目录)
rmdir [-p] 目录名称
-p 连同【上层】【空的】目录也一起删除rmdir -p ./test1/test2/test3
这个操作是可以的,会直接删掉这三个目录(因为路径指向的是 test3,如果不加 -p 只会删掉 test3,所以上面说的【上层】是指是定目录的上层的意思,但是如果直接 rmdir test1 会报错,因为不是空的。- 目录需要一层层的删除才行,而且被删除的目录里面必定不能存在其他的目录或档案,也就是所谓的空目录(empty directory),如果想要将所有的指定目录下的所有东西都干掉的话
rm -r test
不过,这个操作非常危险,一定要谨慎使用。
关于执行档的路径的变量:$PATH
经过前面FHS的说明后,我们知道想要执行文档应该输入完整的路径,例如:ls的完整路径是:/bin/ls(这是绝对路径),那为什么我们在什么地方都可以执行 ls 这个命令呢?
因为有环境变量 PATH 的帮忙啊。
当我们在执行命令的时候,例如 ls ,系统会依照 PATH 的设定去每个 PATH 定义的目录下搜寻名为 ls 的可执行档,如果在 PATH 定义的目录中含有多个名为 ls 的可执行档,那么先搜索到的同名指令被先执行。
可以通过echo $PATH
来查看有那些目录被定义出来了,echo 有【显示、打印】的意思,而 PATH 前面加的 $
表示后面接的是变量,所以会显示出目前的 PATH。
PATH (一定是大写的)这个变量的内容是由一堆目录所组成的,每个目录中间用冒号:
来隔开,目录是有【顺序】之分的。
假如你是 root,如果你将 ls 由 /bin/ls 移动称为了 /root/ls(可用 mv /bin/ls /root达成),然后你自己本身也在 /root 目录下。
- 移动后在任何目录,直接输入 ls 都将无法执行该命令,因为 /root 这个目录并不在 PATH 指定的目录中,所以,即使你在 /root 目录下,也不能够搜索到 ls 这个指令。
- 因为 ls 这个指令只是被移动,并不是被删除,所以可以通过以下几种方法使用。
1、 /root/ls ——直接使用绝对路径。
2、 ./ls ——因为在 /root 目录下,就用 ./ls 来指定即可。
3、 PATH="${PATH}:/root" ——将 /root 加入 PATH 当中。
Tips:另外,除了 $PATH 之外,如果想要更母却的定义出变量的名称,可以使用大括号 ${PATH} 来处理变量的呼叫哦。
为什么 ${PATH}
搜寻目录不加本目录 .
,因为我们的工作目录并非固定的,所以这样对使用者来说并非是好事。 例如:有使用者在公共目录 tmp 中写了一个恶意程序,命名为 ls , 你是 root,然后你中标的几率就会很大,只要在tmp 里面 ls 以下,就会中招了。
- 不同身份使用者预设的 PATH 不同,预设能够随意执行的命令也不同(如 root 与 hare);
- PATH 是可以修改的;
- 使用绝对李静或相对路径直接指定某个指令的档名来执行,会比搜寻 PATH 来的正确;
- 指令应该要方置到正确的目录下,执行才会比较方便;
- 本目录
.
最好不要放到 PATH 当中。
档案与目录管理
档案的管理无非就是显示属性、复制、删除、移动档案或目录
档案与目录查看: ls
- 语法:
- ls [-aAdfFhilnrRSt] 档名或目录名称
- ls [--color={never, auto, always}] 档名或目录名称
- ls [--full-time] 档名或目录名称
- 选项与参数:
- -a:全部的档案,连同隐藏档(开头为 . 的档案)一起列出来(常用)
- -A:全部的档案,连同隐藏档,但不包括 . 与 .. 这两个目录
- -d:仅列出目录本身,而不是列出目录内的档案资料(常用)
- -f:直接列出结果,而不进行排序(ls预设会以档名排序)
- -F:根据档案、目录等讯息,给予附加资料结构。例如:
*
:代表可执行档;/
:代表目录;=
:代表socket档案;|
:代表FIFO档案; - -h:将档案容量以人类较易读的方式列出来;
- -i:列出 inode 号码,inode 的意义后面学;
- -l:长资料串列出,包含档案的属性与权限等等资料(常用);
- -n:列出 UID 与 GID 而非使用者与群组的名称(在账号管理学习);
- -r:将排序结果反向输出,例如:原本档名由小到大,反向则由大到小;
- -R:连同子目录内容一起列出来,等于该目录下的所有档案都会显示出来;
- -S:以档案容量大小排序,而不是用档名排序;
- -t:依照时间排序,而不是用档名。
- --color=never:不要依据档案特性给予颜色提示;
- --color=always:显示颜色;
- --color=auto:让系统自行依据设定来判断是否给予颜色;
- --full-time:以完整时间模式(包含年、月、日、时、分)输出;
- --time={atime, ctime}:输出 access 时间或改变权限属性时间(ctime),而非内容变更时间(modification time).
ls预设的显示为:非隐藏档的档名、以档名进行排序及档名代表的颜色显示。
复制、删除与移动:cp, rm, mv
cp(复制档案或目录)
- 语法:
- cp [-adfilprsu] 来源档(source) 目标档(destination)
- 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的来源档与目的档的权限是不同的,目的档的拥有者通常会是指令操作者本身。(前提是最少得有r权限才可以复制)。
-r 是强制操作,比如复制目录的时候,但是档案与目录的权限可能被改变,所以可以用 【-a】 尤其是在【备份】的时候。
-l 是创建硬链接
-s 是创建软链接
-u 是在目标档案与原来的档案有差别的时候,才会被复制,多用于【备份】
-d 在复制链接档的时候,加-d复制的是链接档,如果不加任何选项,则会复制原档案
最后:就是在同时复制多个档案的时候,最后一个是复制到的路径,所以需要是目录
rm(移除档案或目录)
- 语法:
- rm [-fir] 档案或目录
- 选项与参数:
- -f:就是 force 的意思,忽略不存在的档案,不会出现警告讯息;
- -i:互动模式,在删除前曾询问使用者是否动作
- -r:递归删除!最常用在目录的删除了!非常危险的选项!
一般在 rm -r 一个目录的时候,系统会询问是否需要删除,需要不停的按 y 进行确认,如果我们用【\rm -r/tep】在rm前面加个反斜杠,代表忽略 alias。这个很危险。
如何删除类似【-aaa-】这样的文档:
- 需要给档案的【名字加上引号】,因为-a本身是选项,档案名称中又有-a,所以系统会误判。
- 在档案前加上本目录【./】即可。
- 最后一种方式就是【rm --- -aaa-】
在使用【rm -r】这个指令之前,千万注意,因为该目录或档案【肯定】会被 root 杀掉。
mv(移动档案与目录,或更名)
- 语法:
- mv [-fiu] source destination
- mv [options] source1 source2 source3 ... directory
- 选项:
- -f:force 强制的意思,如果目标档案已经存在了,不会询问而直接覆盖;
- -i:若目标档案(destination)已经存在时,就会询问是否覆盖;
- -u:若目标档案已经存在,且 source 比较新,才会更新(update)
值得注意的是,mv有更名的作用,但是在linux下还有个有趣的命令【rename】,该指令专门进行多个档名的同时更名,并非针对单一档名更名,与 mv 有所区别。
如果有多个来源档案或目录,则最后一个目标档一定是【目录】,意思是,将前面所有的资料全部移动到该目录下。
取得路径的档案名称与目录名称
每个档案的完整档名包含了前面的【目录】与最终的【档名】,中间用斜线【/】分隔,每个档名长度都可达到【255个字符】或【128个汉字】。
获取档名与目录名有什么用呢?在写 shell scripts 的时候就会用到了。
获取档名用:【basename】
获取路径名用:【dirname】
档案内容查阅
常用的查阅内容的命令如下:
cat
由第一行开始显示档案内容(档案全部打印到终端上,可以用之前学过的 shift+PgUp/PgDn 进行翻页tac
从最后一行开始显示,可以看出 tac 是 cat 的倒着写。nl
显示的时候,顺道输出行号more
一页一页的显示档案内容(退出后不会在终端显示全部内容)less
与 more 类似,但是比 more 更好的是,多了向前翻页的功能。head
只看头几行tail
只看尾巴几行od
以二进位的方式读取档案内容
直接查看档案内容
直接把档案内容输出到终端上的,可以使用 cat、tac、nl 这几个指令。
cat(concatenate(连续))
- 语法:
- cat [-AbEnTv]
- 选项与参数:
- -A:相当于 -vET 的整合选项,可以列出一些特殊字符而不是空白而已;
- -b:列出行号,仅针对非空白行做行号显示,空白行不标行号;
- -E:将结尾的断行字符
$
显示出来; - -n:列出行号,连同空白行也会有行号,与 -b 的选项不同;
- -T:将
tab
按键以^I
显示出来; - -v:列出一些看不出来的特殊字符。
tac(反向输出)
就是 cat 的反过来,由最后一行到第一行反向在屏幕上显示出来。
nl(添加行号列印)
- 语法:
- nl [-bnw] 档案
- 选项与参数:
- -b:指定行号指定的方式,主要有两种:
- -ba :表示不论是否为空行,也同样列出行号(类似 cat -n);
- -bt :如果有空行,空的那一行不要列出行号(预设值);
- -n:列出行号表示的方法,主要有三种:
- -nln:行号在屏幕的最左方显示;
- -nrn:行号在自己栏位的最右方显示,且不加 0 ;
- -nrz:行号在自己栏位的最右方显示,且加 0 ;
- -w:行号栏位的占用字符数。
- -b:指定行号指定的方式,主要有两种:
nl 可以将输出的档案内容自动的加上行号!其预设的结果与 cat -n 有点不太一样,nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 等等的功能。
可翻页显示
more(一页一页翻动)
more的最后一行会显示出目前显示的表粉笔,而且还可以在最后一行输入一些有用的指令。
在 more 这个程序的运作过程中,可以执行的按键有:
- 空格键(space):代表向下翻【一页】;
- Enter :代表向下翻【一行】;
- /字串 :代表在这个显示的内容当中,向下搜索【字串】这个关键字;
- :f :立刻显示出档名一级目前显示的行数;
- q :代表立刻离开 more,不在显示该档案内容;
- b 或 [ctrl]-b :代表往回翻页,不过这个动作只对档案有用,对管线无用。
less(一页一页翻动)
less 的用法比起 more 更有弹性,因为 more 没办法向前翻,只能向后翻,但是less 就可以用 [pageup][pagedown]等按键了。
此外,less 还有更多的【搜索】功能,不止可以向下搜,还可以向上搜。
可以输入的指令有:
- 空白键:向下翻动一页;
- [pagedown]:向下翻动一页;
- [pageup]:向上翻动一页;
- /字串 :向下搜索【字串】的功能;
- ?字串 :向上搜索【字串】的功能;
- n :重复前一个搜索(与 / 或 ? 有关);
- N :反向的重复前一个搜索(与 / 或 ? 有关);
- g :前进都这个资料的第一行去;
- G :前进到这个资料的最后一行取(注意大小写);
- q :离开 less 这个程序;
资料擷取[xié qǔ](采取;选取)
我们可以将输出的资料作一个最简单的撷取,那就是取出档案前面几行(head)或取出后面几行(tail)文字的功能。
需要注意的是 head 和 tail 都是以【行】为单位来进行撷取的哦。
head(取出前面几行)
- 语法:
- head [-n number] 档案
- 选项与参数:
- -n:后面接数字,代表显示几行的意思。
预设是显示前面的 10 行。
另外:那个 -n 选项后面的参数比较有趣,如果接的是负数,比如是【-100】,代表列出前面的所有行但不包括后面的【100】行。
tail(取出后面几行)
- 语法:
- tail [-n number] 档案
- 选项与参数:
- -n :后面接数字,代表显示几行的意思;
- -f :表示持续侦测后面所接的档名,要等到按下 [ctrl]-c 才会结束 tail 的侦测
预设的情况是显示最后的 10 行。
另外,如果不知道文档有几行,但是想列出【100】行以后(包括第100行)的资料时,用【tail -n +100 档名】
-f 参数的使用往往会与管道|
符一起用,管道的意思是,前面的指令所输出的信息,通过管道交由后面的指令继续使用。
非纯文字档:od
前面提到的都是纯文字档内容的查看方式,如果遇到非文字档,例如: /usr/bin/passwd 这个档案的内容该如何读取呢?
实际上,由于执行档通常是 binary file ,使用上面提到的指令来读取内容时会产生类似乱码的资料,那么我们可以通过 od 这个指令来读取。
- 语法:
- od [-tTYPE] 档案
- 选项或参数:
- -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;
- -t :后面可以接各种【类型(type)】的输出,例如:
至于显示出来的内容的读法......
修改档案时间或创建新档:touch
linux 下会记录许多的时间参数,其实主要有三个变动时间,分别是:
- modification time (mtime):
- 当该档案的【内容资料】变更时,就会更新这个时间!内容资料指的是档案的内容,而不是档案的属性或权限。
- status time (ctime):
- 该档案的【状态(status)】改变时,就会更新这个时间,例如:权限或属性被改变了,都会变更这个时间。
- access time (atime):
- 档【该档案的内容被取用】时,就会更新这个读取时间(access)。例如,我们使用 cat 取读取一个文档,那么该文档的 atime 就会被更新了。
关于 atime 的补充:
鸟哥的教程没有问题,但是关于 atime 的问题有些复杂,引用原文:
atime updates are by far the biggest IO performance deficiency that Linux has today. Getting rid of atime updates would give us more everyday Linux performance than all the pagecache speedups of the past 10 years, _combined_.
As of 2.6.30 (9 June 2009), Linux defaults to relatime,[3] so that it will not update atime on all file reads. The behavior offers sufficient performance for most purposes and should not break any significant applications. Extended discussion of filesystem performance preceded the decision.[4] Indeed, relatime by default was the first patch Linux applied following the 2.6.29 release. In initial patches relatime only updated atime if atime < mtime or atime < ctime;
鸡饭:
atime更新是Linux目前最大的IO性能缺陷。去掉atime更新会给我们带来比过去10年所有pagecache加速都更高的Linux日常性能。
从2.6.30(2009年6月9日)起,Linux默认为relatime,[3],因此它不会在所有文件读取时更新atime。该行为为大多数目的提供了足够的性能,不应破坏任何重要的应用程序。文件系统性能的扩展讨论早在决定之前就已经开始了。[4]实际上,relatime在默认情况下是2.6.29发行版之后应用的第一个补丁Linux。在初始补丁中,只有当atime<mtime或atime<ctime时,relatime才更新atime;
关于 ctime:
有人认为是: change time 或 create time ,就是改变时间,文件的索引节点发生变化,具体情况有:
1. 文件内容有修改
2. 文件权限有修改
3. inode变化
4. 重命名(重命名不会导致inode改变)
Tips:如果我们想要同时执行多个指令的时候,可以用分好;
将指令隔开,例如:date; ls -l 1.md; ls -l --time=atime 1.md; ls -l --time=ctime 1.md
这个指令把当前的日期,1.md 的mtime、atime、ctime都显示出来了。
在预设的情况下,ls 显示出来的是该档案的 mtime,也就是这个档案的内容上次被变更的时间。
好吧!再废话一下:
ls -l 1.md # 显示的是 1.md 的 mtime
ls -l -c 1.md # 显示的是 1.md 的 ctime
ls -l -u 1.md # 显示的是 1.md 的 atime
还不懂就自己 man 或 info 吧!
好吧,废话这么多,就是为了了解一下 touch
touch 是可以修改档案时间的,档案的时间很重要,如果档案的时间错误,可能会造成某些程序无法顺利运行。比如:一个来自未来的文档(系统时间因为时区等原因修改过等,这种情况是有可能的)
- 语法:
- touch [-acdmt] 档案
- 选项与参数:
- -a : 仅修订 Access time;
叮咚:这个因为刚说的 atime 的相关问题可能不管用了,各个 distributions 情况可能不太相同.
- -c : 仅修改档案的时间,若该档案不存在则不建立新档案;
- -d : 后面可以接欲修订的日期而不用目前的日期,也可以使用 --date="日期或时间"
注意:ctime是操作时间,非目标时间
这里的时间或日期可以直接写成“2 days ago”类型,都可以。 - -m : 仅修改 mtime;
- -t : 后面可以接欲修订的时间而不用目前的时间,格式为[YYYYMMDDhhmm]
注意:ctime是操作的时间,非目标时间
- -a : 仅修订 Access time;
Tips:在预设的情况下,touch 后面直接跟档案,则该档案的三个时间(atime/ctime/mtime)都会更新为当前时间,若档案不存在,则创建该名称的空白档案,也就是创建文档的功能喽。
注意:touch 我们可以建立空档案或修订档案的日期与时间。我们复制一个档案的时候,可以复制所有属性,也无法复制 ctime 这个属性,ctime 可以记录这个档案最近的状态呢(status)被改变的时间。
无论如何,我们平时比较看中的,还是 mtime ,因为我们关心的是这个档案的【内容】什么什么时候被更动过。
touch最常使用情况:
- 创建文档
- 更新某个档案的时间为当前时间(mtime与atime)
这里atime应该无论哪个distribution都是管用的^-^
hare
2020.3.10