红茶的个人站点

  • 首页
  • 专栏
  • 开发工具
  • 其它
  • 隐私政策
Awalon
Talk is cheap,show me the code.
  1. 首页
  2. 专栏
  3. Linux之旅
  4. 正文

Linux 之旅 4:文件与目录管理

2021年8月10日 1070点热度 0人点赞 0条评论

目录与路径

相对路径与绝对路径

这个相当基础,所以这里不过多阐述,不了解的可以搜索其他资料学习。

目录的相关操作

在Linux中有这么几个目录相关的特殊符号需要留意:

  • .表示当前目录

  • ..表示上层目录

  • -表示之前所在的目录

  • ~表示当前用户的家目录

  • ~account表示用户account的家目录

和目录相关的命令主要有:

  • cd:将当前的工作目录切换到指定目录

  • pwd:打印当前工作目录的完整路径

  • mkdir:新建目录

  • rmdir:删除目录

cd

我们看cd命令(change directory)的实际使用示例:

[icexmoon@xyz ~]$ su -
密码:
上一次登录:一 8月  9 16:16:12 CST 2021pts/0 上
ABRT has detected 1 problem(s). For more info run: abrt-cli list --since 1628496972
[root@xyz ~]# pwd
/root
[root@xyz ~]# cd ~icexmoon
[root@xyz icexmoon]# pwd
/home/icexmoon
[root@xyz icexmoon]# cd -
/root
[root@xyz ~]# pwd
/root
[root@xyz ~]# cd /
[root@xyz /]# exit
登出

pwd

pwd对应的英文是print working directory,即打印工作目录,我们看实例:

[icexmoon@xyz ~]$ cd /var/mail
[icexmoon@xyz mail]$ pwd
/var/mail
[icexmoon@xyz mail]$ pwd -P
/var/spool/mail
[icexmoon@xyz mail]$ ls -ald /var/mail
lrwxrwxrwx. 1 root root 10 7月  24 14:33 /var/mail -> spool/mail

需要注意的是,如果使用-P参数,如果当前工作目录是一个符号链接,则会显示其指向的真实路径,这点我们通过ls命令可以证实。

mkdir

mkdir(make directory)的用途是创建一个新目录:

[icexmoon@xyz mail]$ mkdir /tmp/test2
[icexmoon@xyz mail]$ ls -ald /tmp/test2
drwxrwxr-x. 2 icexmoon icexmoon 6 8月   9 19:40 /tmp/test2
[icexmoon@xyz mail]$ mkdir /tmp/test2/test3/test4/test5
mkdir: 无法创建目录"/tmp/test2/test3/test4/test5": 没有那个文件或目录
[icexmoon@xyz mail]$ mkdir -p /tmp/test2/test3/test4/test5
[icexmoon@xyz mail]$ ls -ald /tmp/test2/test3/test4/test5
drwxrwxr-x. 2 icexmoon icexmoon 6 8月   9 19:41 /tmp/test2/test3/test4/test5

命令本身没有什么值得说的,只要权限正确,就可以创建相应的目录。

需要注意的是默认状态是无法创建多个“级联”目录的,即你只能在一个已经存在的目录下创建一个新目录,如果你想一次性创建多层本来不存在的目录,可以使用-p参数。

rmdir

rmdir(remove directory)的用途是删除一个空目录,需要注意的是必须是空目录才能用这个命令删除。

[icexmoon@xyz mail]$ rmdir /tmp/test2/test3/test4/test5
[icexmoon@xyz mail]$ ls -al /tmp/test2/test3/test4/
总用量 0
drwxrwxr-x. 2 icexmoon icexmoon  6 8月   9 19:45 .
drwxrwxr-x. 3 icexmoon icexmoon 19 8月   9 19:41 ..
[icexmoon@xyz mail]$ sudo rmdir -p /tmp/test2/test3/test4
rmdir: 删除目录 "/tmp" 失败: 设备或资源忙
[icexmoon@xyz mail]$ ls -al /tmp/test*
总用量 4
drwxrwxr-x.  2 icexmoon icexmoon    6 8月   8 17:28 .
drwxrwxrwt. 22 root     root     4096 8月   9 19:47 ..
[icexmoon@xyz mail]$

默认情况下这个命令仅会删除目标目录,如果你想将目标目录层级中的所有空目录一起删除的话,可以使用-p参数,虽然在实例中执行rmdir -p显示删除/tmp失败,但实际上/tmp/test2、/tmp/test2/test3等中间层级的空目录都被删除了,而/tmp不是空目录,所以没有删除,这显然是复合我们期望的。

实际上这个命令使用频率并不高,因为大多数情况下我们需要删除的目录都不是空目录,此时我们需要执行的命令是rm -r 目录,当然执行这个命令要慎重,删除了关键文件会导致系统无法开机,这也是为什么不推荐使用root用户进行日常工作。

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

和Windows一样,Linux同样是借助环境变量来实现对可执行命令的检索,甚至变量名也同样是PATH,我们可以通过echo命令来进行查看当前用户的该变量:

[icexmoon@xyz mail]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/icexmoon/.local/bin:/home/icexmoon/bin

不同的路径使用:进行分割。

可以看到,就像之前说的,FHS规定常用的应用会放在/usr/bin以及/usr/sbin,而这两个目录都在环境变量PATH中,所以我们是可以在命令行下直接执行的,此外可以看到用户的家目录下的.local/bin和bin也已经被写入PATH,所以用户自己安装的应用可以放在这两个地方,就可以直接执行。

此外,如果我们需要把某个目录加入PATH变量,可以这样:

[icexmoon@xyz mail]$ PATH="${PATH}:/root"
[icexmoon@xyz mail]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/icexmoon/.local/bin:/home/icexmoon/bin:/root

文件与目录管理

ls

ls命令用于查看目录和文件的信息:

[icexmoon@xyz mail]$ ls -al ~
总用量 48
drwx------. 15 icexmoon icexmoon 4096 8月   9 14:58 .
drwxr-xr-x.  3 root     root       22 7月  24 14:45 ..
-rw-------.  1 icexmoon icexmoon 5373 8月   9 16:43 .bash_history
-rw-r--r--.  1 icexmoon icexmoon   18 4月   1 2020 .bash_logout
-rw-r--r--.  1 icexmoon icexmoon  193 4月   1 2020 .bash_profile
-rw-r--r--.  1 icexmoon icexmoon  231 4月   1 2020 .bashrc
drwx------. 19 icexmoon icexmoon 4096 8月   9 15:01 .cache
drwxr-xr-x. 16 icexmoon icexmoon 4096 7月  29 16:16 .config
drwx------.  3 icexmoon icexmoon   25 7月  24 14:49 .dbus

这是最常用的方式,可以查看所有文件(包括.开头的隐藏文件)的信息。

[icexmoon@xyz mail]$ ls -alF --color=never ~
总用量 48
drwx------. 15 icexmoon icexmoon 4096 8月   9 14:58 ./
drwxr-xr-x.  3 root     root       22 7月  24 14:45 ../
-rw-------.  1 icexmoon icexmoon 5373 8月   9 16:43 .bash_history
-rw-r--r--.  1 icexmoon icexmoon   18 4月   1 2020 .bash_logout
-rw-r--r--.  1 icexmoon icexmoon  193 4月   1 2020 .bash_profile
-rw-r--r--.  1 icexmoon icexmoon  231 4月   1 2020 .bashrc
drwx------. 19 icexmoon icexmoon 4096 8月   9 15:01 .cache/
drwxr-xr-x. 16 icexmoon icexmoon 4096 7月  29 16:16 .config/
drwx------.  3 icexmoon icexmoon   25 7月  24 14:49 .dbus/
-rw-------.  1 icexmoon icexmoon   16 7月  24 14:49 .esd_auth
-rw-------.  1 icexmoon icexmoon 3414 8月   9 14:58 .ICEauthority
-rw-------.  1 icexmoon icexmoon   35 7月  29 17:48 .lesshst
drwx------.  3 icexmoon icexmoon   19 7月  24 14:49 .local/

通常bash终端都可以用颜色区分ls输出的文件和目录,使用--color=never可以屏蔽颜色,使用-F可以让输出的目录结尾加上/以和文件区分。

[icexmoon@xyz mail]$ ls -al --full-time ~
总用量 48
drwx------. 15 icexmoon icexmoon 4096 2021-08-09 14:58:40.156100279 +0800 .
drwxr-xr-x.  3 root     root       22 2021-07-24 14:45:46.681888462 +0800 ..
-rw-------.  1 icexmoon icexmoon 5373 2021-08-09 16:43:06.356025666 +0800 .bash_history
-rw-r--r--.  1 icexmoon icexmoon   18 2020-04-01 10:17:30.000000000 +0800 .bash_logout
-rw-r--r--.  1 icexmoon icexmoon  193 2020-04-01 10:17:30.000000000 +0800 .bash_profile
-rw-r--r--.  1 icexmoon icexmoon  231 2020-04-01 10:17:30.000000000 +0800 .bashrc
drwx------. 19 icexmoon icexmoon 4096 2021-08-09 15:01:45.238097720 +0800 .cache
drwxr-xr-x. 16 icexmoon icexmoon 4096 2021-07-29 16:16:38.468976492 +0800 .config
drwx------.  3 icexmoon icexmoon   25 2021-07-24 14:49:22.547003130 +0800 .dbus

加上--full-time参数可以输出完整时间。

此外很多Linux发行版为了方便设定了alias命令ll,其实就是ls -al。

cp

cp(copy)命令的用途是复制目录或文件,需要注意的是Linux下的目录和文件不仅内容重要,其属性也很重要,所以执行cp命令的用户不同,效果也可能不同。

[root@xyz tmp]# cp /var/log/wtmp .
[root@xyz tmp]# ls -ald /var/log/wtmp wtmp
-rw-rw-r--. 1 root utmp 33408 8月   9 19:30 /var/log/wtmp
-rw-r--r--. 1 root root 33408 8月   9 20:19 wtmp

可以看到复制后的目录的权限是与源目录不同的。

[root@xyz tmp]# cp -a /var/log/wtmp wtmp2
[root@xyz tmp]# ls -ald /var/log/wtmp wtmp2
-rw-rw-r--. 1 root utmp 33408 8月   9 19:30 /var/log/wtmp
-rw-rw-r--. 1 root utmp 33408 8月   9 19:30 wtmp2

要和原文件完全一样的话可以使用-a参数。

此外还有一个细节,如果复制的是目录,目标目录如果已经存在,被复制的目录会被添加到目标目录下边,成为子目录,如果目标目录不存在,则会直接复制过去,并命名为该目录名。

如果要将一个目标目录下的文件拷贝到一个已有目录下,就要这样:

[root@xyz tmp]# cp -ar /etc/* /tmp/etc2
[root@xyz tmp]# ls -al /tmp/etc2
总用量 1364
drwxr-xr-x. 139 root root     8192 8月   9 20:36 .
drwxrwxrwt.  24 root root     4096 8月   9 20:34 ..
drwxr-xr-x.   3 root root      101 7月  24 14:35 abrt
-rw-r--r--.   1 root root       16 7月  24 14:45 adjtime
-rw-r--r--.   1 root root     1529 4月   1 2020 aliases
-rw-r--r--.   1 root root    12288 7月  24 14:47 aliases.db
drwxr-xr-x.   3 root root       65 7月  24 14:37 alsa
drwxr-xr-x.   2 root root     4096 7月  24 14:43 alternatives
-rw-------.   1 root root      541 8月   9 2019 anacrontab
-rw-r--r--.   1 root root       55 8月   8 2019 asound.conf
-rw-r--r--.   1 root root        1 10月 31 2018 at.deny
drwxr-x---.   3 root root       43 7月  24 14:35 audisp

此外复制目录必须要使用-r参数,而且使用-a参数同样可以复制原有文件的属性。

如果复制目录的过程中遇到文件重名,会提示是否要覆盖,如果是大量文件,一个个确认显然不现实,此时可以使用-f参数强制覆盖:

[root@xyz tmp]# cp -ar /etc/* /tmp/etc2
cp:是否覆盖"/tmp/etc2/abrt/abrt-action-save-package-data.conf"? n
cp:是否覆盖"/tmp/etc2/abrt/abrt.conf"? ^C
[root@xyz tmp]# cp -arf /etc/* /tmp/etc2
cp:是否覆盖"/tmp/etc2/abrt/abrt-action-save-package-data.conf"? n
cp:是否覆盖"/tmp/etc2/abrt/abrt.conf"? ^C
[root@xyz tmp]# \cp -arf /etc/* /tmp/etc2

需要注意的是某些Linux发行版出于安全方面的考虑,cp命令本身就是一个alias别名,默认加入-i参数,在这种情况下你加没加-f参数都不起作用,依然会让你进行确认,这种情况下可以在命令前加上\,比如\cp,这样bash就不会使用别名命令,会直接调用原有命令执行。

rm

rm命令(remove)很简单,就是删除目录或文件。

现在用rm删除之前创建的目录:

[root@xyz tmp]# rm -rf wtmp wtmp2
[root@xyz tmp]# rm -rf test
[root@xyz tmp]# rm -rf etc etc2
[root@xyz tmp]# ls -al
总用量 12
drwxrwxrwt. 21 root     root     4096 8月   9 20:45 .
dr-xr-xr-x. 18 root     root      236 8月   8 21:41 ..
-rw-r--r--.  1 root     root      176 8月   9 20:18 bashrc
drwx------.  2 icexmoon icexmoon    6 8月   9 16:03 .esd-1000
drwxrwxrwt.  2 root     root        6 7月  24 14:35 .font-unix
drwxrwxrwt.  2 root     root      174 8月   9 19:29 .ICE-unix

在删除目录的时候需要添加-r参数,如果不想一个个确认是否要删除某某文件可以加入-f参数。

mv

mv(move)命令用于移动目录或文件。

[root@xyz tmp]# cp ~/.bashrc .
[root@xyz tmp]# mkdir test
[root@xyz tmp]# mv .bashrc test
[root@xyz tmp]# ls -al ./test/.bashrc
-rw-r--r--. 1 root root 176 8月   9 20:51 ./test/.bashrc
[root@xyz tmp]# ls -al .bashrc
ls: 无法访问.bashrc: 没有那个文件或目录

值得注意的是,虽然Linux中有一个rename命令,但如果需要对单个目录或者文件重命名,mv命令更为方便:

[root@xyz tmp]# mv bashrc bashrc_rename
[root@xyz tmp]# ls -al bash*
-rw-r--r--. 1 root root 176 8月   9 20:18 bashrc_rename

Linux中的rename命令用于一次性修改大量文件的文件名。

basename\dirname

如果开发过程序的朋友应该知道,程序处理文件系统的时候经常需要根据一个文件路径获取文件名和目录名,bash也有这样的命令:

[root@xyz tmp]# basename /etc/sysconfig/network
network
[root@xyz tmp]# dirname /etc/sysconfig/network
/etc/sysconfig

查看文件内容

这里介绍一些查看文件需要用到的命令。

直接查看文件

cat

cat(concatenate)命令可以直接打印文件内容。

最简单的使用方式:

[icexmoon@xyz ~]$ cat /etc/issue
\S
Kernel \r on an \m

如果需要打印行号:

[icexmoon@xyz ~]$ cat -n /etc/issue
     1  \S
     2  Kernel \r on an \m
     3

如果是开发者,经常需要查看某个文本文件中的特殊字符,比如空格制表符和换行等,就要这样做:

[icexmoon@xyz ~]$ cat -A /etc/man_db.conf
# $
#$
# This file is used by the man-db package to configure the man and cat paths.$
# It is also used to provide a manpath for those without one by examining$
# their PATH environment variable. For details see the manpath(5) man page.$
#$
# Lines beginning with `#' are comments and are ignored. Any combination of$
# tabs or spaces may be used as `whitespace' separators.$
#$
# There are three mappings allowed in this file:$
# --------------------------------------------------------$
# MANDATORY_MANPATH^I^I^Imanpath_element$
# MANPATH_MAP^I^Ipath_element^Imanpath_element$
# MANDB_MAP^I^Iglobal_manpath^I[relative_catpath]$
#---------------------------------------------------------$
# every automatically generated MANPATH includes these fields$
#$
#MANDATORY_MANPATH ^I^I^I/usr/src/pvm3/man$
#$
MANDATORY_MANPATH^I^I^I/usr/man$
MANDATORY_MANPATH^I^I^I/usr/share/man$
MANDATORY_MANPATH^I^I^I/usr/local/share/man$

此时打印出的信息中$表示换行符,^I表示制表符。

tac

tac这个命令从命名上就能看出一些端倪,是cat倒着写,其用途也就是将cat打印的内容倒叙打印。

[icexmoon@xyz ~]$ tac /etc/issue

Kernel \r on an \m
\S

虽然tac就像是cat的逆序输出,但并非支持所有cat的参数,比如-n就不支持,大概是考虑到倒序标识行号会引起误导?

nl

nl会给文件添加行号后打印,其功能类似于cat -n,不过在行号显式方面有更多的选项。

[icexmoon@xyz ~]$ nl /etc/issue
     1  \S
     2  Kernel \r on an \m

[icexmoon@xyz ~]$ nl -b a /etc/issue
     1  \S
     2  Kernel \r on an \m
     3
[icexmoon@xyz ~]$ nl -b t /etc/issue
     1  \S
     2  Kernel \r on an \m

[icexmoon@xyz ~]$ nl -n ln /etc/issue
1       \S
2       Kernel \r on an \m

[icexmoon@xyz ~]$ nl -n rn /etc/issue
     1  \S
     2  Kernel \r on an \m

[icexmoon@xyz ~]$ nl -n rz /etc/issue
000001  \S
000002  Kernel \r on an \m

[icexmoon@xyz ~]$ nl -n rz -w3 /etc/issue
001     \S
002     Kernel \r on an \m

默认情况下nl打印的行号是不会包含空白行的,相当于nl -b t,如果要包含空白行,就要使用nl -b a。

此外默认情况下nl打印额行号是靠左没有0占位的数字,相当于nl -n ln,如果要让行号靠右显式,但不用0占位,可以nl -n rn,如果需要零占位,则使用nl -n rz,如果想指定行号的位宽,可以使用nl -w 3。

翻页查看

除了使用上述命令一次性输出所有文件内容以外,对于内容巨大的文件,我们可以使用支持翻页查看的命令。

more

[icexmoon@xyz ~]$ more /etc/man_db.conf
#
#
# This file is used by the man-db package to configure the man and cat paths.
# It is also used to provide a manpath for those without one by examining
# their PATH environment variable. For details see the manpath(5) man page.
#
# Lines beginning with `#' are comments and are ignored. Any combination of
# tabs or spaces may be used as `whitespace' separators.

进入more命令的模式后,可以执行以下操作:

  • 空格:向下翻页

  • b:向上翻页

  • 回车:向下翻一行

  • /:搜索字符串,回车后进行搜索,按n搜索下一个

  • q:退出

less

less与more的用法类似,但功能更强大。

[icexmoon@xyz ~]$ less /etc/man_db.conf

less中可以执行以下操作:

  • PageUp或b:向上翻页

  • PageDown或空格:向下翻页

  • Home或g:返回首页

  • End或G:前往最后一页

  • /:向下搜搜字符串,使用n搜索下一个,使用N搜索上一个

  • ?:向上搜搜字符串

  • q:退出

可以看出,less除了兼容more上的操作以外,还支持更人性化的键位,比如PageUp和Home等,个人觉得这比more上的键位更好用。此外在less中检索字符串会对结果进行标记,一目了然,而more不会,所以推荐使用less。

数据截取

在开发程序中最常见的数据处理就是截取或切割,对于文件我们同样可以使用相关命令进行类似操作,比如获取开头的几行或结尾的几行,或者指定的x~y行之类的。

head

head命令可以只打印前n行数据:

[icexmoon@xyz ~]$ head /etc/man_db.conf
#
#
# This file is used by the man-db package to configure the man and cat paths.
# It is also used to provide a manpath for those without one by examining
# their PATH environment variable. For details see the manpath(5) man page.
#
# Lines beginning with `#' are comments and are ignored. Any combination of
# tabs or spaces may be used as `whitespace' separators.
#
# There are three mappings allowed in this file:

默认打印前十行,如果需要指定行数,可以:

[icexmoon@xyz ~]$ head -n 5 /etc/man_db.conf
#
#
# This file is used by the man-db package to configure the man and cat paths.
# It is also used to provide a manpath for those without one by examining
# their PATH environment variable. For details see the manpath(5) man page.

如果需要排除最后若干行,可以这样:

[icexmoon@xyz ~]$ head -n -110 /etc/man_db.conf
#
#
# This file is used by the man-db package to configure the man and cat paths.
# It is also used to provide a manpath for those without one by examining
# their PATH environment variable. For details see the manpath(5) man page.
#
# Lines beginning with `#' are comments and are ignored. Any combination of
# tabs or spaces may be used as `whitespace' separators.
#
# There are three mappings allowed in this file:
# --------------------------------------------------------
# MANDATORY_MANPATH                     manpath_element
# MANPATH_MAP           path_element    manpath_element
# MANDB_MAP             global_manpath  [relative_catpath]
#---------------------------------------------------------
# every automatically generated MANPATH includes these fields
#
#MANDATORY_MANPATH                      /usr/src/pvm3/man
#
MANDATORY_MANPATH                       /usr/man
MANDATORY_MANPATH                       /usr/share/man

tail

tail命令与head类似,不过是取最后的若干行。

[icexmoon@xyz ~]$ tail /etc/man_db.conf
# formatted for a terminal of the given width, regardless of the width of
# the terminal actually being used. This should generally be within the
# range set by MINCATWIDTH and MAXCATWIDTH.
#
#CATWIDTH       0
#
#---------------------------------------------------------
# Flags.
# NOCACHE keeps man from creating cat pages.
#NOCACHE
[icexmoon@xyz ~]$ tail -n 10 /etc/man_db.conf
# formatted for a terminal of the given width, regardless of the width of
# the terminal actually being used. This should generally be within the
# range set by MINCATWIDTH and MAXCATWIDTH.
#
#CATWIDTH       0
#
#---------------------------------------------------------
# Flags.
# NOCACHE keeps man from creating cat pages.
#NOCACHE

tail默认是取最后十行,相当于tail -n 10。

类似的,tail也可以排除开始的若干行:

[icexmoon@xyz ~]$ tail -n +120 /etc/man_db.conf
#
# If CATWIDTH is set to a non-zero number, cat pages will always be
# formatted for a terminal of the given width, regardless of the width of
# the terminal actually being used. This should generally be within the
# range set by MINCATWIDTH and MAXCATWIDTH.
#
#CATWIDTH       0
#
#---------------------------------------------------------
# Flags.
# NOCACHE keeps man from creating cat pages.
#NOCACHE

此外,对于某些会一直产生的文件(比如日志),可以使用-f参数进行持续检测,一有新产生的数据就会立即输出,如果想退出,可以使用CTRL+c退出:

[icexmoon@xyz ~]$ sudo tail -f /var/log/messages
[sudo] icexmoon 的密码:
Aug 10 11:40:02 xyz systemd: Created slice User Slice of root.
Aug 10 11:40:02 xyz systemd: Started Session 7 of user root.
Aug 10 11:40:02 xyz systemd: Removed slice User Slice of root.
Aug 10 11:50:01 xyz systemd: Created slice User Slice of root.
Aug 10 11:50:01 xyz systemd: Started Session 8 of user root.
Aug 10 11:50:01 xyz systemd: Removed slice User Slice of root.
Aug 10 11:50:23 xyz dbus[727]: [system] Activating via systemd: service name='net.reactivated.Fprint' unit='fprintd.service'
Aug 10 11:50:23 xyz systemd: Starting Fingerprint Authentication Daemon...
Aug 10 11:50:23 xyz dbus[727]: [system] Successfully activated service 'net.reactivated.Fprint'
Aug 10 11:50:23 xyz systemd: Started Fingerprint Authentication Daemon.


^C
[icexmoon@xyz ~]$

最后,我们可以将上述的命令结合起来使用,以达成某些目的,比如如果需要第20~30行的数据,可以:

[icexmoon@xyz ~]$ nl /etc/man_db.conf | head -n 30 | tail -n +20
    20  MANDATORY_MANPATH                       /usr/man
    21  MANDATORY_MANPATH                       /usr/share/man
    22  MANDATORY_MANPATH                       /usr/local/share/man
    23  #---------------------------------------------------------
    24  # set up PATH to MANPATH mapping
    25  # ie. what man tree holds man pages for what binary directory.
    26  #
    27  #               *PATH*        ->        *MANPATH*
    28  #
    29  MANPATH_MAP     /bin                    /usr/share/man
    30  MANPATH_MAP     /usr/bin                /usr/share/man

这里使用了管道符号|,会在后边进行介绍。

非纯文本文件

上边介绍的工具都是查看一般性的文本文件的,对于非文本文件,比如二进制文件,就需要使用od命令进行查看:

[icexmoon@xyz ~]$ sudo od -t c /usr/bin/passwd | head -n 10
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   H   2  \0  \0  \0  \0  \0  \0
0000040   @  \0  \0  \0  \0  \0  \0  \0 220   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
0000120   @  \0  \0  \0  \0  \0  \0  \0   @  \0  \0  \0  \0  \0  \0  \0
0000140 370 001  \0  \0  \0  \0  \0  \0 370 001  \0  \0  \0  \0  \0  \0
0000160  \b  \0  \0  \0  \0  \0  \0  \0 003  \0  \0  \0 004  \0  \0  \0
0000200   8 002  \0  \0  \0  \0  \0  \0   8 002  \0  \0  \0  \0  \0  \0
0000220   8 002  \0  \0  \0  \0  \0  \0 034  \0  \0  \0  \0  \0  \0  \0

这里是使用ASCII字符的方式进行展示,此外还可以使用其他诸如8进制或16进制的方式进行展示,这里不在说明。

修改文件时间及创建文件

稍微接触过Linux的同学应该知道有个很方便的创建空白文件的命令touch,事实上这个命令的本职工作是修改文件时间属性,而创建空文件知识其附带的功能。

我们之前提过,文件有三个时间相关的属性:

  • ctime:即status time,就是文件状态改变的时间,比如文件的权限或所属用户发生了改变,这个时间就会随之改变。

  • mtime:即modify time,就是文件的内容修改时间,如果文件内容发生变化,这个时间也会改变。

  • atime:即access time,就是最后一次访问文件的时间,只要读取文件,这个时间就会改变。

默认情况下ls打印的信息中的事件指的是mtime,我们可以使用--time指定其它时间:

[icexmoon@xyz ~]$ ls -al /etc/man_db.conf; ls -al --time=atime /etc/man_db.conf; ls -al --time=ctime /etc/man_db.conf
-rw-r--r--. 1 root root 5171 10月 31 2018 /etc/man_db.conf
-rw-r--r--. 1 root root 5171 8月   9 20:31 /etc/man_db.conf
-rw-r--r--. 1 root root 5171 7月  24 14:35 /etc/man_db.conf

可以看到man_db.conf的三个时间并不相同。

可以通过给touch命令指定一个不存在的文件方式创建一个空文件:

[icexmoon@xyz ~]$ su -
密码:
上一次登录:一 8月  9 20:17:49 CST 2021pts/0 上
[root@xyz ~]# cd /tmp
[root@xyz tmp]# touch touch_test
[root@xyz tmp]# ls -al touch_test; ls -al --time=ctime touch_test; ls -al --time=atime touch_test
-rw-r--r--. 1 root root 0 8月  10 12:12 touch_test
-rw-r--r--. 1 root root 0 8月  10 12:12 touch_test
-rw-r--r--. 1 root root 0 8月  10 12:12 touch_test

可以看到,创建的这个空文件的三个时间属性都相同,都被初始化为当前时间。

除了创建空文件,touch命令还可以修改时间属性:

[root@xyz tmp]# touch -d "2 days ago" touch_test
[root@xyz tmp]# ls -al touch_test; ls -al --time=ctime touch_test; ls -al --time=atime touch_test
-rw-r--r--. 1 root root 0 8月   8 12:18 touch_test
-rw-r--r--. 1 root root 0 8月  10 12:18 touch_test
-rw-r--r--. 1 root root 0 8月   8 12:18 touch_test
[root@xyz tmp]# touch -t "202101011201" touch_test
[root@xyz tmp]# ls -al touch_test; ls -al --time=ctime touch_test; ls -al --time=atime touch_test
-rw-r--r--. 1 root root 0 1月   1 2021 touch_test
-rw-r--r--. 1 root root 0 8月  10 12:19 touch_test
-rw-r--r--. 1 root root 0 1月   1 2021 touch_test

可以看到无论是使用时间字符串-d,还是使用格式化时间-t,都只能修改atime和mtime,而ctime是不能修改的,并且会自动设置为你执行touch命令的时间。这也很好理解,毕竟如果ctime也被随意修改,就相当于黑客行为了,完全就看不出来文件的属性有没有被人篡改过。

文件与目录的默认权限与隐藏权限

umask

Linux系统中文件或目录创建时候会有一个默认权限,这个权限与umask有关:

[icexmoon@xyz ~]$ umask
0002
[icexmoon@xyz ~]$ umask -S
u=rwx,g=rwx,o=rx

umask命令默认显式的是数字形式,比如上边的0002,这种表现形式的意思是默认权限将排除other的写权限,因为该权限在数字形式的权限中正好是第四位的2。

也可以使用-S参数显式为符号形式,如上边的u=rwx,g=rwx,o=rx,这里很清楚的看到缺失了other的写权限。

但需要注意的是umask只是参与决定最终的默认权限,但并不等于默认权限,默认权限具体是什么还要结合“可以设定的最大权限”来看,而后者分为文件和目录两种:

  • 对于文件,可以分配的最大权限是-rw-rw-rw,也就是说是不给执行权限的,对应的数字形式是666。

  • 对于目录,可以分配的最大权限是-rwxrwxrwx,对应的数字形式是777。

这里可能是出于安全方面的考虑,毕竟可执行文件可能会执行一些木马之类的损害系统安全的程序,所以对文件赋予执行权限应当慎重,而目录自然不牵扯到这些问题。

而最终的默认权限则是可赋予的最大权限的基础上再去除umask中排除的权限。

我们来看实例:

[icexmoon@xyz ~]$ cd /tmp
[icexmoon@xyz tmp]$ mkdir test2
[icexmoon@xyz tmp]$ touch test3
[icexmoon@xyz tmp]$ ls -ald test2 test3
drwxrwxr-x. 2 icexmoon icexmoon 6 8月  10 13:51 test2
-rw-rw-r--. 1 icexmoon icexmoon 0 8月  10 13:51 test3

之前已经说过了,当前用户的umask是0002,而对于新建的目录test2,其权限就是在目录的最大权限rwxrwxrwx的基础上去除other的写权限,其结果就是rwxrwxr-x,而对于新建的文件test3,其权限是在文件的最大权限rw-rw-rw-的基础上去除other的写权限,其结果就是rw-rw-r--。

需要注意的是,这种运算并不能简单的以数字形式进行加减运算,比如0777-0002=0775这样,或许大多数情况下结果一致,但有时候会出现错误的结果,究其根本是因为其本质的运算是位运算,并非数学运算,这是两种完全不同的运算方式。

举例来说,上边的运算过程实际是这样的:对于目录test2,运算过程是0111111111&(!0000000010)=0111111101,其结果也就是-rwxrwxr-x。对于文件test3,其运算过程是0110110110&(!0000000010)=0110110100,其结果是-rw-rw-r--,在实际运算中会对umask进行取反后再与运算。

这里简单的说明如何使用位运算计算默认权限,更多位运算的只是可以阅读位运算(&、|、^、~、>>、<<)。

当然实际使用中并不需要真的进行一番位运算,体会后按照实际情况进行逻辑运算就能得出结果。

如果要修改umask的值,也很简单:

[icexmoon@xyz tmp]$ rmdir test2; rm -f test3
[icexmoon@xyz tmp]$ umask 022
[icexmoon@xyz tmp]$ mkdir test2
[icexmoon@xyz tmp]$ touch test3
[icexmoon@xyz tmp]$ ls -ald test2 test3
drwxr-xr-x. 2 icexmoon icexmoon 6 8月  10 14:13 test2
-rw-r--r--. 1 icexmoon icexmoon 0 8月  10 14:13 test3
[icexmoon@xyz tmp]$ umask 002

可以看到,通过使用umask 022,可以让默认权限中的group不再具有写权限(当然最后不要忘记改回来)。

总的来说umask可以看作是user permission mask,起到一个用户权限面具的作用,用面具遮盖剩下的就是我们最终看到的默认权限。

文件隐藏属性

除了之前介绍的文件相关的属性:权限、拥有者、群组、时间等,文件还具有特殊用途的隐藏属性。

chattr

使用chattr(change attribute)命令可以修改文件的隐藏属性:

[icexmoon@xyz tmp]$ touch attr_test
[icexmoon@xyz tmp]$ chattr +i attr_test
chattr: 不允许的操作 while setting flags on attr_test
[icexmoon@xyz tmp]$ sudo chattr +i attr_test
[sudo] icexmoon 的密码:
[icexmoon@xyz tmp]$ sudo rm -f attr_test
rm: 无法删除"attr_test": 不允许的操作
[icexmoon@xyz tmp]$ sudo chattr -i attr_test
[icexmoon@xyz tmp]$ sudo rm -f attr_test
[icexmoon@xyz tmp]$ ls -al attr_test
ls: 无法访问attr_test: 没有那个文件或目录

可以看到,要执行chattr必须要有root权限,即使你就是文件的拥有者也不行。此外通过chattr +i我们可以给文件增加一个隐藏属性i,设置了这个隐藏属性之后,即使是root权限也无法删除该文件,除非再使用chattr -i命令去除该属性。

lsattr

可以使用lsattr查看文件所拥有的隐藏属性:

[icexmoon@xyz tmp]$ touch attr_test
[icexmoon@xyz tmp]$ sudo chattr +aiS attr_test
[icexmoon@xyz tmp]$ sudo lsattr attr_test
--S-ia---------- attr_test
[icexmoon@xyz tmp]$ sudo chattr -aiS attr_test
[icexmoon@xyz tmp]$ rm -f attr_test

如果遇到了用root权限也删除不掉的文件,可以使用lsattr查看隐藏属性试试看。

文件特殊权限

可能有人注意到了,明明之前我们说rwx权限分为三个维度,但是上边介绍umask时候说明权限的时候都是0777,在三个维度前多了一位表示权限的数字0,那个其实就是特殊权限。

SUID

[icexmoon@xyz tmp]$ ls -al /usr/bin/passwd
-rwsr-xr-x. 1 root root 27856 4月   1 2020 /usr/bin/passwd

如果我们查看可执行文件/usr/bin/passwd就能发现,owner的权限并非rwx而是rws,这是怎么回事?

其实那个s就是表示这个文件具有特殊权限SUID。

SUID全称Set UID,其作用是让二进制文件执行的时候具有等同于owner的权限,具体来说,上边的可执行文件passwd用于修改用户密码,而用户密码是保存在/etc/passwd中的:

[icexmoon@xyz tmp]$ ls -al /etc/passwd
-rw-r--r--. 1 root root 2271 7月  24 14:45 /etc/passwd

可以看到这个密码文件保存的很好,仅有root用户具有写权限,那么正常来说除了root用户,其它任何用户执行/usr/bin/passwd程序都是无法正常修改密码的,这显然是不行的。

此时SUID就起了作用,因为/usr/bin/passwd文件具有SUID权限,所以在执行的过程中就会拥有该文件的拥有者root的全部权限,自然也可以修改/etc/passwd文件。

当然你并不需要为不安全担心,因为毕竟是通过可执行文件间接修改配置文件,而非是你可以自行随便修改,所以并不存在安全性上的问题。

此外,使用SUID权限有以下限制和特点:

  • SUID仅针对二进制文件有效(这个很好理解,其目的我们已经说过了)

  • 执行者对该程序需要具有x权限(这个也好理解,连x权限都没有,SUID自然不起作用)

  • 该权限仅在程序执行过程中起作用

  • 执行者将拥有文件的拥有者的权限

最后要强调的是,SUID仅能作用于二进制文件,对于bash的批处理脚本shell是不行的。

SGID

SGID全称Set GID,其作用与SUID类似,只不过是让可执行文件在执行的时候拥有其所属群组的权限:

[icexmoon@xyz tmp]$ ls -al /usr/bin/locate
-rwx--s--x. 1 root slocate 40520 4月  11 2018 /usr/bin/locate

类似于passwd,locate因为具有SGID的权限,所以在执行的时候将拥有群组slocate的全部权限。

SGID大体上的用途和限制与SUID类似,这里不再重复说明,需要注意的是SGID还可以作用于目录。

在讲SGID作用于目录的时候具有以下特点:

  • 如果用户具有该目录的r和x权限,则进入该目录后将拥有该目录的所属群组的权限(仅限于该目录中)

  • 如果用户同时具有w权限,可以创建文件,则在该目录中创建的新文件的群组也会是该目录的所属群组

简单地来说就是如果你需要一个团队成员共享的项目目录,那直接将该目录设置为SGID权限就是最省事的方式了,你不需要一一对成员设置所属群组,只要确保相应的用户有该目录的rx权限即可。

SBIT

全称Sticky Bit,目前仅对目录有效,已经对文件失效。

将SBIT作用于目录时候具有以下效果:

当用户具有该目录的wx权限时,在该目录下创建的文件仅有自己和root可以删除。

这里举例说明:

[icexmoon@xyz tmp]$ ls -ald /tmp
drwxrwxrwt. 24 root root 4096 8月  10 14:51 /tmp

可以看到/tmp目录具有SBIT权限,且权限为rwxrwxrwt,理论上任何人都可以在这个目录进行任何操作,但因为SBIT的存在,只有文件的创建者和root可以删除相应的文件(如果具体的文件权限允许的话)。

我们看具体例子:

[icexmoon@xyz tmp]$ su -
密码:
上一次登录:二 8月 10 12:12:43 CST 2021pts/0 上
[root@xyz ~]# cd /tmp
[root@xyz tmp]# touch test_sbit
[root@xyz tmp]# chmod 0777 test_sbit
[root@xyz tmp]# ls -al test_sbit
-rwxrwxrwx. 1 root root 0 8月  10 15:05 test_sbit
[root@xyz tmp]# exit
登出
[icexmoon@xyz tmp]$ rm test_sbit
rm: 无法删除"test_sbit": 不允许的操作

这里我们使用root用户在/tmp中创建一个文件test_sbit,并将权限设置为777,理论上任何人都可以删除这个文件,但我们改用icexmoon用户尝试删除的时候却提示不允许,这就是因为/tmp有SBIT权限的缘故。

特殊权限设置

与普通权限类似,特殊权限的设置也分为符号与数字两种,对于数字,有以下对应关系:

  • 4:SUID

  • 2:SGID

  • 1:SBIT

举例来说,如果一个文件的权限是-rwsr-xr-x的话,其对应的数字形式应该是4755。

下面看一些具体示例:

[icexmoon@xyz tmp]$ touch test_special
[icexmoon@xyz tmp]$ chmod 6755 test_special
[icexmoon@xyz tmp]$ ls -al test_special
-rwsr-sr-x. 1 icexmoon icexmoon 0 8月  10 15:14 test_special
[icexmoon@xyz tmp]$ chmod 4755 test_special
[icexmoon@xyz tmp]$ ls -al test_special
-rwsr-xr-x. 1 icexmoon icexmoon 0 8月  10 15:14 test_special
[icexmoon@xyz tmp]$ chmod 6766 test_special
[icexmoon@xyz tmp]$ ls -al test_special
-rwsrwSrw-. 1 icexmoon icexmoon 0 8月  10 15:14 test_special
[icexmoon@xyz tmp]$ chmod 6666 test_special
[icexmoon@xyz tmp]$ ls -al test_special
-rwSrwSrw-. 1 icexmoon icexmoon 0 8月  10 15:14 test_special

需要注意的是最后那个chmod 6666 test_special,在这个设置中所有用户都不具有执行权限,自然SUID和GUID都是无效的。

此外,我们同样可以使用符号进行设置:

[icexmoon@xyz tmp]$ chmod u=rwxs,g=rwxs,o=rwxt test_special
[icexmoon@xyz tmp]$ ls -al test_special
-rwsrwsrwt. 1 icexmoon icexmoon 0 8月  10 15:14 test_special

当然,因为是文件,这里设置的SBIT权限并没有什么实际效果。

观察文件类型

在Windows中我们通常通过文件后缀名判断文件的类型,但Linux中文件的执行方式和后缀名并没有一定的关系,很多时候后缀名只是一种人性化标识的手段罢了,如果要准确判断Linux中的文件的类型,就需要使用file命令:

[icexmoon@xyz tmp]$ chmod u=rwxs,g=rwxs,o=rwxt test_special
[icexmoon@xyz tmp]$ ls -al test_special
-rwsrwsrwt. 1 icexmoon icexmoon 0 8月  10 15:14 test_special
[icexmoon@xyz tmp]$ sudo file /var/lib/mlocate/mlocate.db
/var/lib/mlocate/mlocate.db: data

此外,如果你需要解压缩某个tar包,但该包缺少可辨识的压缩相关的后缀名,你可以使用file命令查看具体使用的是何种压缩算法,然后针对性地解压缩。

指令与文件的搜寻

which

我们有时候需要知道某个命令的具体路径,此时就可以使用which命令来查找:

[icexmoon@xyz tmp]$ which ifconfig
/usr/sbin/ifconfig
[icexmoon@xyz tmp]$ which which
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
        /usr/bin/alias
        /usr/bin/which
[icexmoon@xyz tmp]$ which history
/usr/bin/which: no history in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/icexmoon/.local/bin:/home/icexmoon/bin)

在查找which命令本身的时候我们可以发现,which命令本身是一个alias别名。

此外,如果查找history是没有结果的,因为history并非一个单独程序,而是bash内置的命令。

查找文件

在Linux中查找文件,通常可以使用find、whereis和locate命令,虽然find就可以做的很好,但其执行速度很慢,所以更推荐使用后两个先进行查找,找不到再使用find。

whereis

whereis仅会在一些特定目录中进行查找,所以速度比find /会快很多:

[icexmoon@xyz tmp]$ which history
/usr/bin/which: no history in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/icexmoon/.local/bin:/home/icexmoon/bin)
[icexmoon@xyz tmp]$ whereis ifconfig
ifconfig: /usr/sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz
[icexmoon@xyz tmp]$ whereis passwd
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz
[icexmoon@xyz tmp]$ whereis -m passwd
passwd: /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz

可以看到,whereis查找了usr/local/bin和usr/bin等常用目录,此外还可以通过-m等参数指定只检索某些目录。

完整的whereis查找目录列表可以使用下面的方式查看:

[icexmoon@xyz tmp]$ whereis -l
bin: /usr/bin
bin: /usr/sbin
bin: /usr/lib
bin: /usr/lib64

locate

如果要查找的文件并不在whereis检索的常见目录中,可以使用locate命令进行检索:

[icexmoon@xyz tmp]$ locate -l 5 passwd
/etc/passwd
/etc/passwd-
/etc/pam.d/passwd
/etc/security/opasswd
/usr/bin/gpasswd

可以看到使用locate命令检索速度很快,这是因为locate对文件使用数据库建立了索引,就和许多Windows上的辅助工具(Listary等)是一个效果,自然检索速度很快。

我们可以使用locate -S查看其索引状况:

[icexmoon@xyz tmp]$ locate -S
数据库 /var/lib/mlocate/mlocate.db:
        9,390 文件夹
        130,339 文件
        6,265,584 文件名中的字节数
        2,912,590 字节用于存储数据库

因为locate使用的是索引查找,所以如果查找的文件比较新,还没有被收录进索引,自然是找不到的,这时候就需要我们手动更新索引:

[icexmoon@xyz tmp]$ sudo updatedb

find

find命令相对来说查找速度慢,但优点是功能强大,可以定制很多查询条件:

[icexmoon@xyz tmp]$ find / -mtime 0

这样可以查找Linux系统内过去1天内修改过的所有文件,-mtime参数后跟的值单位是天,所以0表示1天内,3表示第4天内,如果是+n则表示n天前(不包含n),如果是-n则表示n天内(不包含n)。

具体可以参考下面的图:

image-20210810162104795

(图片来自鸟叔的Linux私房菜)

除了可以指定具体时间以外,还可以这样:

[icexmoon@xyz tmp]$ sudo find /etc -newer /etc/passwd
[sudo] icexmoon 的密码:
/etc
/etc/fstab
/etc/resolv.conf
/etc/udev
/etc/udev/hwdb.bin
/etc/ssh
/etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_rsa_key.pub
/etc/ssh/ssh_host_ecdsa_key
/etc/ssh/ssh_host_ecdsa_key.pub

这里的意思是查找/etc下面比/etc/passwd“更新”的文件,这种做法对比较不同版本文件的新旧比较有用。

此外,我们还可以查找指定用户的文件:

[icexmoon@xyz tmp]$ sudo find /home -user icexmoon | head -n 10
/home/icexmoon
/home/icexmoon/.mozilla
/home/icexmoon/.mozilla/extensions
/home/icexmoon/.mozilla/plugins
/home/icexmoon/.mozilla/firefox
/home/icexmoon/.mozilla/firefox/p1dll8kw.default-default
/home/icexmoon/.mozilla/firefox/p1dll8kw.default-default/.parentlock
/home/icexmoon/.mozilla/firefox/p1dll8kw.default-default/compatibility.ini
/home/icexmoon/.mozilla/firefox/p1dll8kw.default-default/permissions.sqlite
/home/icexmoon/.mozilla/firefox/p1dll8kw.default-default/cookies.sqlite

甚至查找没有任何拥有者的文件:

[icexmoon@xyz tmp]$ sudo find / -nouser | head -n 10
find: ‘/proc/5962/task/5962/fd/5’: 没有那个文件或目录
find: ‘/proc/5962/task/5962/fdinfo/5’: 没有那个文件或目录
find: ‘/proc/5962/fd/6’: 没有那个文件或目录
find: ‘/proc/5962/fdinfo/6’: 没有那个文件或目录

通常可以通过这种方式查找系统中不正常的文件,当然有时候是因为使用源码自行编译软件产生的文件,并真的不正常。

此外还可以通过文件名进行查询,当然这是最常用的方式:

[icexmoon@xyz tmp]$ sudo find / -name passwd
/sys/fs/selinux/class/passwd
/sys/fs/selinux/class/passwd/perms/passwd
/etc/pam.d/passwd
/etc/passwd
/usr/bin/passwd
/usr/share/bash-completion/completions/passwd

甚至可以使用通配符:

[icexmoon@xyz tmp]$ sudo find / -name *passwd* | head -n 15
/sys/fs/selinux/class/passwd
/sys/fs/selinux/class/passwd/perms/passwd
/etc/security/opasswd
/etc/pam.d/passwd
/etc/passwd
/etc/passwd-
/var/lib/yum/yumdb/p/cb573d29021a1afd49e5da955c200648a19c5f52-passwd-0.79-6.el7-x86_64
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/grub2-mkpasswd-pbkdf2
/usr/bin/lppasswd
/usr/bin/vncpasswd
/usr/sbin/saslpasswd2
/usr/sbin/chgpasswd
/usr/sbin/chpasswd

根据文件类型查找:

[icexmoon@xyz tmp]$ sudo find /run -type s | head -n 10
/run/NetworkManager/private-dhcp
/run/mcelog-client
/run/gssproxy.sock
/run/vmware/guestServicePipe
/run/abrt/abrt.socket
/run/dbus/system_bus_socket
/run/avahi-daemon/socket
/run/libvirt/libvirt-admin-sock
/run/libvirt/libvirt-sock-ro
/run/libvirt/libvirt-sock

-s参数的值有:

  • f:一般文件

  • b,c:设备文件

  • d:目录

  • l:链接文件

  • s:socket

  • p:FIFO

还可以根据权限进行查询:

[icexmoon@xyz tmp]$ sudo find / -perm /7000 | head -n 10
find: ‘/proc/6471/task/6471/fd/5’: 没有那个文件或目录
find: ‘/proc/6471/task/6471/fdinfo/5’: 没有那个文件或目录
find: ‘/proc/6471/fd/6’: 没有那个文件或目录
find: ‘/proc/6471/fdinfo/6’: 没有那个文件或目录
/dev/mqueue
/dev/shm
/run/log/journal
/run/log/journal/f5a85e92d51e4d40975fd956fd775f9c
/var/tmp
/var/tmp/systemd-private-d0852420785e44eebf244b09617b0df9-rtkit-daemon.service-134NjQ/tmp
/var/tmp/systemd-private-d0852420785e44eebf244b09617b0df9-cups.service-VISku6/tmp
/var/tmp/systemd-private-d0852420785e44eebf244b09617b0df9-bolt.service-Q64Kpb/tmp
/var/tmp/systemd-private-d0852420785e44eebf244b09617b0df9-colord.service-3H8qc2/tmp
/var/tmp/systemd-private-d0852420785e44eebf244b09617b0df9-fwupd.service-XUSOJd/tmp

这里/7000的意思是有任意的SUID,SGID,SBIT权限都算,如果是7000,则必须要是--s--s--t权限的文件才算。

再看一个例子:

[icexmoon@xyz tmp]$ sudo find /usr/bin /usr/sbin -perm /6000 | head -n 5
/usr/bin/fusermount
/usr/bin/wall
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/passwd
[icexmoon@xyz tmp]$ ls -al /usr/bin/fusermount
-rwsr-xr-x. 1 root root 32096 10月 31 2018 /usr/bin/fusermount

这里查找了/usr/bin和/usr/sbin下有特殊权限的文件,且通过ls可以看到fusermount的确有SUID权限。

我们还可以设置利用find输出的结果执行其它命令:

[icexmoon@xyz tmp]$ sudo find /usr/bin /usr/sbin -perm /6000 -exec ls -l {} \;
-rwsr-xr-x. 1 root root 32096 10月 31 2018 /usr/bin/fusermount
-r-xr-sr-x. 1 root tty 15344 6月  10 2014 /usr/bin/wall
-rws--x--x. 1 root root 23968 10月  1 2020 /usr/bin/chfn
-rws--x--x. 1 root root 23880 10月  1 2020 /usr/bin/chsh
-rwsr-xr-x. 1 root root 27856 4月   1 2020 /usr/bin/passwd
-rwsr-xr-x. 1 root root 32128 10月  1 2020 /usr/bin/su
-rwsr-xr-x. 1 root root 73888 8月   9 2019 /usr/bin/chage
-rwsr-xr-x. 1 root root 78408 8月   9 2019 /usr/bin/gpasswd
-rwsr-xr-x. 1 root root 41936 8月   9 2019 /usr/bin/newgrp
-rwsr-xr-x. 1 root root 44264 10月  1 2020 /usr/bin/mount
-rwsr-xr-x. 1 root root 31984 10月  1 2020 /usr/bin/umount
-rwsr-xr-x. 1 root root 23576 4月   1 2020 /usr/bin/pkexec

需要注意的是这里并非使用管道命令,而是通过-exec参数让find命令调用其它命令对结果进行“二次处理”,这里二次处理所需的命令需要放在-exec参数后,且需要以\;进行结尾,而且用{}表示find查找到的单条文件路径。

从上边我们可以看到,find可以设置许多复杂的查找条件,而这些都是locate所不具备的,所以find还是挺重要的。

关于文件与目录相关的内容就介绍到这里了,谢谢阅读。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: Linux 文件 目录管理
最后更新:2021年8月10日

魔芋红茶

加一点PHP,加一点Go,加一点Python......

点赞
< 上一篇
下一篇 >

文章评论

取消回复

*

code

COPYRIGHT © 2021 icexmoon.cn. ALL RIGHTS RESERVED.
本网站由提供CDN加速/云存储服务

Theme Kratos Made By Seaton Jiang

宁ICP备2021001508号

宁公网安备64040202000141号