(学习总结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
相关推荐
你好呀我是裤裤1 小时前
Linux基础开发工具的使用(apt、vim、gcc、g++、gdb、make、makefile)
linux·运维·vim
望获linux1 小时前
如何在望获实时 Linux & 京博航友善 NanoPC-T6 上部署 Docker
linux·运维·服务器·docker·eureka·开源软件
wangchen_01 小时前
linux编译器和自动化构建工具(gcc与Makeile)
linux·运维·服务器
DC_BLOG1 小时前
Linux-Ansible命令
linux·运维·服务器·ansible
suenpeng1 小时前
安全运维,等保测试常见解决问题。
linux·运维·安全
贩卖纯净水.1 小时前
REACT学习DAY02(恨连接不上服务器)
服务器·学习·react.js
码农君莫笑1 小时前
Linux系统上同时打印到物理打印机并生成PDF副本方法研究
linux·前端·chrome·打印·信管通
南风过闲庭2 小时前
操作系统研究
大数据·人工智能·科技·学习·ai·系统架构
马剑威(威哥爱编程)2 小时前
Linux驱动开发13个实用案例
linux·运维·驱动开发
程序员JerrySUN2 小时前
每天设计者模式-1:基础面试题
java·linux·运维·服务器·开发语言·python·docker