一、目录与路径
如果是在写程序 (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 <== 取得的变成目录名了!