6.1 目录与路径
下达指令时,该指令是通过什么功能来取得与PATH变量有关!
6.1.1 相对路径与绝对路径
- 相对路径 的用途
相邻目录进行切换,不必记住全路径
cd ../cctv
- 绝对路径的用途
在写程序(shell scripts)来管理系统的条件下,务必使用绝对路径的写法。在工作调度(cron)当中尤其重要。
6.1.2 目录的相关操作
. 代表此层目录
.. 代表上一层目录
- 代表前一个工作目录
~ 代表“目前使用者身份”所在的主文件夹
~account 代表 account 这个使用者的主文件夹(account是个账号名称)
根目录下存在(.) 也存在 (..),但是同一个目录。
常见处理目录的指令:
- cd: 变换目录
- pwd: 显示目前的目录
- mkdir: 创建一个新的目录
- rmdir: 删除一个空的目录
➡ cd(change directory,变换目录)
[dmtsai@study ~]$ su - # 先切换身份成为 root 看看!
[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 就这样写!
[tab] 可以补齐相应目录
➡ 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 的选项后,会不以链接文件的数据显示,而是显示正确的完整路径啊!
-P 选项可以取得正确的目录名称,而不是链接文件的路径。
➡ 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 来强制设置属性,系统会使用默认属性。
# 那么你的默认属性为何?这要通过下面介绍的 [umask](../Text/index.html#umask) 才能了解喔! ^_^
mkdir -m 711 -p [folder]
-m 设置权限
-p 创建连续目录(不存在的情况下)
➡ 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 [dir] 只可删除空目录
rm -r [dir] 可删除目录及目录下所有文件
rm -p [dir] 回一并删除上层目录
6.1.3 可执行文件路径变量: $PATH
ls 是指令,系统会依照PATH的设置去每个PATH定义的目录下搜寻文件名为ls的可执行文件,如果有多个,先搜寻到的同名指令先被执行!
范例:先用root的身份列出搜寻的路径为何?
[root@study ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
范例:用dmtsai的身份列出搜寻的路径为何?
[root@study ~]# exit # 由之前的 su - 离开,变回原本的帐号!或再取得一个终端机皆可!
[dmtsai@study ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
# 记不记得我们前一章说过,目前 /bin 是链接到 /usr/bin 当中的喔!
无论是root还是dmtsai 都有 /bin 或 /usr/bin目录在PATH变量内,所以在任何地方执行ls都可以找到 /bin/ls 可执行文件!
需要注意的是:
- 不同身份使用者默认的PATH不同,默认能够随意执行的指令也不同
- PATH是可以修改的
- 使用绝对路径或相对路径直接指定某个指令的文件名来执行,会比搜寻PATH来的正确
- 指令应该要放置到正确目录下,执行才会比较方便
- 本目录(.)最好不要放到PATH中
6.2 文件与目录管理
6.2.1 文件与目录检视:ls
[root@study ~]# ls [-aAdfFhilnrRSt] 文件名或目录名称..
[root@study ~]# ls [--color={never,auto,always}] 文件名或目录名称..
[root@study ~]# 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)
6.2.2 复制、删除与移动:cp,rm,mv
- cp(复制文件或目录)
[root@study ~]# cp [-adfilprsu] 来源文件(source) 目标文件(destination)
[root@study ~]# 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 -l 是所谓的实体链接(硬链接 hard link),-s是符号链接(软链接 symbolic link)
硬链接只能对文件创建,没法对目录创建;软链接类似windows快捷方式,是一个特殊的文本文件,包含着目标文件的位置信息。
当一个物理文件的最后一个硬链接被删除时候,该文件才会被删除。删除软链接就和删除windows的一个快捷方式一样,对物理文件没影响。
- rm(移除文件或目录)
[root@study ~]# rm [-fir] 文件或目录
选项与参数:
-f :就是 force 的意思,忽略不存在的文件,不会出现警告讯息;
-i :互动模式,在删除前会询问使用者是否动作
-r :递回删除啊!最常用在目录的删除了!这是非常危险的选项!!!
范例一:将刚刚在 cp 的范例中创建的 bashrc 删除掉!
[root@study ~]# cd /tmp
[root@study tmp]# rm -i bashrc
rm: remove regular file `bashrc'? y
# 如果加上 -i 的选项就会主动询问喔,避免你删除到错误的文件名!
范例二:通过万用字符*的帮忙,将/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再谈!
# 拜托!这个范例很可怕!你不要删错了!删除 /etc 系统是会挂掉的!
范例四:删除一个带有 - 开头的文件
[root@study tmp]# touch ./-aaa- <==[touch](../Text/index.html#touch)这个指令可以创建空文件!
[root@study tmp]# ls -l
-rw-r--r--. 1 root root 0 Jun 11 19:22 -aaa- <==文件大小为0,所以是空文件
[root@study tmp]# rm -aaarm: invalid option -- 'a' <== 因为 "-" 是选项嘛!所以系统误判了!
Try 'rm ./-aaa-' to remove the file `-aaa-'. <== 新的 bash 有给建议的
Try 'rm --help' for more information.
[root@study tmp]# rm ./-aaa
- mv(移动文件与目录,或更名)
[root@study ~]# mv [-fiu] source destination
[root@study ~]# mv [options] source1 source2 source3 .... directory
选项与参数:
-f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
-i :若目标文件 (destination) 已经存在时,就会询问是否覆盖!
-u :若目标文件已经存在,且 source 比较新,才会更新 (update)
范例一:复制一文件,创建一目录,将文件移动到目录中
[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 ,
# 该指令专职进行多个文件名的同时更名,并非针对单一文件名变更,与mv不同。请man rename。
范例三:再创建两个文件,再全部移动到 /tmp/mvtest2 当中
[root@study tmp]# cp ~/.bashrc bashrc1
[root@study tmp]# cp ~/.bashrc bashrc2
[root@study tmp]# mv bashrc1 bashrc2 mvtest2
# 注意到这边,如果有多个来源文件或目录,则最后一个目标文件一定是“目录!”
# 意思是说,将所有的数据移动到该目录的意思!
rename 可以用来更改大量文件的文件名
6.2.3 取得路径的文件名称与目录名称
[root@study ~]# basename /etc/sysconfig/network
network <== 很简单!就取得最后的文件名~
[root@study ~]# dirname /etc/sysconfig/network
/etc/sysconfig <== 取得的变成目录名了!
6.3 文件内容查阅
- cat (Concatenate 连续) 由第一行开始显示文件内容
- tac 从最后一行开始显示,可以看出 tac 是 cat 的倒着写!
- nl 显示的时候,顺道输出行号!
- more 一页一页的显示文件内容
- less 与 more 类似,但是比 more 更好的是,他可以往前翻页!
- head 只看头几行
- tail 只看尾巴几行
- od 以二进制的方式读取文件内容!
# cat
cat [-n/b] [file] # 显示行号
cat [-A] [file] # 显示断行 / [tab] 等
# tac
同 cat,但是反向显示
# nl(添加行号打印)
nl [-bnw] 文件
选项与参数:
-b :指定行号指定的方式,主要有两种:
-b a :表示不论是否为空行,也同样列出行号(类似 cat -n);
-b t :如果有空行,空的那一行不要列出行号(默认值);
-n :列出行号表示的方法,主要有三种:
-n ln :行号在屏幕的最左方显示;
-n rn :行号在自己字段的最右方显示,且不加 0 ;
-n rz :行号在自己字段的最右方显示,且加 0 ;
-w :行号字段的占用的字符数。
# more(可向后翻页)
more [file]
进入文件后可以:
空白键 (space):代表向下翻一页;
Enter :代表向下翻“一行”;
/字串 :代表在这个显示的内容当中,向下搜寻“字串”这个关键字;
:f :立刻显示出文件名以及目前显示的行数;
q :代表立刻离开 more ,不再显示该文件内容。
b 或 [ctrl]-b :代表往回翻页,不过这动作只对文件有用,对管线无用。
# less(可前后翻页)
less [file]
进入文件后可以:
空白键 :向下翻动一页;
[pagedown]:向下翻动一页;
[pageup] :向上翻动一页;
/字串 :向下搜寻“字串”的功能;
?字串 :向上搜寻“字串”的功能;
n :重复前一个搜寻 (与 / 或 ? 有关!)
N :反向的重复前一个搜寻 (与 / 或 ? 有关!)
g :前进到这个数据的第一行去;
G :前进到这个数据的最后一行去 (注意大小写);
q :离开 less 这个程序;
6.3.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
- 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这个指令的侦测!
head -n 20 /etc/man_db.conf | tail -n 10 # 得到第 11 到第 20 行之间的内容
6.3.4 非纯文本文件: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。
echo password | od -t oCc echo # 传给 od 去继续处理
6.3.5 修改文件时间或创建新文件:touch
touch指令最常被使用的情况是:
- 创建一个空的文件
- 将某个文件日期修订为目前(mtime 与 atime)
Linux会记录文件的三个时间:
- modification time(mtime): 文件“内容数据”变更时,会更新时间
- status time(ctime): 文件“状态”改变时,会更新时间
- access time(atime): 文件“被取用”时,会更新时间,cat读取会更新此时间
date; ls -l /etc/man_db.conf ; ls -l --time=atime /etc/man_db.conf ; ls -l --time=ctime /etc/man_db.conf # 这两行其实是同一行喔!用分号隔开,默认显示mtime
[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 呢!在默认的状态下,如果 touch 后面有接文件,
# 则该文件的三个时间 (atime/ctime/mtime) 都会更新为目前的时间。若该文件不存在,
# 则会主动的创建一个新的空的文件喔!例如上面这个例子!
范例二:将 ~/.bashrc 复制成为 bashrc,假设复制完全的属性,检查其日期
[dmtsai@study tmp]# cp -a ~/.bashrc bashrc
[dmtsai@study tmp]# date; ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc
Tue Jun 16 00:49:24 CST 2015 <==这是目前的时间
-rw-r--r--. 1 dmtsai dmtsai 231 Mar 6 06:06 bashrc <==这是 mtime
-rw-r--r--. 1 dmtsai dmtsai 231 Jun 15 23:44 bashrc <==这是 atime
-rw-r--r--. 1 dmtsai dmtsai 231 Jun 16 00:47 bashrc <==这是 ctime
范例三:修改案例二的 bashrc 文件,将日期调整为两天前
[dmtsai@study tmp]# touch -d "2 days ago" bashrc
[dmtsai@study tmp]# date; ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc
Tue Jun 16 00:51:52 CST 2015
-rw-r--r--. 1 dmtsai dmtsai 231 Jun 14 00:51 bashrc
-rw-r--r--. 1 dmtsai dmtsai 231 Jun 14 00:51 bashrc
-rw-r--r--. 1 dmtsai dmtsai 231 Jun 16 00:51 bashrc
# 跟上个范例比较看看,本来是 16 日变成 14 日了 (atime/mtime)~不过, ctime 并没有跟着改变喔!
范例四:将上个范例的 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 则是记录目前的时间!
6.4 文件与目录的默认权限与隐藏权限
除了基本r,w,x权限外,在Linux传统的Ex2/Ex3/Ex4文件系统下,还可以设置系统隐藏属性,可以用chattr来设置,以lsattr来查看,最重要的是可以设置其不可修改的特性!让文件的拥有者都不能进行修改!不过CentOS 7.x使用xfs作为默认文件系统,xfs就没有支持所有的chattr参数。
6.4.1 文件默认权限:umask
umask是指定“目前使用者在创建文件或目录时的权限默认值”
[root@study ~]# umask
0022 <==与一般权限有关的是后面三个数字!
# [特殊权限][u:-r/w/x][g:-r/w/x][o:-r/w/x]
# rwx的得分是指“权限默认值需要减掉的权限”, 如拿掉写的权限,就是2分
umask 002 # 设置当前目录默认权限
[root@study ~]# umask -S
u=rwx,g=rx,o=rx
6.4.2 文件隐藏属性
chattr指令只能在Ext2/Ext3/Ext4上完整生效,xfs仅支持部分参数而已。
- chattr(设置文件隐藏属性)
[root@study ~]# chattr [+-=][ASacdistu] 文件或目录名称
选项与参数:
+ :增加某一个特殊参数,其他原本存在参数则不动。
- :移除某一个特殊参数,其他原本存在参数则不动。
= :设置一定,且仅有后面接的参数
A :当设置了 A 这个属性时,若你有存取此文件(或目录)时,他的存取时间 atime 将不会被修改,
可避免 I/O 较慢的机器过度的存取磁盘。(目前建议使用文件系统挂载参数处理这个项目)
S :一般文件是非同步写入磁盘的(原理请参考[前一章sync](../Text/index.html#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 而已
范例:请尝试到/tmp下面创建文件,并加入 i 的参数,尝试删除看看。
[root@study ~]# cd /tmp
[root@study tmp]# touch attrtest <==创建一个空文件
[root@study tmp]# chattr +i attrtest <==给予 i 的属性
[root@study tmp]# rm attrtest <==尝试删除看看
rm: remove regular empty file `attrtest'? y
rm: cannot remove `attrtest': Operation not permitted
# 连 root 也没有办法将这个文件删除呢!赶紧解除设置!
范例:请将该文件的 i 属性取消!
[root@study tmp]# chattr -i attrtest
- lsattr(显示文件隐藏属性)
[root@study ~]# lsattr [-adR] 文件或目录
选项与参数:
-a :将隐藏文件的属性也秀出来;
-d :如果接的是目录,仅列出目录本身的属性而非目录内的文件名;
-R :连同子目录的数据也一并列出来!
[root@study tmp]# chattr +aiS attrtest
[root@study tmp]# lsattr attrtest
--S-ia---------- attrtest
6.4.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
系统还有特殊权限 s 和 t
➡ Set UID
/usr/bin/passwd 文件的权限状态 “-rwsr-xr-x”,成为Set UID,简称为SUID的特殊权限。SUID的限制与功能:
- SUID权限仅对二进制程序(binary program)有效;
- 执行者对于该程序需要具有x的可执行权限;
- 本权限仅在执行该程序的过程中有效(run-time);
- 执行者将具有该程序拥有者(owner)的权限;
SUID仅可用在binary program上,不能用在shell script上!
➡ Set GID
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
SGID可以针对文件或目录来设置!
对文件设置,SGID有如下功能:
- SGID对二进制程序有用;
- 程序执行者对于该程序来说,需具备x权限;
- 执行者在执行过程中会获取该程序群组的支持
SGID对目录设置,有如下功能:
- 使用者若对于此目录具有 r 与 x 权限时,使用者能够进入此目录;
- 使用者在此目录下的有效群组(effective group)将会变成该目录的群组;
- 若使用者在此目录下具有 w 的权限(可新建文件),则使用者所创建的新文件与此目录的群组相同。
➡ Sticky Bit
Sticky Bit,SBIT目前只针对目录有效:
- 当使用者对于此目录具有 w,x权限,亦即具有写入的权限时;
- 当使用者在该目录下创建文件或目录时,仅有自己与root才有权力删除该文件
➡ SUID / SGID / SBIT 权限设置
4为SUID / 2为SGID / 1为SBIT
[root@study ~]# cd /tmp
[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代表“空”的意思,SUID表示“文件执行时,具有文件拥有者的权限”,但是文件拥有者无执行权限时,就没有权限给其他人使用,所以是“空”。
6.4.4 观察文件类型: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 文件!
6.5 指令与文件的搜寻
某些软件配置文件的文件名是不变的,但是各distribution放置的目录不同,可以通过一些搜寻指令将该配置文件的完整文件名找出来。
6.5.1 指令文件名的搜寻
可以通过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 会等于后面接的那串指令啦!
# 更多的数据我们会在 bash 章节中再来谈的!
范例三:请找出 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
# 但是 which 默认是找 PATH 内所规范的目录,history是“bash内置的指令”。可以通过type指令。
6.5.2 文件文件名的搜寻
find不很常用,速度慢也消耗硬盘。一般都先用whereis 或 locate来检查,找不到,再用find搜寻。
whereis只找系统某些特定目录下的文件,locate利用数据库来搜寻文件名。
➡ whereis(由一些特定目录中寻找文件文件名)
[root@study ~]# whereis [-bmsu] 文件或目录名
选项与参数:
-l :可以列出 whereis 会去查询的几个主要目录而已
-b :只找 binary 格式的文件
-m :只找在说明文档 manual 路径下的文件
-s :只找 source 来源文件
-u :搜寻不在上述三个项目当中的其他特殊文件
范例一:请找出 ifconfig 这个文件名
[root@study ~]# whereis ifconfig
ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz
范例二:只找出跟 passwd 有关的“说明文档”文件名(man page)
[root@study ~]# whereis passwd # 全部的文件名通通列出来!
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz
[root@study ~]# whereis -m passwd # 只有在 man 里面的文件名才抓出来!
passwd: /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz
➡ locate / updatedb
locate寻找的数据是由“已创建的数据库 /var/lib/mlocate/” 里面的数据,数据库的创建默认是在每天执行一次(每个distribution不同,CentOS 7.x是每天更新一次)
新创建的文件则找不到,需要执行 updatedb(根据/etc/updatedb.conf 的设置去搜寻系统硬盘内的文件名,饼更新/var/lib/mlocate内的数据库文件)
[root@study ~]# locate [-ir] keyword
选项与参数:
-i :忽略大小写的差异;
-c :不输出文件名,仅计算找到的文件数量
-l :仅输出几行的意思,例如输出五行则是 -l 5
-S :输出 locate 所使用的数据库文件的相关信息,包括该数据库纪录的文件/目录数量等
-r :后面可接正则表达式的显示方式
范例一:找出系统中所有与 passwd 相关的文件名,且只列出 5 个
[root@study ~]# locate -l 5 passwd
/etc/passwd
/etc/passwd-
/etc/pam.d/passwd
/etc/security/opasswd
/usr/bin/gpasswd
范例二:列出 locate 查询所使用的数据库文件之文件名与各数据数量
[root@study ~]# locate -S
Database /var/lib/mlocate/mlocate.db:
8,086 directories # 总纪录目录数
109,605 files # 总纪录文件数
5,190,295 Bytes in file names
2,349,150 Bytes used to store database
- 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 是重点!0 代表目前的时间,所以,从现在开始到 24 小时前,
# 有变动过内容的文件都会被列出来!那如果是三天前的 24 小时内?
# 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,
# 使用 -7000 表示要同时含有 ---s--s--t 的所有三个权限。而只需要任意一个,就是 /7000
➡ 额外可进行的动作
选项与参数:
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
# 查找当前目录的.txt文件并以列表形式列出来
find ./ -name "*.txt" -exec ls -l "{}" \;
# 批量修改当前目录下.txt文件的后缀名改为.txtd
find ./ -name "*.txt" -exec mv "{}" "{}d" \;
- {} 代表的是“由 find 找到的内容”,如上图所示,find 的结果会被放置到 {} 位置中;
- -exec 一直到 ; 是关键字,代表 find 额外动作的开始 (-exec) 到结束 (;) ,在这中间的就是 find 指令内的额外动作。
- “ ; ”在 bash 环境下是有特殊意义的,因此利用反斜线来跳脱。
6.6 极重要的复习!权限与指令间的关系
权限对于使用者帐号来说是非常重要的,因为他可以限制使用者能不能读取/创建/删除/修改文件或目录! 在这一章我们介绍了很多文件系统的管理指令,第五章则介绍了很多文件权限的意义。在这个小节当中, 我们就将这两者结合起来,说明一下什么指令在什么样的权限下才能够运行吧!
一、让使用者能进入某目录成为“可工作目录”的基本权限为何:
- 可使用的指令:例如 cd 等变换工作目录的指令;
- 目录所需权限:使用者对这个目录至少需要具有 x 的权限
- 额外需求:如果使用者想要在这个目录内利用 ls 查阅文件名,则使用者对此目录还需要 r的权限。
二、使用者在某个目录内读取一个文件的基本权限为何? - 可使用的指令:例如本章谈到的 cat, more, less等等
- 目录所需权限:使用者对这个目录至少需要具有 x 权限;
- 文件所需权限:使用者对文件至少需要具有 r 的权限才行!
三、让使用者可以修改一个文件的基本权限为何? - 可使用的指令:例如 nano 或未来要介绍的 vi 编辑器等;
- 目录所需权限:使用者在该文件所在的目录至少要有 x 权限;
- 文件所需权限:使用者对该文件至少要有 r, w 权限
四、让一个使用者可以创建一个文件的基本权限为何? - 目录所需权限:使用者在该目录要具有 w,x 的权限,重点在 w 啦!
五、让使用者进入某目录并执行该目录下的某个指令之基本权限为何? - 目录所需权限:使用者在该目录至少要有 x 的权限;
- 文件所需权限:使用者在该文件至少需要有 x 的权限
➡ 例题
例题:让一个使用者 dmtsai 能够进行“cp /dir1/file1 /dir2”的指令时,请说明 dir1, file1, dir2 的最小所需权限为何?
答:执行 cp 时, dmtsai 要“能够读取来源文件,并且写入目标文件!”所以应参考上述第二点与第四点的说明! 因此各文件/目录的最小权限应该是:
- dir1 :至少需要有 x 权限;
- file1:至少需要有 r 权限;
- dir2 :至少需要有 w, x 权限。
例题:有一个文件全名为 /home/student/www/index.html ,各相关文件/目录的权限如下:
drwxr-xr-x 23 root root 4096 Sep 22 12:09 /
drwxr-xr-x 6 root root 4096 Sep 29 02:21 /home
drwx------ 6 student student 4096 Sep 29 02:23 /home/student
drwxr-xr-x 6 student student 4096 Sep 29 02:24 /home/student/www
-rwxr--r-- 6 student student 369 Sep 29 02:27 /home/student/www/index.html
请问 vbird 这个帐号(不属于student群组)能否读取 index.html 这个文件呢?答:虽然 www与 index.html 是可以让 vbird 读取的权限,但是因为目录结构是由根目录一层一层读取的,因此 vbird 可进入 /home 但是却不可进入 /home/student/ ,既然连进入 /home/student 都不许了, 当然就读不到 index.html 了!所以答案是“vbird不会读取到 index.html 的内容”喔!那要如何修改权限呢?其实只要将 /home/student 的权限修改为最小 711 ,或者直接给予755 就可以啰!
6.7 重点回顾
- 绝对路径:“一定由根目录 / 写起”;相对路径:“不由 / 写起,而是由相对当前目录写起”
- 特殊目录有:., .., -, ~, ~account需要注意;
- 与目录相关的指令有:cd, mkdir, rmdir, pwd 等重要指令;
- rmdir 仅能删除空目录,要删除非空目录需使用“ rm -r ”指令;
- 使用者能使用的指令是依据 PATH 变量所规定的目录去搜寻的;
- ls 可以检视文件的属性,尤其 -d, -a, -l 等选项特别重要!
- 文件的复制、删除、移动可以分别使用:cp, rm , mv等指令来操作;
- 检查文件的内容(读档)可使用的指令包括有:cat, tac, nl, more, less, head, tail, od 等
- cat -n 与 nl 均可显示行号,但默认的情况下,空白行会不会编号并不相同;
- touch 的目的在修改文件的时间参数,但亦可用来创建空文件;
- 一个文件记录的时间参数有三种,分别是 access time(atime), status time (ctime), modification time(mtime),ls 默认显示的是 mtime。
- 除了传统的rwx权限之外,在Ext2/Ext3/Ext4/xfs文件系统中,还可以使用chattr与lsattr设置及观察隐藏属性。 常见的包括只能新增数据的 +a 与完全不能更动文件的 +i 属性。
- 新建文件/目录时,新文件的默认权限使用 umask 来规范。默认目录完全权限为
drwxrwxrwx, 文件则为-rw-rw-rw-。 - 文件具有SUID的特殊权限时,代表当使用者执行此一binary程序时,在执行过程中使用者会暂时具有程序拥有者的权限
- 目录具有SGID的特殊权限时,代表使用者在这个目录下面新建的文件之群组都会与该目录的群组名称相同。
- 目录具有SBIT的特殊权限时,代表在该目录下使用者创建的文件只有自己与root能够删除!
- 观察文件的类型可以使用 file 指令来观察;
- 搜寻指令的完整文件名可用 which 或 type ,这两个指令都是通过 PATH 变量来搜寻文件名;
- 搜寻文件的完整文件名可以使用 whereis 找特定目录或 locate 到数据库去搜寻,而不实际搜寻文件系统;
- 利用 find 可以加入许多选项来直接查询文件系统,以获得自己想要知道的文件名。