Linux学习笔记11——Linux 文件与目录管理

一、目录与路径

如果是在写程序 (shell scripts) 来管理系统的条件下,务必使用绝对路径的写法。 怎么说呢?因为绝对路径的写法虽然比较麻烦,但是可以肯定这个写法绝对不会有问题。 如果使用相对路径在程序当中,则可能由于你执行的工作环境不同,导致一些问题的发生。

1,目录的相关操作

到变换目录的指令是cd,特殊的目录:

有个有趣的问题,/(根目录)是否有上层目录?用ls -al查询,发现根目录确实是有上层目录,cd ..发现还是在根目录,即根目录的上级目录和当前目录是一样的。

常见的目录相关指令:

cd:变换目录

pwd:显示目前的目录

mkdir:创建一个新的目录

rmdir:删除一个空的目录

cd (change directory, 变换目录)

# pwd [-P]

-P :显示出确实的路径,而非使用链接 (link) 路径。

cd /var/mail

pwd

pwd -P

为什么会有这么大差异?

因为这是个链接文件。

mkdir [-mp] 目录名称

-m :设置文件的权限喔!直接设置,不需要看默认权限 (umask) 的脸色~

-p :帮助你直接将所需要的目录(包含上层目录)递回创建起来!

在test下尝试创建数个文件夹:

要想一次创建多级目录,需要用-p

mkdir -p a1/b1/c1/d

创建权限为rwx--x--x的目录

当然如果没有用-m则会采用默认权限

不过在生成目录时,不建议用-p,要是写错了就会很麻烦的。

rmdir (删除“空”的目录)

rmdir [-p] 目录名称

-p :连同“上层”“空的”目录也一起删除

一旦目录非空,则会报错。

[root@docker1 test]# rmdir -p a1/b1/c1/d1/

# 瞧!利用 -p 这个选项,立刻就可以将 test1/test2/test3/test4 一次删除~

# 不过要注意的是,这个 rmdir 仅能“删除空的目录”喔!

那如果要将所有目录下的东西都杀掉呢?! 这个时候就必须使用“ rm -r test ”啰!不过,还是使用 rmdir 比较不危险!你也可以尝试以 -p 的选项加入,来删除上层的目录喔!

2,关于可执行文件路径的变量: $PATH

我们查阅当前目录的相关信息,用ls就可以,为什么我可以在任何地方执行/bin/ls这个指令呢?这是

因为环境变量 PATH 的帮助所致呀!

PATH(一定是大写)这个变量的内容是由一堆目录所组成的,每个目录中间用冒号(:)来隔开, 每个目录是有“顺序”之分的。仔细看一下上面的输出,你可以发现到无论是root还是其他用户都有 /bin 或 /usr/bin 这个目录在PATH变量内,所以当然就能够在任何地方执行ls来找到/bin/ls可执行文件啰!

如果要再PATH中再添加一个目录,放置可执行文件:

二、文件与目录管理

1,文件与目录的检视: ls

ls -a  能够显示隐藏文件

不显示颜色:

ls -alF --color=never

完整显示修改时间:

ls -al --full-time ~

其实 ls 的用法还有很多,包括查阅文件所在 i-node 号码的 ls -i 选项,以及用来进行文件排序的 -S 选项,还有用来查阅不同时间的动作的 --time=atime 等选项。ls 最常被使用到的功能还是那个 -l 的选项,所以就有 ll  =  ls -l。

2,复制、删除与移动: cp, rm, mv ——cp

cp (copy)复制,mv (move)移动也可用作改名,rm (remove)移除。

cp (复制文件或目录)

cp [-adfilprsu] 来源文件(source) 目标文件(destination)

选项与参数:

-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)这个指令是非常重要的,不同身份者执行这个指令会有不同的结果产生,尤其是

那个-a, -p的选项, 对于不同身份来说,差异则非常的大!

我们来做几个练习:

(1)将主文件夹下的 .bashrc 复制到 /test 下,并更名为 bashrc

root权限下执行:

cp .bashrc test/bashrc

然后再执行一次,cp -i .bashrc test/bashrc

(2)变换目录到/test,并将/var/log/wtmp复制到/tmp且观察属性:

[root@docker1 ~]# cd test/

[root@docker1 test]# cp /var/log/wtmp .

[root@docker1 test]# ll /var/log/wtmp wtmp

结果:

-rw-rw-r--. 1 root utmp 55296 11月  5 22:58 /var/log/wtmp

-rw-r--r--  1 root root 55296 11月  5 23:12 wtmp

复制后的权限是由变化的!还有一点,创建的时间也不同了

# 那如果你想要将文件的所有特性都一起复制过来该怎办?可以加上 -a 喔!如下所示:

[root@docker1 test]# cp -a /var/log/wtmp wtmp_2

[root@docker1 test]# ls -l /var/log/wtmp wtmp_2

结果:

-rw-rw-r--. 1 root utmp 55296 11月  5 22:58 /var/log/wtmp

-rw-rw-r--. 1 root utmp 55296 11月  5 22:58 wtmp_2

通过cp -a可以将文件的所有特性都复制过来。

我们如果去复制别人的数据 (当然,该文件你必须要有 read 的权限才行啊!^^) 时, 总是希望复制到的数据最后是我们自己的,所以,在默认的条件中, cp 的来源文件与目的文件的权限是不同的,目的文件的拥有者通常会是指令操作者本身。由于我是 root 的身份,因此复制过来的文件拥有者与群组就改变成为 root 所有了!

由于具有这个特性,因此当我们在进行备份的时候,某些需要特别注意的特殊权限文件, 例如密码档 (/etc/shadow) 以及一些配置文件,就不能直接以 cp 来复制,而必须要加上 -a或者是 -p 等等可以完整复制文件权限的选项才行!

(3)复制 /etc/ 这个目录下的所有内容到 /test下面

[root@docker1 test]# cp /etc/ .

cp: 略过目录"/etc/"

如果是目录则不能直接复制,要加上 -r 的选项 -r :递回持续复制,用于目录的复制行为;

# 还是要再次的强调喔! -r 是可以复制目录,但是,文件与目录的权限可能会被改变

# 所以,也可以利用“ cp -a /etc /tmp ”来下达指令喔!尤其是在备份的情况下!

(4)将范例一复制的 bashrc 创建一个链接文件 (symbolic link)

[root@docker1 test]# ls -l bashrc

-rw-r--r-- 1 root root 176 11月  5 23:08 bashrc

[root@docker1 test]# cp -s bashrc bashrc_slink

[root@docker1 test]# cp -l bashrc bashrc_hlink

[root@docker1 test]# ls -l bashrc*

-rw-r--r-- 2 root root 176 11月  5 23:08 bashrc

-rw-r--r-- 2 root root 176 11月  5 23:08 bashrc_hlink

lrwxrwxrwx 1 root root   6 11月  5 23:27 bashrc_slink -> bashrc

范例四可有趣了!使用 -l 及 -s 都会创建所谓的链接文件(link file),但是这两种链接文件却有不一样的情况。这是怎么一回事啊? 那个 -l 就是所谓的实体链接(hard link),至于 -s 则是符号链接(symbolic link), 简单来说,bashrc_slink 是一个“捷径”,这个捷径会链接到bashrc去!所以你会看到文件名右侧会有个指向(->)的符号!

至于bashrc_hlink文件与bashrc的属性与权限完全一模一样,与尚未进行链接前的差异则是第二栏的link数由1变成2了!

(5)若 ~/.bashrc 比 /tmp/bashrc 新才复制过来

[root@docker1 test]# cp -u ~/.bashrc /tmp/bashrc

这个 -u 的特性,是在目标文件与来源文件有差异时,才会复制的。所以,比较常被用于“备份”的工作当中喔! ^_^

(6)将范例四造成的 bashrc_slink 复制成为 bashrc_slink_1 与bashrc_slink_2

[root@docker1 test]#  cp bashrc_slink bashrc_slink_1

[root@docker1 test]# cp -d bashrc_slink bashrc_slink_2

[root@docker1 test]# ls -l bashrc bashrc_slink*

-rw-r--r-- 2 root root 176 11月  5 23:08 bashrc

lrwxrwxrwx 1 root root   6 11月  5 23:27 bashrc_slink -> bashrc

-rw-r--r-- 1 root root 176 11月  5 23:32 bashrc_slink_1                     #与原始文件相同

lrwxrwxrwx 1 root root   6 11月  5 23:32 bashrc_slink_2 -> bashrc     #是链接文件!

# 这个例子也是很有趣喔!原本复制的是链接文件,但是却将链接文件的实际文件复制过来了

# 也就是说,如果没有加上任何选项时,cp复制的是原始文件,而非链接文件的属性!

# 若要复制链接文件的属性,就得要使用 -d 的选项了!如 bashrc_slink_2 所示。

-d :若来源文件为链接文件的属性(link file),则复制链接文件属性而非文件本身;

(7)将主文件夹的 .bashrc 及 .bash_history 复制到 /tmp 下面

[root@docker1 test]#  cp ~/.bashrc ~/.bash_history /tmp

# 可以将多个数据一次复制到同一个目录去!最后面一定是目录!

[tom@docker1 test]$ cp -a /var/log/wtmp /tmp/dmtsai_wtmp

[tom@docker1 test]$ ls -l /var/log/wtmp /tmp/dmtsai_wtmp

-rw-rw-r--  1 tom  tom  55296 11月  5 22:58 /tmp/dmtsai_wtmp

-rw-rw-r--. 1 root utmp 55296 11月  5 22:58 /var/log/wtmp

由于 tom的身份并不能随意修改文件的拥有者与群组,因此虽然能够复制wtmp的相关权限与时间等属性, 但是与拥有者、群组相关的,原本 tom身份无法进行的动作,即使加上 -a 选项,也是无法达成完整复制权限的!

总之,由于 cp 有种种的文件属性与权限的特性,所以,在复制时,你必须要清楚的了解到:

(1)是否需要完整的保留来源文件的信息?

(2)来源文件是否为链接文件 (symbolic link file)?

(3)来源文件是否为特殊的文件,例如 FIFO, socket 等?

(4)来源文件是否为目录?

3,rm (移除文件或目录)

# rm [-fir] 文件或目录

选项与参数:

-f :就是 force 的意思,忽略不存在的文件,不会出现警告讯息;

-i :互动模式,在删除前会询问使用者是否动作

-r :递回删除啊!最常用在目录的删除了!这是非常危险的选项!!!

(1)将刚刚在 cp 的范例中创建的 bashrc 删除掉!

[root@docker1 test]# cd /tmp/

[root@docker1 tmp]# rm -i bashrc

rm:是否删除普通文件 "bashrc"?y

[root@docker1 tmp]#

# 如果加上 -i 的选项就会主动询问喔,避免你删除到错误的文件名!

(2)通过万用字符*的帮忙,将/test下面开头为bashrc的文件名通通删除:

[root@docker1 tmp]# ll bashrc*

# 注意那个星号,代表的是 0 到无穷多个任意字符喔!很好用的东西!

(3)将 cp 范例中所创建的 /tmp/etc/ 这个目录删除掉!

[root@docker1 tmp]# rmdir etc/

rmdir: 删除 "etc/" 失败: 目录非空 <== 删不掉啊!因为这不是空的目录!

[root@docker1 tmp]# rm -r /tmp/etc/

rm:是否进入目录"/tmp/etc/"? y

rm:是否删除普通文件 "/tmp/etc/fstab"?y

rm:是否删除普通空文件 "/tmp/etc/crypttab"?y

rm:是否删除符号链接 "/tmp/etc/mtab"?y

# 因为身份是 root ,默认已经加入了 -i 的选项,所以你要一直按 y 才会删除!

# 如果不想要继续按 y ,可以按下“ [ctrl]-c ”来结束 rm 的工作。

# 这是一种保护的动作,如果确定要删除掉此目录而不要询问,可以这样做:

[root@docker1 tmp]# \rm -r /tmp/etc/

# 在指令前加上反斜线,可以忽略掉 alias 的指定选项喔!至于 alias 我们在bash再谈!

# 拜托!这个范例很可怕!你不要删错了!删除 /etc 系统是会挂掉的!

(4)删除一个带有 - 开头的文件

[root@docker1 test]# touch ./-aaa- <==[touch](../Text/index.html#touch)这个指令可以创建空文件!

[root@study tmp]# ls -l

[root@docker1 test]# ll

总用量 112

drwxr-xr-x  2 tom  tom     20 10月 29 23:30 aa

-rw-r--r--  1 root root     0 11月  5 23:46 -aaa- <==文件大小为0,所以是空文件

[root@docker1 test]# rm -aaa   rm:无效选项 -- a <== 因为 "-" 是选项嘛!所以系统误判了!

Try 'rm ./-aaa-' to remove the file `-aaa-'. <== 新的 bash 有给建议的

Try 'rm --help' for more information.

[root@docker1 test]# rm ./-aaa-

rm:是否删除普通空文件 "./-aaa-"?y

这是移除的指令(remove),要注意的是,通常在Linux系统下,为了怕文件被 root 误杀,所以很多 distributions 都已经默认加入 -i 这个选项了!而如果要连目录下的东西都一起杀掉的话, 例如子目录里面还有子目录时,那就要使用 -r 这个选项了!不过,使用“ rm -r ”这个指令之前,请千万注意了,因为该目录或文件“肯定”会被 root 杀掉!因为系统不会再次询问你是否要砍掉呦!所以那是个超级严重的指令下达呦! 得特别注意!不过,如果你确定该目录不要了,那么使用 rm -r 来循环杀掉是不错的方式!

文件名最好不要使用 "-" 号开头, 因为"-" 后面接的是选项,这时就要./文件名来进行删除啦。查man rm的话,还有一种办法:“ rm -- -aaa- ”

4,mv (移动文件与目录,或更名)

# mv [-fiu] source destination

# mv [options] source1 source2 source3 .... directory

选项与参数:

-f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;

-i :若目标文件 (destination) 已经存在时,就会询问是否覆盖!

-u :若目标文件已经存在,且 source 比较新,才会更新 (update)

范例一:复制一文件,创建一目录,将文件移动到目录中

[root@docker1 ~]# cd /tmp/

[root@docker1 tmp]#  cp ~/.bashrc bashrc

[root@docker1 tmp]# mkdir mvtest

[root@docker1 tmp]# mv bashrc mvtest/

# 将某个文件移动到某个目录去,就是这样做!

范例二:将刚刚的目录名称更名为 mvtest2

[root@docker1 tmp]# mv mvtest mvtest2 <== 这样就更名了!简单~

# 其实在 Linux 下面还有个有趣的指令,名称为 rename ,

# 该指令专职进行多个文件名的同时更名,并非针对单一文件名变更,与mv不同。请man rename。

范例三:再创建两个文件,再全部移动到 /tmp/mvtest2 当中

[root@docker1 tmp]# cp ~/.bashrc bashrc1

[root@docker1 tmp]# cp ~/.bashrc bashrc2

[root@docker1 tmp]# mv bashrc1 bashrc2 mvtest2/

# 注意到这边,如果有多个来源文件或目录,则最后一个目标文件一定是“目录!”

# 意思是说,将所有的数据移动到该目录的意思!

5,取得路径的文件名称与目录名称

要分辨文件名和目录名,可以通过basename 与 dirname来搞定:

[root@docker1 tmp]# basename /etc/sysconfig/network

network <== 很简单!就取得最后的文件名~

[root@docker1 tmp]# dirname /etc/sysconfig/network

/etc/sysconfig <== 取得的变成目录名了!

猜你喜欢

转载自blog.csdn.net/qq_22059611/article/details/83717571