Linux系统编程学习笔记(二):权限、重定向与管道,开始理解Linux的规则
上一篇主要学习了 Linux 的基础操作。
从:
ls
pwd
cd
到:
touch
mkdir
rm
cp
mv
cat
grep
这些命令让我慢慢熟悉了 Linux 的命令行环境。
但只会这些还远远不够。
当我开始学习 Linux 权限、重定向和管道之后,我才慢慢感觉到:
Linux 真正有意思的地方,不只是“命令多”,而是命令背后有一套完整的系统思想。
这一篇就继续记录我学习过程中的几个重点。
一、Linux 中的用户和权限
Linux 中有两种非常重要的用户:
root
普通用户
root 是超级用户,拥有非常高的系统权限。
普通用户的权限则受到限制。
在命令提示符中也可以看到区别:
root用户:
#
普通用户:
$
例如:
[root@localhost ~]#
[user@localhost ~]$
看到提示符,就可以大概知道自己现在是什么身份。
二、su:切换用户
可以使用:
su 用户名
切换用户。
例如:
su root
切换到 root。
如果需要退出当前用户环境,可以:
exit
用户之间的切换和权限是 Linux 安全体系非常基础的一部分。
三、Linux 权限到底是什么?
执行:
ls -l
经常会看到类似:
-rwxr-xr--
这一串内容其实非常重要。
它描述的是文件的权限。
Linux 的基本权限有三种:
r = read
w = write
x = execute
分别表示:
r:读
w:写
x:执行
同时,权限又会分别针对三类用户:
u:User,文件所有者
g:Group,文件所属组
o:Others,其他用户
所以一个权限字符串可以理解成:
rwx | r-x | r--
↓ ↓ ↓
u g o
四、权限的数字表示
除了字符形式之外,Linux 中还经常使用数字来表示权限。
例如:
r = 4
w = 2
x = 1
所以:
rwx = 7
rw- = 6
r-x = 5
r-- = 4
因此:
rwxr-xr--
也可以表示成:
754
这就是为什么我们经常看到:
chmod 755 xxx
这样的命令。
五、chmod:修改权限
最常见的权限修改命令就是:
chmod
例如:
chmod 755 test
就是设置对应的权限。
也可以使用符号方式:
chmod +x test
给文件增加执行权限。
或者:
chmod -x test
去掉执行权限。
学习到这里以后,我才发现:
Linux 中的“能不能操作一个文件”,很多时候并不是程序本身决定的,而是操作系统先进行权限检查。
六、目录权限和普通文件权限不完全一样
这是我觉得 Linux 权限里面特别容易混淆的一点。
对于普通文件:
r:读取内容
w:修改内容
x:执行文件
但是对于目录,含义不太一样。
目录的 r
表示可以查看目录中的内容。
目录的 w
表示可以在目录中创建、删除等操作。
目录的 x
表示可以进入目录,以及对目录中的对象进行访问。
尤其是 x 权限非常重要。
比如:
一个目录有 r,但是没有 x
并不代表你就可以随便进入这个目录。
所以:
文件的权限和目录的权限,不能完全用同一种方式理解。
这个地方需要在实际操作中慢慢体会。
七、为什么我可以删除别人的文件?
学习目录权限时,有一个特别容易产生疑惑的问题:
假设:
张三创建了一个文件
为什么另一个用户有可能把它删除?
原因就在于:
删除文件主要受到目录权限的影响。
如果用户对目录具有写权限,那么它可能有权限删除目录中的文件,即使自己对这个文件本身没有写权限。
这看起来有点奇怪,但 Linux 的权限设计就是这样工作的。
为了进一步解决这种场景,Linux 中还有一个特殊权限:
粘滞位(sticky bit)
八、粘滞位
可以使用:
chmod +t /home/
给目录设置粘滞位。
设置后,目录中的文件不能被普通用户随意删除。
通常只有:
超级管理员
目录所有者
文件所有者
可以删除对应文件。
这也是 Linux 权限设计很有意思的地方。
权限不仅仅是:
能不能读
能不能写
能不能执行
还有各种特殊权限来处理真实系统中的复杂情况。
九、umask:为什么创建出来的文件权限不一样?
创建文件时,还有一个非常重要的概念:
umask
例如:
umask
可以查看当前掩码。
Linux 创建普通文件时,会以一定的默认权限为基础,然后受到 umask 的影响。
基本关系可以理解为:
实际权限 = 默认权限 & ~umask
所以:
“我创建文件时为什么权限不是我想象中的那个值?”
很多时候就和 umask 有关。
十、重定向:让程序的输出去另一个地方
Linux 中还有一个特别重要的概念:
重定向。
比如:
echo hello > test.txt
正常情况下:
echo hello
结果会显示到终端。
但是:
echo hello > test.txt
结果就被写到了文件中。
也就是说:
程序输出
↓
文件
这就是输出重定向。
追加重定向
如果使用:
echo hello >> test.txt
它和 > 的区别是:
> :覆盖
>> :追加
所以写日志时,>> 就非常常见。
十一、管道:让一个命令接着处理另一个命令
Linux 中另一个非常经典的设计就是:
|
也就是管道。
例如:
head -200 test.txt | tail -20
这条命令可以把前一个命令产生的结果交给后一个命令继续处理。
可以理解成:
命令A
↓
管道
↓
命令B
这就是 Linux 命令行非常强大的地方。
我们不需要写一个非常复杂的程序,也可以通过组合多个小工具完成一件事情。
十二、grep + 管道
比如:
cat test.txt | grep hello
这里:
cat
负责输出文件内容。
然后:
grep
负责从中筛选出包含 hello 的内容。
这样两个命令组合起来,就完成了一次文本搜索。
实际上,Linux 中很多命令的设计思路就是:
一个程序做好一件事情,然后通过管道和其他程序组合起来。
这种思想我觉得非常值得学习。
十三、head、tail 和管道组合
例如:
head -200 test.txt | tail -20
可以实现查看指定范围的内容。
前面先取出前 200 行:
head -200
然后再从这些内容里取最后 20 行:
tail -20
最终得到的就是:
第181行 ~ 第200行
这种组合方式看起来非常简单,但是实际开发中非常实用。
十四、tar:Linux 中非常重要的打包工具
除了文件操作,Linux 中还经常需要进行文件打包和解包。
常见工具之一就是:
tar
例如:
tar -cvf test.tar test/
可以将目录进行打包。
解包:
tar -xvf test.tar
常见参数:
-c 创建
-x 解包
-t 查看
-z gzip
-v 显示详细过程
-f 指定文件名
如果是:
.tar.gz
经常会看到:
tar -zxvf xxx.tar.gz
十五、tar 和管道组合起来会更有意思
例如:
tar -cvf - /etc | tar -xvf -
这里没有真正把中间结果保存成一个文件。
而是:
tar打包
↓
标准输出
↓
管道
↓
tar解包
这让我第一次明显感受到:
Linux 命令真正强大的地方,不是某一条命令本身,而是很多命令可以组合起来。
十六、查看系统信息
Linux 中还可以使用:
uname -a
查看系统和内核相关信息。
例如:
uname -r
可以查看内核版本。
还可以:
lsb_release -a
查看系统版本信息。
这些命令在排查环境问题的时候很有用。
十七、日志是 Linux 学习中绕不开的东西
前面提到:
tail -f log.txt
这个命令对服务器开发非常实用。
程序运行以后,很多信息都会写到日志里。
这时候我们经常会:
tail -f xxx.log
一边运行程序,一边观察日志变化。
再配合:
grep
就可以快速找到自己关心的内容。
例如:
tail -f app.log | grep error
这样就只看和 error 有关的日志。
我觉得这就是 Linux 思维特别典型的一个体现:
查看
+
筛选
+
组合
十八、学习 Linux 以后,我开始改变自己的思维方式
以前写 C++ 的时候,我经常会想:
“这个功能怎么实现?”
现在学习 Linux 后,我开始多想一步:
“这个功能最终是怎么和操作系统交互的?”
例如一个文件操作:
程序
↓
函数
↓
系统调用
↓
内核
↓
文件系统
↓
磁盘
虽然现在还没有真正深入到每一层,但至少已经开始建立这种意识。
这可能就是从普通编程走向系统编程的一个变化。
十九、目前对 Linux 学习路线的理解
经过这一阶段学习,我大概把 Linux 系统编程理解成了这样一条路线:
Linux基础
↓
Shell
↓
文件与目录
↓
权限
↓
重定向与管道
↓
系统调用
↓
文件描述符
↓
进程
↓
进程间通信
↓
网络编程
现在学到的:
ls
cd
chmod
grep
tar
|
>
以后都会在更底层的内容中再次出现。
二十、这两天学习下来最大的感受
这段时间学习 Linux,我最大的感受就是:
Linux 不是一堆需要死记硬背的命令,而是一套非常完整的系统思维。
从文件和目录:
路径
到用户和权限:
谁可以做什么
再到重定向和管道:
程序之间怎么传递数据
这些东西实际上都是联系在一起的。
以前我看到:
ls -l
只觉得它是“查看文件”。
现在再看到:
-rwxr-xr--
我会开始思考:
谁拥有这个文件?
谁能读?
谁能写?
谁能执行?
看到:
A | B
也不只是觉得“多了一根竖线”,而是会想到:
A的输出
↓
管道
↓
B的输入
我觉得这就是学习 Linux 之后最大的变化:
开始从“会使用命令”,慢慢走向“理解系统”。
结语
作为一名大二学生,现在的我还只是刚刚开始接触 Linux 系统编程。
目前掌握的东西还非常基础,但我觉得基础反而是最重要的。
因为后面真正开始学习:
文件描述符
系统调用
进程
fork
exec
进程间通信
信号
网络编程
的时候,前面这些知识都会成为基础。
所以目前我的目标也不是一次把 Linux 学完,而是:
先把基础打牢,再一点一点往操作系统内部走。
Linux 学习之路,继续。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)