20220810 06. Linux 文件与目录管理
6.1 目录与路径
6.1.1 相对路径与绝对路径
路径(PATH)
-
绝对路径:路径的写法“一定由根目录 / 写起”,例如: /usr/share/doc 这个目录。
-
相对路径:路径的写法“不是由 / 写起”,例如由 /usr/share/doc 要到 /usr/share/man 下面时,可以写成: “cd ../man”这就是相对路径的写法啦!相对路径意指“相对于目前工作目录的路径!”
相对路径的用途
比较方便
绝对路径的用途
绝对路径的正确度要比较好
6.1.2 目录的相关操作
比较特殊的目录:
目录名称 | 描述 |
---|---|
. | 代表此层目录 |
.. | 代表上一层目录 |
- | 代表前一个工作目录 |
~ | 代表“目前使用者身份”所在的主文件夹 |
~account | 代表 account 这个使用者的主文件夹(account是个帐号名称) |
根目录下有没有上层目录(..)存在?有,根目录的上一层(..)与根目录自己(.)是同一个目录
常见的处理目录的指令:
-
cd:变换目录
-
pwd:显示目前的目录
-
mkdir:创建一个新的目录
-
rmdir:删除一个空的目录
ls -ld [目录路径] # 仅展示目录本身
cd (change directory, 变换目录)
su - # 切换身份成为 root
cd [相对路径或绝对路径]
cd ~dmtsai # 去到 dmtsai 这个使用者的主文件夹
cd ~ # 回到自己的主文件夹
cd # 回到自己的主文件夹
cd .. # 去到目前的上层目录
cd - # 回到前一个目录
cd /var/spool/mail # 绝对路径
cd ../postfix # 相对路径
Linux 的默认命令行界面 (bash shell) 具有文件补齐功 能, 你要常常利用 [tab] 按键来达成你的目录完整性
pwd (显示目前所在的目录)
pwd [-P]
# -P :显示出确实的路径,而非使用链接 (link) 路径
cd /var/mail # /var/mail是一个链接文件
pwd # 列出目前的工作目录
pwd -P # 显示链接文件所链接的完整路径
pwd是Print Working Directory的缩写
mkdir (创建新目录)
mkdir [-mp] 目录名称
# -m :设置文件的权限
# -p :帮助你直接将所需要的目录(包含上层目录)递回创建起来
mkdir test # 创建目录
mkdir -p test1/test2/test3/test4 # 创建多层目录
mkdir -m 711 test2 # 创建目录并设置权限
rmdir (删除“空”的目录)
rmdir [-p] 目录名称
# -p :连同“上层”“空的”目录也一起删除
rmdir test # 删除空目录
rmdir -p test1/test2/test3/test4 # 删除多层空目录
rmdir
只能删除空的目录,如果要连目录内文件一并删除,使用 rm -r test
6.1.3 关于可执行文件路径的变量: $PATH
指令ls完整文件名为:/bin/ls(这是绝对 路径), 那你会不会觉得很奇怪:“为什么我可以在任何地方执行/bin/ls这个指令呢? ”
环境变量 PATH
# 显示 PATH
echo $PATH
# 修改 PATH,当前会话有效
PATH="${PATH}:/root"
PATH(一定是大写)这个变量的内容是由一堆目录所组成的,每个目录中间用冒号(:)来隔 开, 每个目录是有“顺序”之分的。
顺序是有意义的,如果在不同目录下存在相同命令,执行顺序在前的目录下的命令。注意:不同用户的PATH不同,顺序也不同
-
不同身份使用者默认的PATH不同,默认能够随意执行的指令也不同(如root与dmtsai);
-
PATH是可以修改的;
-
使用绝对路径或相对路径直接指定某个指令的文件名来执行,会比搜寻PATH来的正确;
-
指令应该要放置到正确的目录下,执行才会比较方便;
-
本目录(.)最好不要放到PATH当中。
6.2 文件与目录管理
6.2.1 文件与目录的检视: ls
ls [-aAdfFhilnrRSt] 文件名或目录名称..
ls [--color={never,auto,always}] 文件名或目录名称..
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 默认显示的只有:非隐藏文件的文件名、 以文件名进行 排序及文件名代表的颜色显示。默认按照字母顺序从小到大
# 范例一:将主文件夹下的所有文件列出来(含属性与隐藏文件)
ls -al ~
# 范例二:承上题,不显示颜色,但在文件名末显示出该文件名代表的类型(type)
ls -alF --color=never ~
# 范例三:完整的呈现文件的修改时间 (modification time)
ls -al --full-time ~
ls 最常被使用到的功能还是那个 -l 的选项,为此,很多 distribution 在默认的情况 中, 已经将 ll
(L 的小写) 设置成为 ls -l
的意思了
6.2.2 复制、删除与移动: cp, rm, mv
cp (copy)
mv (move)
rm (remove)
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)这个指令是非常重要的,不同身份者执行这个指令会有不同的结果产生,尤其是 那个-a, -p的选项, 对于不同身份来说,差异则非常的大
# 范例一:用root身份,将主文件夹下的 .bashrc 复制到 /tmp 下,并更名为 bashrc
cp ~/.bashrc /tmp/bashrc
cp -i ~/.bashrc /tmp/bashrc
## 重复两次复制,会在覆盖前询问进行二次确认
# 范例二:变换目录到/tmp,并将/var/log/wtmp复制到/tmp且观察属性:
cd /tmp
cp /var/log/wtmp . # 复制到当前目录
ls -l /var/log/wtmp wtmp # 在不加任何选项的情况下,文件的某些属性/权限会改变
-rw-rw-r-- 1 root utmp 133248 Aug 11 09:23 /var/log/wtmp
-rw-r--r-- 1 root root 133248 Aug 11 10:26 wtmp
cp -a /var/log/wtmp wtmp_2 # 同时复制文件属性
ls -l /var/log/wtmp wtmp_2
在默认的条件中, cp 的来源文件与目的文件的权限是不同的,目的文件的拥有者通常会是指令操作者本身
# 范例三:复制 /etc/ 这个目录下的所有内容到 /tmp 下面
cp -r /etc/ /tmp # 复制目录,-a 也可以
# 范例四:将范例一复制的 bashrc 创建一个链接文件 (symbolic link)
cp -s bashrc bashrc_slink # 符号链接
cp -l bashrc bashrc_hlink # 实体链接
ls -l bashrc*
-rw-r--r-- 2 root root 434 Aug 11 10:24 bashrc
-rw-r--r-- 2 root root 434 Aug 11 10:24 bashrc_hlink
lrwxrwxrwx 1 root root 6 Aug 11 10:31 bashrc_slink -> bashrc
使用 -l 及 -s 都会创建所谓的链接文件(link file)
-l 就是所谓的实体链接(hard link),至于 -s 则 是符号链接(symbolic link)
# 范例五:若 ~/.bashrc 比 /tmp/bashrc 新才复制过来
cp -u ~/.bashrc /tmp/bashrc # 常被用于“备份”的工作,增量更新
# 范例六:将范例四造成的 bashrc_slink 复制成为 bashrc_slink_1 与bashrc_slink_2
cp bashrc_slink bashrc_slink_1 # cp 一个符号链接,复制的是文件本身
cp -d bashrc_slink bashrc_slink_2 # -d 参数指示复制符号链接
ls -l bashrc bashrc_slink*
-rw-r--r-- 2 root root 434 Aug 11 10:24 bashrc
lrwxrwxrwx 1 root root 6 Aug 11 10:31 bashrc_slink -> bashrc
-rw-r--r-- 1 root root 434 Aug 11 10:33 bashrc_slink_1
lrwxrwxrwx 1 root root 6 Aug 11 10:33 bashrc_slink_2 -> bashrc
# 范例七:将主文件夹的 .bashrc 及 .bash_history 复制到 /tmp 下面
cp ~/.bashrc ~/.bash_history /tmp # 将多个数据一次复制到同一个目录去!最后面一定是目录
能否使用 dmtsai 的身份,完整的复制/var/log/wtmp文件到/tmp下面,并更名为 dmtsai_wtmp呢?
cp -a /var/log/wtmp /tmp/dmtsai_wtmp
ls -l /var/log/wtmp /tmp/dmtsai_wtmp
-rw-rw-r-- 1 dmtsai dmtsai 133248 Aug 11 09:23 /tmp/dmtsai_wtmp
-rw-rw-r-- 1 root utmp 133248 Aug 11 09:23 /var/log/wtmp
由于 dmtsai 的身份并不能随意修改文件的拥有者与群组,因此虽然能够复制wtmp的相关权限 与时间等属性, 但是与拥有者、群组相关的,原本 dmtsai 身份无法进行的动作,即使加上 - a 选项,也是无法达成完整复制权限的!
由于 cp 有种种的文件属性与权限的特性,所以,在复制时,你必须要清楚的了解到:
-
是否需要完整的保留来源文件的信息?
-
来源文件是否为链接文件 (symbolic link file)?
-
来源文件是否为特殊的文件,例如 FIFO, socket 等?
-
来源文件是否为目录?
rm (移除文件或目录)
rm [-fir] 文件或目录
选项与参数:
-f :就是 force 的意思,忽略不存在的文件,不会出现警告讯息;
-i :互动模式,在删除前会询问使用者是否动作
-r :递回删除啊!最常用在目录的删除了!这是非常危险的选项!!!
# 范例一:将刚刚在 cp 的范例中创建的 bashrc 删除掉
cd /tmp
rm -i bashrc # 删除前二次确认
# 范例二:通过万用字符*的帮忙,将/tmp下面开头为bashrc的文件名通通删除:
rm -i bashrc*
# 范例三:将 cp 范例中所创建的 /tmp/etc/ 这个目录删除掉!
rmdir /tmp/etc # 删除空目录
rm -r /tmp/etc # 删除目录
# 范例四:删除一个带有 - 开头的文件
touch ./-aaa-
rm ./-aaa-
通常在Linux系统下,为了怕文件被 root 误杀, 所以很多 distributions 都已经默认加入 -i 这个选项
mv (移动文件与目录,或更名)
mv [-fiu] source destination
mv [options] source1 source2 source3 .... directory
选项与参数:
-f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
-i :若目标文件 (destination) 已经存在时,就会询问是否覆盖!
-u :若目标文件已经存在,且 source 比较新,才会更新 (update)
# 范例一:复制一文件,创建一目录,将文件移动到目录中
cd /tmp
cp ~/.bashrc bashrc
mkdir mvtest
mv bashrc mvtest # 复制文件到目录中
# 范例二:将刚刚的目录名称更名为 mvtest2
mv mvtest mvtest2 # 目录重命名
# 范例三:再创建两个文件,再全部移动到 /tmp/mvtest2 当中
cp ~/.bashrc bashrc1
cp ~/.bashrc bashrc2
mv bashrc1 bashrc2 mvtest2 # 移动多个文件到目录
rename 命令, 可以用来更改大量文件的文件名
6.2.3 取得路径的文件名称与目录名称
取得文件名或者是目录名称,一般的用途应该是在写程序的时候用来判断 之用的
basename /etc/sysconfig/network # 路径的文件名
network
dirname /etc/sysconfig/network # 路径的目录名
/etc/sysconfig
6.3 文件内容查阅
-
cat 由第一行开始显示文件内容
-
tac 从最后一行开始显示,可以看出 tac 是 cat 的倒着写!
-
nl 显示的时候,顺道输出行号!
-
more 一页一页的显示文件内容
-
less 与 more 类似,但是比 more 更好的是,他可以往前翻页!
-
head 只看头几行
-
tail 只看尾巴几行
-
od 以二进制的方式读取文件内容!
6.3.1 直接检视文件内容
cat (concatenate)
cat 是 Concatenate (连续) 的简写
cat [-AbEnTv]
选项与参数:
-A :相当于 -vET 的整合选项,可列出一些特殊字符而不是空白而已;
-b :列出行号,仅针对非空白行做行号显示,空白行不标行号!
-E :将结尾的断行字符 $ 显示出来;
-n :打印出行号,连同空白行也会有行号,与 -b 的选项不同;
-T :将 [tab] 按键以 ^I 显示出来;
-v :列出一些看不出来的特殊字符
# 范例一:检阅 /etc/issue 这个文件的内容
cat /etc/issue
# 范例二:承上题,如果还要加印行号呢?
cat -n /etc/issue # 如果不想要编排空白行的行号,可以使用 -b
# 范例三:将 /etc/man_db.conf 的内容完整的显示出来(包含特殊字符)
cat -A /etc/man_db.conf
[tab]会以 ^I
表示, 断行字符则是以 $
表示!不过断行字符在Windows/Linux则不太相同,Windows的断行字符是 ^M$
tac (反向列示)
tac 刚好是 将 cat 反写过来,所以他的功能就跟 cat 相反
cat 是由“第一行到最后一行连续显示在屏 幕上”,而 tac 则是“ 由最后一行到第一行反向在屏幕上显示出来 ”
nl (添加行号打印)
nl [-bnw] 文件
选项与参数:
-b :指定行号指定的方式,主要有两种:
-b a :表示不论是否为空行,也同样列出行号(类似 cat -n);
-b t :如果有空行,空的那一行不要列出行号(默认值);
-n :列出行号表示的方法,主要有三种:
-n ln :行号在屏幕的最左方显示;
-n rn :行号在自己字段的最右方显示,且不加 0 ;
-n rz :行号在自己字段的最右方显示,且加 0 ;
-w :行号字段的占用的字符数。
# 范例一:用 nl 列出 /etc/issue 的内容
nl /etc/issue
nl -b a /etc/issue # 空行也加上行号
nl -b a -n rz /etc/issue # 行号前面自动补上 0
nl -b a -n rz -w 3 /etc/issue # 行号改成3位数
6.3.2 可翻页检视
more (一页一页翻动)
more /etc/man_db.conf
-
空白键 (space):代表向下翻一页;
-
Enter :代表向下翻“一行”;
-
/字串 :代表在这个显示的内容当中,向下搜寻“字串”这个关键字;
- 重复搜寻同一个字串, 可以按下 n
-
:f :立刻显示出文件名以及目前显示的行数;
-
q :代表立刻离开 more ,不再显示该文件内容。
-
b 或 [ctrl]-b :代表往回翻页,不过这动作只对文件有用,对管线无用。
less (一页一页翻动)
less /etc/man_db.conf
less 的用法比起 more 又更加的有弹性
-
空白键 :向下翻动一页;
-
[pagedown]:向下翻动一页;
-
[pageup] :向上翻动一页;
-
/字串 :向下搜寻“字串”的功能;
-
?字串 :向上搜寻“字串”的功能;
-
n :重复前一个搜寻 (与 / 或 ? 有关!)
-
N :反向的重复前一个搜寻 (与 / 或 ? 有关!)
-
g :前进到这个数据的第一行去;
-
G :前进到这个数据的最后一行去 (注意大小写);
-
q :离开 less 这个程序;
man这个指 令就是调用 less 来显示说明文档的内容的
6.3.3 数据撷取
head (取出前面几行)
head [-n number] 文件
选项与参数:
-n :后面接数字,代表显示几行的意思
head /etc/man_db.conf # 默认取前10行
head -n 20 /etc/man_db.conf # 取前20行
head -n -100 /etc/man_db.conf # 后面100行都不打印,只打印前面几行
举例来说 CentOS 7.1 的 /etc/mandb.conf 共有131行, 则上述的指令“head -n -100 /etc/man_db.conf” 就会列出前面31行,后面100行不会打印出来 了。
tail (取出后面几行)
tail [-n number] 文件
选项与参数:
-n :后面接数字,代表显示几行的意思
-f :表示持续侦测后面所接的文件名,要等到按下[ctrl]-c才会结束tail的侦测
tail /etc/man_db.conf # 默认取后10行
tail -n 20 /etc/man_db.conf # 取后20行
tail -n +100 /etc/man_db.conf # 列出100行以后的数据
tail -f /var/log/messages # 持续侦测/var/log/messages的内容
# 要显示 /etc/man_db.conf 的第 11 到第 20 行
head -n 20 /etc/man_db.conf | tail -n 10
# 承上一题,列出正确的行号
cat -n /etc/man_db.conf | head -n 20 | tail -n 10
指令中间有个管线 (|) 的符号存在,这个管线的意思是:“前面的指令所输出的讯 息,请通过管线交由后续的指令继续使用”的意思。
6.3.4 非纯文本文件: od
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方式来展现!
od -t c /usr/bin/passwd
# 范例二:请将/etc/issue这个文件的内容以8进位列出储存值与ASCII的对照表
od -t oCc /etc/issue
# 范例三:找到 password 这几个字的 ASCII 对照
echo password | od -t oCc
这个指令可以将 binary file 的内容作一个大 致的输出
6.3.5 修改文件时间或创建新文件: touch
每个文件在linux下面都会记录许多的时间参数, 其 实是有三个主要的变动时间
-
modification time (mtime): 当该文件的“内容数据”变更时,就会更新这个时间!内 容数据指的是文件的内容,而不是文件的属性或权限
-
status time (ctime): 当该文件的“状态 (status)”改变时,就会更新这个时间,举 例来说,像是权限与属性被更改了,都会更新这个时间
-
access time (atime): 当“该文件的内容被取用”时,就会更新这个读取时间 (access)。举例来说,我们使用 cat 去读取 /etc/man_db.conf , 就会更新该文件的 atime 了(实际测试cat并不会改变atime)
atime 不变的问题参考:为什么 linux 的文件访问时间 atime 不会变化?
date; ll /etc/man_db.conf ; ll --time=atime /etc/man_db.conf ; ll --time=ctime /etc/man_db.conf
Thu Aug 11 14:21:24 CST 2022 # 当前时间
-rw-r--r-- 1 root root 5171 Oct 31 2018 /etc/man_db.conf # mtime
-rw-r--r-- 1 root root 5171 Oct 31 2018 /etc/man_db.conf # atime
-rw-r--r-- 1 root root 5171 Oct 29 2019 /etc/man_db.conf # ctime
在默认的情况下,ls 显示出来的是该文件的 mtime ,也就是这个文件的内容上次 被更动的时间
系统时间可能会“来自未来”
touch [-acdmt] 文件
选项与参数:
-a :仅修订 access time;
-c :仅修改文件的时间,若该文件不存在则不创建新文件;
-d :后面可以接欲修订的日期而不用目前的日期,也可以使用 --date="日期或时间"
-m :仅修改 mtime ;
-t :后面可以接欲修订的时间而不用目前的时间,格式为[YYYYMMDDhhmm]
# 范例一:新建一个空的文件并观察时间
cd /tmp
touch testtouch
ls -l testtouch
## 在默认的状态下,如果 touch 后面有接文件, 则该文件的三个时间 (atime/ctime/mtime) 都会更新为目前的时间。若该文件不存在, 则会主动的创建一个新的空的文件
# 范例二:将 ~/.bashrc 复制成为 bashrc,假设复制完全的属性,检查其日期
cp -a ~/.bashrc bashrc
date; ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc
# 范例三:修改案例二的 bashrc 文件,将日期调整为两天前
touch -d "2 days ago" bashrc # ctime 不变
# 范例四:将上个范例的 bashrc 日期改为 2014/06/15 2:02
touch -t 201406150202 bashrc # ctime 不变
touch 这个指令最常被使用的情况是:
-
创建一个空的文件;
-
将某个文件日期修订为目前 (mtime 与 atime)
6.4 文件与目录的默认权限与隐藏权限
除了基本r, w, x权限外,在Linux传统的Ext2/Ext3/Ext4文件系统下,我们还可以设置其他的系 统隐藏属性, 这部份可使用 chattr 来设置,而以 lsattr 来查看,最重要的属性就是可以设置 其不可修改的特性
6.4.1 文件默认权限:umask
当你创 建一个新的文件或目录时,他的默认权限会是什么
umask 就是指定 “目前使用者在创建文件或目录时 候的权限默认值”
umask # 数字体态的权限设置分数
0022
umask -S # 会以符号类型的方式来显示出权限
u=rwx,g=rx,o=rx
怎么 umask 会有四组数字啊?不是只有三组吗?第一组是特殊权限用的,我们先 不要理他,所以先看后面三组即可
在默认权限的属性上,目录与文件是不一样的。
-
若使用者创建为“文件”则默认“没有可执行( x )权限”,亦即只有 rw 这两个项目,也就是最大为 666 分,默认权限如下: -rw-rw-rw-
-
若使用者创建为“目录”,则由于 x 与是否可以进入此目录有关,因此默认为所有权限均开放,亦即为 777 分,默认权限如下: drwxrwxrwx
umask 的分数指的是“该默认值需要减掉的权限!”
因为 umask 为 022,所以 user 并没有被拿掉任何权限,不 过 group 与 others 的权限被拿掉了 2 (也就是 w 这个权限)
-
创建文件时:(-rw-rw-rw-) - (-----w--w-) ==> -rw-r--r--
-
创建目录时:(drwxrwxrwx) - (d----w--w-) ==> drwxr-xr-x
touch test1
mkdir test2
umask
0022
ll -d test*
-rw-r--r-- 1 root root 0 Aug 11 15:00 test1
drwxr-xr-x 2 root root 4096 Aug 11 15:00 test2
umask的利用与重要性:专题制作
umask 002 # 修改umask,当前会话有效
6.4.2 文件隐藏属性
这些隐藏的属性确实对于系统有很大的 帮助的~ 尤其是在系统安全 (Security) 上面
chattr指令只能在Ext2/Ext3/Ext4的 Linux 传统文件系统上面完整生效, 其他的文件系统可能 就无法完整的支持这个指令了,例如 xfs 仅支持部份参数而已
chattr (设置文件隐藏属性)
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 的参数,尝试删除看看。
cd /tmp
touch attrtest # 创建一个空文件
chattr +i attrtest # 给予 i 的属性
rm attrtest # 尝试删除看看,报错
# 范例:请将该文件的 i 属性取消!
chattr -i attrtest
个人认为最重要的当属 +i 与 +a 这个属性了
lsattr (显示文件隐藏属性)
lsattr [-adR] 文件或目录
选项与参数:
-a :将隐藏文件的属性也秀出来;
-d :如果接的是目录,仅列出目录本身的属性而非目录内的文件名;
-R :连同子目录的数据也一并列出来!
chattr +aiS attrtest
lsattr attrtest
--S-ia-------e-- attrtest
6.4.3 文件特殊权限: SUID, SGID, SBIT
ll -d /tmp/
drwxrwxrwt 10 root root 4096 Aug 11 15:27 /tmp/
ll /usr/bin/passwd
-rwsr-xr-x 1 root root 27856 May 1 2020 /usr/bin/passwd
权限里的s和t是什么?
Set UID
当 s 这个标志出现在文件拥有者的 x 权限上时,例如刚刚提到的 /usr/bin/passwd 这个文件的 权限状态:“-rwsr-xr-x”,此时就被称为 Set UID,简称为 SUID 的特殊权限
SUID有这样的限制与功能:
-
SUID 权限仅对二进制程序(binary program)有效;
-
执行者对于该程序需要具有 x 的可执行权限;
-
本权限仅在执行该程序的过程中有效 (run-time);
-
执行者将具有该程序拥有者 (owner) 的权限。
Linux 系统中,所有帐号的密码都记录在 /etc/shadow 这个文件里面,这个文件的权限 为:“---------- 1 root root”,意思是这个文件仅有root可读且仅有root可以强制写入而已。 既然这个文件仅有 root 可以修改,那么鸟哥的 dmtsai 这个一般帐号使用者能否自行修改自己的密 码呢? 一般使用者可以使用 passwd 修改自己的密码了!
-
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 仅可用在binary program 上, 不能够用在 shell script 上面!这是因为 shell script 只是将很多的 binary 可执行文件叫进来执行而已!所以 SUID 的权限部分,还是得要看 shell script 调用进来的程序的设置, 而不是 shell script 本身。当然,SUID 对于目录也是无 效的
Set GID
s 在群组的 x 时则称为 Set GID, SGID
ls -l /usr/bin/locate
-rwx--s--x. 1 root slocate 40496 Jun 10 2014 /usr/bin/locatel
与 SUID 不同的是,SGID 可以针对文件或目录来设置
-
SGID 对二进制程序有用;
-
程序执行者对于该程序来说,需具备 x 的权限;
-
执行者在执行的过程中将会获得该程序群组的支持!
举例来说,上面的 /usr/bin/locate 这个程序可以去搜寻 /var/lib/mlocate/mlocate.db 这个文件 的内容,mlocate.db 的权限如下:
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
除了 binary program 之外,事实上 SGID 也能够用在目录上,这也是非常常见的一种用途! 当一个目录设置了 SGID 的权限后,他将具有如下的功能:
-
使用者若对于此目录具有 r 与 x 的权限时,该使用者能够进入此目录;
-
使用者在此目录下的有效群组(effective group)将会变成该目录的群组;
-
用途:若使用者在此目录下具有 w 的权限(可以新建文件),则使用者所创建的新文件,该新文件的群组与此目录的群组相同。
Sticky Bit
SBIT 目前只针对目录有效
SBIT 对于目录的作用是:
-
当使用者对于此目录具有 w, x 权限,亦即具有写入的权限时;
-
当使用者在该目录下创建文件或目录时,仅有自己与 root 才有权力删除该文件
/tmp 本身的权限是“drwxrwxrwt”
SUID/SGID/SBIT 权限设置
-
4 为 SUID
-
2 为 SGID
-
1 为 SBIT
cd /tmp
touch test # 创建一个测试用空档
chmod 4755 test; ls -l test # 加入具有 SUID 的权限
-rwsr-xr-x 1 root root 0 Jun 16 02:53 test
chmod 6755 test; ls -l test # 加入具有 SUID/SGID 的权限
-rwsr-sr-x 1 root root 0 Jun 16 02:53 test
chmod 1755 test; ls -l test # 加入 SBIT 的功能!
-rwxr-xr-t 1 root root 0 Jun 16 02:53 test
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 为 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
6.4.4 观察文件类型:file
如果你想要知道某个文件的基本数据,例如是属于 ASCII 或者是 data 文件,或者是 binary , 且其中有没有使用到动态函数库 (share library) 等等的信息,就可以利用 file 这个指令 来检阅
file ~/.bashrc
/root/.bashrc: ASCII text # 是 ASCII 的纯文本文件
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 的动态函数库链接等等。
file /var/lib/mlocate/mlocate.db
/var/lib/mlocate/mlocate.db: data # data 文件# data 文件
6.5 指令与文件的搜寻
6.5.1 指令文件名的搜寻
连续输入两次[tab]按键就能够知道使用者有多少指令可以下 达。 那你知不知道这些指令的完整文件名放在哪里?
which (寻找“可执行文件”)
which [-a] command
选项或参数:
-a :将所有由 PATH 目录中可以找到的指令均列出,而不止第一个被找到的指令名称
# 范例一搜寻 ifconfig 这个指令的完整文件名
which ifconfig
/usr/sbin/ifconfig
# 范例二:用 which 去找出 which 的文件名为何?
which which
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
/usr/bin/alias
/usr/bin/which
## alias 就是所谓的“命令别名”,意思是输入 which 会等于后面接的那串指令
# 范例三:请找出 history 这个指令的完整文件名
which history
/usr/bin/which: no history in (/opt/rh/devtoolset-9/root/usr/bin:/opt/rh/rh-postgresql12/root/usr/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/data/soft/TencentKona-8.0.4-272/bin:/data/soft/TencentKona-8.0.4-272/jre/bin:/data/soft/apache-zookeeper-3.6.3-bin/bin:/data/soft/kafka_2.13-2.7.2/bin:/usr/local/go/bin:/home/go/bin:/usr/local/go/bin:/root/go/bin:/root/.ft:/root/bin)
history --help
-bash: history: --: invalid option
history: usage: history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]
which 指令是根据“PATH”这个环境变量所规范的路径,去搜寻“可执行文件”的文件名
怎么 history 这个常用的指令竟然找不到啊!为什么呢?这是因为 history 是“bash 内置的指令”啦! 但是 which 默认是找 PATH 内所规范的目录,所以当然一定 找不到的啊(有 bash 就有 history!)
6.5.2 文件文件名的搜寻
通常 find 不很常用 的!因为速度慢之外, 也很操硬盘!一般我们都是先使用 whereis 或者是 locate 来检查,如 果真的找不到了,才以 find 来搜寻
whereis 只找系统中某些特定目录下 面的文件而已,locate 则是利用数据库来搜寻文件名
whereis (由一些特定的目录中寻找文件文件名)
whereis [-bmsu] 文件或目录名
选项与参数:
-l :可以列出 whereis 会去查询的几个主要目录而已
-b :只找 binary 格式的文件
-m :只找在说明文档 manual 路径下的文件
-s :只找 source 来源文件
-u :搜寻不在上述三个项目当中的其他特殊文件
# 范例一:请找出 ifconfig 这个文件名
whereis ifconfig
# 范例二:只找出跟 passwd 有关的“说明文档”文件名(man page)
whereis passwd # 全部的文件名通通列出来
whereis -m passwd # 只有在 man 里面的文件名才抓出来!
locate / updatedb
yum install mlocate # 安装
updatedb # 更新数据库,否则无法使用
locate [-ir] keyword
选项与参数:
-i :忽略大小写的差异;
-c :不输出文件名,仅计算找到的文件数量
-l :仅输出几行的意思,例如输出五行则是 -l 5
-S :输出 locate 所使用的数据库文件的相关信息,包括该数据库纪录的文件/目录数量等
-r :后面可接正则表达式的显示方式
# 范例一:找出系统中所有与 passwd 相关的文件名,且只列出 5 个
locate -l 5 passwd
# 范例二:列出 locate 查询所使用的数据库文件之文件名与各数据数量
locate -S
locate 是经由数据库来搜寻的,而数据库的创建默认是在每天执行 一次 (每个 distribution 都不同,CentOS 7.x 是每天更新数据库一次!),所以当你新创建 起来的文件, 却还在数据库更新之前搜寻该文件,那么 locate 会告诉你“找不到!
-
updatedb:根据 /etc/updatedb.conf 的设置去搜寻系统硬盘内的文件名,并更新/var/lib/mlocate 内的数据库文件;
-
locate:依据 /var/lib/mlocate 内的数据库记载,找出使用者输入的关键字文件名。
find
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) 的文件列出
find / -mtime 0
# 0 代表目前的时间,所以,从现在开始到 24 小时前,有变动过内容的文件都会被列出来!
# 那如果是三天前的 24 小时内? find / -mtime 3
# 范例二:寻找 /etc 下面的文件,如果文件日期比 /etc/passwd 新就列出
find /etc -newer /etc/passwd
# -newer 用在分辨两个文件之间的新旧关系是很有用的!新的文件文件名
# 4天内被更动过 的文件文件名
find /var -mtime -4
# 4天前的那一天
find /var -mtime 4
# 4天前(不包括4天)被更动过 的文件文件名
find /var -mtime +4
-
+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 的文件
find /home -user dmtsai
# 范例四:搜寻系统中不属于任何人的文件
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 这个文件
find / -name passwd
# 范例五-1:找出文件名包含了 passwd 这个关键字的文件
find / -name "*passwd*"
# -name默认是完整文件名,如果想要找关键字,可以使用类似 * 的任意字符来处理
# 范例六:找出 /run 目录下,文件类型为 Socket 的文件名有哪些?
find /run -type s
# 范例七:搜寻文件当中含有 SGID 或 SUID 或 SBIT 的属性
find / -perm /7000
# 所谓的 7000 就是 ---s--s--t ,那么只要含有 s 或 t 的就列出,所以当然要使用 /7000,
# 使用 -7000 表示要同时含有 ---s--s--t 的所有三个权限。而只需要任意一个,就是 /7000
# 找出来 /usr/bin, /usr/sbin 这两个 目录下, 只要具有 SUID 或 SGID 就列出来该文件
find /usr/bin /usr/sbin -perm /6000
选项与参数:
4\. 额外可进行的动作:
-exec command :command 为其他指令,-exec 后面可再接额外的指令来处理搜寻到的结果。
-print :将结果打印到屏幕上,这个动作是默认动作!
# 范例八:将上个范例找到的文件使用 ls -l 列出来
find /usr/bin /usr/sbin -perm /7000 -exec ls -l {} \; # -exec 后面的 ls -l 就是额外的指令,指令不支持命令别名, 不可以使用 ll
# 范例九:找出系统中,大于 1MB 的文件
find / -size +1M
find 的特殊功能就是能够进行额外的动作(action)
-
{} 代表的是“由 find 找到的内容”,如上图所示,find 的结果会被放置到 {} 位置中;
-
-exec 一直到 ; 是关键字,代表 find 额外动作的开始 (-exec) 到结束 (;) ,在这中间的就是 find 指令内的额外动作。 在本例中就是“ ls -l {} ”啰!
-
因为“ ; ”在 bash 环境下是有特殊意义的,因此利用反斜线来跳脱。
# 找出 /etc 下面文件名包含 httpd 的文件
find /etc -name '*httpd*'
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 就可以啰!