Linux 目录、通配符、重定向、管道、shell、权限与粘滞位
- Linux 目录
- 通配符
- 重定向
- 管道
- shell 介绍
- Linux 权限
- Linux 权限的概念
- 用户切换命令 su
- Linux权限管理
- 文件访问者的分类:
- 常用文件类型与其标识符:
- 文件基本权限和权限值的表示方法:
- 更改文件或目录访问权限命令 chmod
- 修改文件的所有者和所属组命令 chown
- 修改文件或目录的所属组命令 chgrp
- 创建文件和目录时的默认权限掩码命令 umask
- 判断文件类型命令 file
- 提高执行权限命令 sudo
- 目录的权限与问题
- 粘滞位
以下命令行环境为 Ubuntu 22.04.5 。
Linux 目录
Linux 系统中,磁盘上的文件和目录被组成一棵目录树,每个节点都是目录或文件,其中普通文件一定是目录树的叶子节点,而目录可能是叶子(空目录), 也可能是路上节点。
路径存在的意义:树状组织方式,都是为了保证快速定位查找到指定的文件,而定位文件就需要具有唯一性的方案来进行定位文件。其中任何一个节点,都保证只有一个父节点。所以,从根目录开始,定位指定文件,路径具有唯一性。
-
绝对路径:一般从 “
/
”(根目录) 开始,不依赖其他目录定位文件的方式 -
相对路径:相对于当前用户所处目录,定位文件的路径方式
绝对路径一般不会随着用户的路径变化而丧失唯一性,并且在特定服务的配置文件中也经常被使用。
相对路径因为它的便捷性,一般在命令行中使用较多。
Linux 中当前目录设置为 .
,上一级目录为 ..
,通过命令可以轻松操作相对路径:
cd .. # 返回到上一级目录,若为根目录则不会返回
ls ../mydir # 列出上一级目录的子目录中的文件
ls -a # 查看隐藏的文件,包含两者
通配符
在 Linux 的 shell 环境中,通配符是用于匹配文件名或路径名的特殊字符,可以快速批量操作文件,常用的通配符有:
*
匹配任意长度的字符。
ls *.c # 列出当前目录所有以 .c 为结尾的文件
rm test_ # 删除当前目录所有以 test_ 开头的文件
?
匹配单个任意字符。
ls test_?.c # 列出当前目录单个字符的,但是如 test_10.c 不匹配
[]
匹配括号内的任意一个字符。支持范围:[a-z](小写字母)、[0-9](数字)、[A-Za-z](大小写字母)。
ls test[123].c # 列出当前目录 test1.c、test2.c、test3.c 文件
ls test[0-7].c # 列出当前目录从 test0.c 到 test7.c 文件
ls test[a-d].c # 列出当前目录从 testa.c 到 testd.c 文件
ls test[A-Cb-c].c # 当前目录大写从 testA.c 到 testC.c 文件,小写从 testb.c 到 testc.c 文件
{}
生成多个组合,用于批量操作。
touch test{1,2,3,4}.c # 创建 test1.c、test2.c、test3.c、test4.c 多个文件
touch test{1..100}.c # 中间用 .. 分开表示创建从 test1.c 直到 test100.c 一共100个文件
touch test{a..z}.c # 表示创建从 testa.c 直到 testz.c
^
或!
反向匹配,排除括号内的字符(部分 shell 中^
等价!
)。
ls test[!2].c # 表示除了 test2.c ,列出当前的 test1.c 到 test9.c
**
递归匹配目录。
ls ** # 不仅列出当前目录下的文件,还将子目录中所有文件列出
注意事项:
通配符是由 shell 进行扩展的,而不是由具体的命令进行处理。
转义字符:若文件名本身包含 *
、?
等特殊字符,需用引号或反斜杠转义:
ls "test?.c" # 列出名为 test?.c 文件
ls test\*.c # 列出名为 test*.c 文件
重定向
重定向用于控制命令的输入来源和输出目标,管理数据流向文件或其他命令,常见用法:
- 标准输出重定向
>
和>>
,用于本将写入 标准输出(stdout) 的命令(打印到屏幕)写入其它文件。
ls > test1.txt # 将 ls 输出覆盖写入 test1.txt 文件,当前目录没有 test1.txt 会自动创建一个
echo "write" > test1.txt # 再次用 > 写入 test1.txt 会先清空之前的内容ls >> test2.txt # 将 ls 输出追加到 test2.txt 中,当前目录没有 test2.txt 会自动创建一个
echo "write" >> test2.txt # 再次用 >> 写入会追加到 test2.txt 文件末尾,不会覆盖之前的内容
- 标准错误重定向
2>
和2>>
,用于本将写入 标准错误(stderr) 的命令(也是打印到屏幕)写入其它文件。
ls no_find_file 2> error1.log # ls 没有找到 no_find_file 文件时,会将错误信息覆盖的写入 error1.log ,当前目录没有 error1.log 会自动创建一个
ls no_find_file 2>> error2.log # 同上,但写入时是追加,而不是覆盖# 注意,标准输出与标准错误都是打印到屏幕,但是两者是不同的
# > 本该写入 标准输出 的命令,不会写入 标准错误,反之同理
echo "write" 2> error1.log # 不会写入 error1.log 文件,而是打印到屏幕,但其它操作都会执行,如:覆盖操作依然执行
ls no_find_file > error3.log # 不会写入 error3.log 文件,而是打印到屏幕,但其他操作都会执行,如:当前目录没有 error3.log 会自动创建一个
- 混合重定向
&> 或 > [文件名] 2>&1
与&>>
,处理写入 stdout 或 stderr 的命令重定向到同一文件。
ls no_find_file &> error1.log # 不管 no_find_file 文件是否存在,都会覆盖的写入 error1.log,当前目录没有 error1.log 会自动创建一个
ls no_find_file > error1.log 2>&1 # &> 的等价写法
echo "write" &>> error1.log # 同上,但写入时是追加,不是覆盖
- 输入重定向
<
,将文件内容作为命令的标准输入。
echo "test write" > test.txt # 将 test write 写入 test.txt 文件
cat < test.txt # 从文件 test.txt 中读取并打印 test write
- 输入重定向
<<
多行输入(Here Document),将多行内容作为输入传递给命令,直到遇见自己规定的终止符。
cat << quit # 规定 quit 为终止符
> test1 write # 第一行打印 test1 write
> test2 write # 第二行打印 test2 write
> test3 write # 第三行打印 test3 write
> quit # 终止,随后开始打印grep -n "hh" << q # 规定 q 为终止符,grep 会检查哪行出现 hh 关键字并带上行号打印出来
> haha
> hehe
> lele
> hh
> 666
> 555
> q
- 输入重定向
<<<
单行输入(Here String),将字符串作为输入。
cat <<< "test write" # 在屏幕打印 test write
grep -n "test" <<< "test write" # 查找 test 关键字并带上行号打印
管道
通过 |
符号将一个命令的标准输出(stdout) 传递给另一个命令的标准输入(stdin),实现数据流的逐级处理。
# ls 将当前目录信息传给 grep,而后筛选出带有 .txt 关键字的文件名带上行号并打印在屏幕上
ls -l | grep -n ".txt"
shell 介绍
Linux 严格意义上是一个操作系统,称之为 " 内核(kernel) " ,但用户一般不能直接使用 kernel,而是通过 kernel 的 " 外壳 " 程序,也就是所谓的 shell,来与 kernel 沟通。
但为什么不能直接使用 kernel 呢? 从技术角度,shell 的最简单定义——命令行解释器(command Interpreter) 主要包含:
- 将使用者的命令翻译给 kernel 处理。
- 将 kernel 的处理结果翻译给使用者。
对比 windows GUI(Graphical User Interface 图形用户界面),用户操作 windows 时不是直接操作 windows 内核,而是通过图形接口点击来完成操作。shell 对于 Linux 有相同的作用,主要是对用户的命令(指令) 进行解析,解析指令给 Linux内核,反馈结果再通过内核运行出结果,通过 shell 解析给用户。
Linux 权限
Linux 权限的概念
Linux 下有两种用户,超级用户(root) 和 普通用户:
-
超级用户:可以在 Linux系统 下做任何事情,不受限制
-
普通用户:在 Linux 下做有限的事情
超级用户的命令提示符是 #
,普通用户的命令提示符是 $
。
用户切换命令 su
语法:su [选项] [用户名]
功能:切换用户
常用选项:
- - 或 -l :切换用户时,完全模拟目标用户登录时的环境,将会加载目标用户的环境变量和配置文件
- -c [“命令”] : 切换用户后会执行双引号中的命令,再返回到当前用户
- -s [目标 bash] :切换到用户并将 目标 bash 作为 shell
- -m 或 -p : 保留当前环境变量,不加载目标用户环境变量
其它操作:
- 不写用户名时自动切换到 root 账号
例如要从 root 用户切换到普通用户 user,则使用 su user。要从普通用户 user 切换到 root 用户则使用 su root(root可以省略),此时系统会提示输入 root 用户的口令。
Linux权限管理
文件访问者的分类:
- 文件和文件目录的所有者:u — User
- 文件和文件目录的所有者所在组的用户:g — Group
- 其他用户:o — Others
常用文件类型与其标识符:
- d:文件夹目录
- -:普通文件
- l:符号链接(软链接),指向另一个目录或文件(类似Windows的快捷方式)
- b:块设备文件(例如硬盘、USB等)
- p:管道文件
- c:字符设备文件(例如屏幕等串口设备)
- s:套接口文件
文件基本权限和权限值的表示方法:
权限值的表示方法:
-
字符表示方法
-
8 进制数值表示方法
基本权限:
- 读( r(字符表示) / 4(8进制表示) ):read 对文件而言,具有读取文件内容的权限;对目录来说,具有浏览该目录信息的权限
- 写( w / 2 ):write 对文件而言,具有修改文件内容的权限;对目录来说具有删除和移动目录内文件的权限
- 执行( x / 1 ):execute 对文件而言,具有执行文件的权限;对目录来说,具有进入目录的权限
- " - " 表示不具有该项权限
以下是一些文件访问权限的相关命令操作。
更改文件或目录访问权限命令 chmod
语法:chmod [选项] [权限模式] [文件或目录名]
功能:设置文件或目录的访问权限
常用选项:
- -R -> 递归修改目录及其子目录和文件的权限,只有文件的拥有者和 root 才可以改变文件的权限
权限模式:
-
数字模式:[用三位8进制数字表示,单个数对应一位角色的操作数值的和]
-
符号模式:[用户角色符号][权限操作符号][权限字符符号]
用户角色符号:
- u:拥有者
- g:拥有者同组用
- o:其他用户
- a:所有用户(当用户符号不写默认)
权限操作符号:
- + :添加权限
- - :移除权限
- = :覆盖原有权限
权限字符符号:
- r :读
- w :写
- x :执行
修改文件的所有者和所属组命令 chown
语法:chown [选项] [所有者]:[所属组] [文件或目录名]
功能:修改文件的所有者和所属组
常用选项:
- -R 递归的修改目录及其所有子目录与文件的所有者和所属组
其它操作:
- 所有者与所属组至少要写一个
修改文件或目录的所属组命令 chgrp
语法:chgrp [选项] [所属名] [文件或目录名]
功能:修改文件或目录的所属组
常用选项:
- -R 递归修改文件或目录的所属组
创建文件和目录时的默认权限掩码命令 umask
语法:umask [权限值]
功能:设置默认文件权限掩码,决定新创建的文件或目录的默认权限
其它操作:
- 不写权限值可以查看当前用户的 umask 值
注意权限计算公式:
文件和目录最终权限 = 默认权限值 - umask
将现有默认的存取权限值减去权限掩码后,即可产生建立文件时预设权限。超级用户默认掩码值为 0022,普通用户默认为 0002。
判断文件类型命令 file
语法: file [选项] [文件或目录]
功能:不依赖文件扩展名,而是分析文件内容与结构判断文件类型。
常用选项:
-
-b 只输出文件类型描述信息,不显示文件名
-
-c 详细显示指令执行过程,便于排错或分析程序执行的情形
-
-z 尝试去解读压缩文件的内容
-
-L 当文件是符号链接时,显示符号链接指向的文件类型
提高执行权限命令 sudo
语法:sudo [选项] [命令]
功能:以超级用户或其他用户身份执行命令。
常用选项:
-
-l 列出当前用户可以使用 sudo 执行的命令
-
-u 以指定用户身份执行命令
-
-i 切换到超级用户身份的 shell,且加载其环境变量
-
-s 切换到超级用户身份的 shell,但不加载环境变量
-
-k 清除 sudo 认证时间戳,强制下次使用重新输入密码
-
-v 刷新 sudo 认证时间戳,延长不输入密码时间
-
-b 在后台执行命令
-
-H 设置 HOME 环境变量为 超级用户的主目录
目录的权限与问题
-
可读权限(read):如果目录没有可读权限,则无法用 ls 等命令查看目录中的文件内容
-
可写权限(write): 如果目录没有可写权限,则无法在目录中创建文件, 也无法在目录中删除文件
-
可执行权限(execute):如果目录没有可执行权限,则无法 cd 到目录中
注意:
- 目录的可执行权限是表示用户是否在目录下执行命令。
- 如果目录没有 x(执行) 权限,则无法对目录执行任何命令,甚至无法 cd 进入目录,即使目录仍然有 -r(读) 权限(这个地方很容易犯错,认为有读权限就可以进入目录读取目录下的文件)
- 而如果目录具有 x 权限,但没有 -r 权限,则用户可以执行命令,可以 cd 进入目录。但由于没有目录的读权限,即使可以执行命令,但仍然没有权限使用 ls 读取当前目录下的文档。
于是出现了问题,如果用户具有当前目录的写权限, 用户就可以删除当前目录中的文件或目录,而不论这个用户是否有这个被删除文件或目录的执行权限。
为了解决这个不科学的问题,Linux 引入了粘滞位的概念。
粘滞位
粘滞位(Sticky Bit) 是一种特殊的权限标记,主要用于目录的权限控制。
普通目录的权限问题:在普通目录中,如果用户对目录有写权限,则可以删除目录中的任何文件,即使这些文件不属于该用户。
粘滞位解决方法:当前目录设置了粘滞位后,只有 文件的所有者、目录的所有者、超级用户 才能删除或重命名当前目录中的文件。
其应用场景:共享目录(如 /tmp)或 协作环境中,防止用户删除他人的文件,提高安全性和协作效率。
使用方法:
语法1:chmod +t [目录]
语法2:chmod [数字模式] [目录]
语法3:chmod -t [目录]
数字模式:在三位的数字的权限值再添加最高位数字 1
chmod +t mydir # 将 mydir 目录设置粘滞位
chmod 1760 mydir # 最高位 1 代表数字模式设置粘滞位,其它三位为常规权限设置
chmod -t mydir # 移除 mydir 的粘滞位
查看粘滞位:
使用 ls -l 命令查看上一级目录权限时,如果粘滞位已设置,其他用户权限位的最后一位会显示为 t
或 T
。
ls -l # 查看粘滞位
# drwxrwxr-t 2 user1 user1 4096 Feb 15 15:17 mydir