(学习总结23)Linux 目录、通配符、重定向、管道、shell、权限与粘滞位

Linux 目录、通配符、重定向、管道、shell、权限与粘滞位

以下命令行环境为 Ubuntu 22.04.5

Linux 目录

Linux 系统中,磁盘上的文件和目录被组成一棵目录树,每个节点都是目录或文件,其中普通文件一定是目录树的叶子节点,而目录可能是叶子(空目录), 也可能是路上节点。

路径存在的意义:树状组织方式,都是为了保证快速定位查找到指定的文件,而定位文件就需要具有唯一性的方案来进行定位文件。其中任何一个节点,都保证只有一个父节点。所以,从根目录开始,定位指定文件,路径具有唯一性

  1. 绝对路径:一般从 "/"(根目录) 开始,不依赖其他目录定位文件的方式

  2. 相对路径:相对于当前用户所处目录,定位文件的路径方式

绝对路径一般不会随着用户的路径变化而丧失唯一性,并且在特定服务的配置文件中也经常被使用。

相对路径因为它的便捷性,一般在命令行中使用较多。

Linux 中当前目录设置为 . ,上一级目录为 .. ,通过命令可以轻松操作相对路径:

bash 复制代码
cd ..		# 返回到上一级目录,若为根目录则不会返回
ls ../mydir	# 列出上一级目录的子目录中的文件
ls -a		# 查看隐藏的文件,包含两者

通配符

在 Linux 的 shell 环境中,通配符是用于匹配文件名或路径名的特殊字符 ,可以快速批量操作文件,常用的通配符有:

  1. * 匹配任意长度的字符。
bash 复制代码
ls *.c      # 列出当前目录所有以 .c 为结尾的文件
rm test_	# 删除当前目录所有以 test_ 开头的文件
  1. ? 匹配单个任意字符。
bash 复制代码
ls test_?.c		# 列出当前目录单个字符的,但是如 test_10.c 不匹配
  1. [] 匹配括号内的任意一个字符。支持范围:a-z(小写字母)、0-9(数字)、A-Za-z(大小写字母)。
bash 复制代码
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 文件
  1. {} 生成多个组合,用于批量操作。
bash 复制代码
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
  1. ^! 反向匹配,排除括号内的字符(部分 shell 中 ^ 等价 !)。
bash 复制代码
ls test[!2].c		# 表示除了 test2.c ,列出当前的 test1.c 到 test9.c 
  1. ** 递归匹配目录。
bash 复制代码
ls **			# 不仅列出当前目录下的文件,还将子目录中所有文件列出

注意事项:

通配符是由 shell 进行扩展的,而不是由具体的命令进行处理。

转义字符:若文件名本身包含 *? 等特殊字符,需用引号或反斜杠转义:

bash 复制代码
ls "test?.c"	# 列出名为 test?.c 文件
ls test\*.c		# 列出名为 test*.c 文件

重定向

重定向用于控制命令的输入来源和输出目标,管理数据流向文件或其他命令,常见用法:

  1. 标准输出重定向 >>>,用于本将写入 标准输出(stdout) 的命令(打印到屏幕)写入其它文件
bash 复制代码
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 文件末尾,不会覆盖之前的内容
  1. 标准错误重定向 2>2>>,用于本将写入 标准错误(stderr) 的命令(也是打印到屏幕)写入其它文件
bash 复制代码
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 会自动创建一个
  1. 混合重定向 &> 或 > [文件名] 2>&1&>>处理写入 stdout 或 stderr 的命令重定向到同一文件
bash 复制代码
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			# 同上,但写入时是追加,不是覆盖
  1. 输入重定向 <将文件内容作为命令的标准输入
bash 复制代码
echo "test write" > test.txt	# 将 test write 写入 test.txt 文件
cat < test.txt					# 从文件 test.txt 中读取并打印 test write
  1. 输入重定向 << 多行输入(Here Document),将多行内容作为输入传递给命令,直到遇见自己规定的终止符
bash 复制代码
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
  1. 输入重定向 <<< 单行输入(Here String),将字符串作为输入
bash 复制代码
cat <<< "test write"				# 在屏幕打印 test write
grep -n "test" <<< "test write"		# 查找 test 关键字并带上行号打印

管道

通过 | 符号将一个命令的标准输出(stdout) 传递给另一个命令的标准输入(stdin),实现数据流的逐级处理。

bash 复制代码
# ls 将当前目录信息传给 grep,而后筛选出带有 .txt 关键字的文件名带上行号并打印在屏幕上
ls -l | grep -n ".txt"	

shell 介绍

Linux 严格意义上是一个操作系统,称之为 " 内核(kernel) " ,但用户一般不能直接使用 kernel,而是通过 kernel 的 " 外壳 " 程序,也就是所谓的 shell,来与 kernel 沟通。

但为什么不能直接使用 kernel 呢? 从技术角度,shell 的最简单定义------命令行解释器(command Interpreter) 主要包含:

  1. 将使用者的命令翻译给 kernel 处理。
  2. 将 kernel 的处理结果翻译给使用者。

对比 windows GUI(Graphical User Interface 图形用户界面),用户操作 windows 时不是直接操作 windows 内核,而是通过图形接口点击来完成操作。shell 对于 Linux 有相同的作用,主要是对用户的命令(指令) 进行解析,解析指令给 Linux内核,反馈结果再通过内核运行出结果,通过 shell 解析给用户。

Linux 权限

Linux 权限的概念

Linux 下有两种用户,超级用户(root) 和 普通用户:

  1. 超级用户:可以在 Linux系统 下做任何事情,不受限制

  2. 普通用户:在 Linux 下做有限的事情

超级用户的命令提示符是 # ,普通用户的命令提示符是 $

用户切换命令 su

语法 :su 选项 用户名
功能 :切换用户
常用选项

    • 或 -l :切换用户时,完全模拟目标用户登录时的环境,将会加载目标用户的环境变量和配置文件
  • -c "命令" : 切换用户后会执行双引号中的命令,再返回到当前用户
  • -s 目标 bash :切换到用户并将 目标 bash 作为 shell
  • -m 或 -p : 保留当前环境变量,不加载目标用户环境变量

其它操作:

  1. 不写用户名时自动切换到 root 账号

例如要从 root 用户切换到普通用户 user,则使用 su user。要从普通用户 user 切换到 root 用户则使用 su root(root可以省略),此时系统会提示输入 root 用户的口令。

Linux权限管理

文件访问者的分类:

  1. 文件和文件目录的所有者:u --- User
  2. 文件和文件目录的所有者所在组的用户:g --- Group
  3. 其他用户:o --- Others

常用文件类型与其标识符:

  1. d:文件夹目录
  2. -:普通文件
  3. l:符号链接(软链接),指向另一个目录或文件(类似Windows的快捷方式)
  4. b:块设备文件(例如硬盘、USB等)
  5. p:管道文件
  6. c:字符设备文件(例如屏幕等串口设备)
  7. s:套接口文件

文件基本权限和权限值的表示方法:

权限值的表示方法:

  1. 字符表示方法

  2. 8 进制数值表示方法

基本权限:

  1. 读( r(字符表示) / 4(8进制表示) ):read 对文件而言,具有读取文件内容的权限;对目录来说,具有浏览该目录信息的权限
  2. 写( w / 2 ):write 对文件而言,具有修改文件内容的权限;对目录来说具有删除和移动目录内文件的权限
  3. 执行( x / 1 ):execute 对文件而言,具有执行文件的权限;对目录来说,具有进入目录的权限
  4. " - " 表示不具有该项权限

以下是一些文件访问权限的相关命令操作。

更改文件或目录访问权限命令 chmod

语法 :chmod 选项 权限模式 文件或目录名
功能 :设置文件或目录的访问权限
常用选项

  • -R -> 递归修改目录及其子目录和文件的权限,只有文件的拥有者和 root 才可以改变文件的权限

权限模式:

  1. 数字模式:用三位8进制数字表示,单个数对应一位角色的操作数值的和

  2. 符号模式:用户角色符号权限操作符号权限字符符号

用户角色符号:

  • u:拥有者
  • g:拥有者同组用
  • o:其他用户
  • a:所有用户(当用户符号不写默认)

权限操作符号:

    • :添加权限
    • :移除权限
  • = :覆盖原有权限

权限字符符号:

  • r :读
  • w :写
  • x :执行

修改文件的所有者和所属组命令 chown

语法 :chown 选项 所有者:所属组 文件或目录名
功能 :修改文件的所有者和所属组
常用选项

  • -R 递归的修改目录及其所有子目录与文件的所有者和所属组

其它操作:

  1. 所有者与所属组至少要写一个

修改文件或目录的所属组命令 chgrp

语法 :chgrp 选项 所属名 文件或目录名
功能 :修改文件或目录的所属组
常用选项:

  • -R 递归修改文件或目录的所属组

创建文件和目录时的默认权限掩码命令 umask

语法 :umask 权限值
功能:设置默认文件权限掩码,决定新创建的文件或目录的默认权限

其它操作:

  1. 不写权限值可以查看当前用户的 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 环境变量为 超级用户的主目录

目录的权限与问题

  1. 可读权限(read):如果目录没有可读权限,则无法用 ls 等命令查看目录中的文件内容

  2. 可写权限(write): 如果目录没有可写权限,则无法在目录中创建文件, 也无法在目录中删除文件

  3. 可执行权限(execute):如果目录没有可执行权限,则无法 cd 到目录中

注意:

  • 目录的可执行权限是表示用户是否在目录下执行命令。
  • 如果目录没有 x(执行) 权限,则无法对目录执行任何命令,甚至无法 cd 进入目录,即使目录仍然有 -r(读) 权限(这个地方很容易犯错,认为有读权限就可以进入目录读取目录下的文件)
  • 而如果目录具有 x 权限,但没有 -r 权限,则用户可以执行命令,可以 cd 进入目录。但由于没有目录的读权限,即使可以执行命令,但仍然没有权限使用 ls 读取当前目录下的文档。

于是出现了问题,如果用户具有当前目录的写权限, 用户就可以删除当前目录中的文件或目录,而不论这个用户是否有这个被删除文件或目录的执行权限。

为了解决这个不科学的问题,Linux 引入了粘滞位的概念。

粘滞位

粘滞位(Sticky Bit) 是一种特殊的权限标记,主要用于目录的权限控制

普通目录的权限问题:在普通目录中,如果用户对目录有写权限,则可以删除目录中的任何文件,即使这些文件不属于该用户

粘滞位解决方法:当前目录设置了粘滞位后,只有 文件的所有者、目录的所有者、超级用户 才能删除或重命名当前目录中的文件。

其应用场景:共享目录(如 /tmp)或 协作环境中,防止用户删除他人的文件,提高安全性和协作效率

使用方法:
语法1 :chmod +t 目录
语法2 :chmod 数字模式 目录
语法3:chmod -t 目录

数字模式:在三位的数字的权限值再添加最高位数字 1

bash 复制代码
chmod +t mydir		# 将 mydir 目录设置粘滞位
chmod 1760 mydir	# 最高位 1 代表数字模式设置粘滞位,其它三位为常规权限设置
chmod -t mydir		# 移除 mydir 的粘滞位

查看粘滞位:

使用 ls -l 命令查看上一级目录权限时,如果粘滞位已设置,其他用户权限位 的最后一位会显示为 tT

bash 复制代码
ls -l		# 查看粘滞位
# drwxrwxr-t 2 user1 user1 4096 Feb 15 15:17 mydir
相关推荐
FoldWinCard1 小时前
D5 Linux 网络及端口命令
linux·运维·服务器
零涂毕业设计2 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
tedcloud1232 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
霸道流氓气质2 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
SakitamaX3 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.3 小时前
Linux系统管理
linux·运维
阿龙的工作记录3 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
代码村新手4 小时前
Linux的基本指令
linux·运维·服务器
hkj88084 小时前
Ubuntu 切换java版本
java·linux·ubuntu
caimouse6 小时前
protoc-gen-c 支持 proto3 `optional` 关键字修改记录
c语言·学习