Shell
输入输出流重定向
< file输入流重定向> file输出流重定向>> file追加内容
missing:~$ echo hello > hello.txt
missing:~$ cat hello.txt
hello
missing:~$ cat < hello.txt
hello
missing:~$ cat < hello.txt > hello2.txt
missing:~$ cat hello2.txt
hello
- 管道(pipe)
|将一个程序的输出和另外一个程序的输入连接起来
missing:~$ ls -l / | tail -n1
drwxr-xr-x 1 root root 4096 Jun 20 2019 var
missing:~$ curl --head --silent google.com | grep --ignore-case content-length | cut --delimiter=' ' -f2
219
su 和 sudo
在某些场合内必须以 su 身份运行,如
- 向 sysfs 文件写入内容
例如,您笔记本电脑的屏幕亮度写在 brightness 文件中,它位于
通过将数值写入该文件,我们可以改变屏幕的亮度。现在,蹦到您脑袋里的第一个想法可能是:
$ sudo find -L /sys/class/backlight -maxdepth 2 -name '*brightness*'
/sys/class/backlight/thinkpad_screen/brightness
$ cd /sys/class/backlight/thinkpad_screen
$ sudo echo 3 > brightness
An error occurred while redirecting file 'brightness'
open: Permission denied
报错原因:|、>、和 < 是通过 shell 执行的,而不是被各个程序单独执行。
echo 等程序并不知道 | 的存在,它们只知道从自己的输入输出流中进行读写。 对于上面这种情况, shell (权限为您的当前用户) 在设置 sudo echo 前尝试打开 brightness 文件并写入,但是系统拒绝了 shell 的操作因为此时 shell 不是根用户。
明白这一点后,我们可以这样操作:
关于 tee
上文介绍了简单的使用 tee 提权 echo 的方式
tee 命令基于标准输入读取数据,标准输出或文件写入数据。
P.S. 这个命令的名字由来就是 T 字形("tee")的管道接头,一入二出
Eg.
此时这个输出内容不仅被写入 output.txt 文件,也被显示在标准输出中。
- 追加:
-a - 多文件:
[command] | tee [file1] [file2] [file3] - 管道支持:下面的命令不仅会将文件名存入
output.txt文件中,还会通过wc命令让你知道输入到output.txt中的文件数目:ls file* | tee output.txt | wc -l - 在 Vim 中使用 tee 提权:
:w !sudo tee % - 忽视终端:
-i此时可用Ctrl+C优雅退出了
课后习题
Quote
- 转义字符
\ - 单引号
'保留其中的 literal value - 双引号
"保留除了 ‘$’, ‘`’, ‘\’, ’!‘(当 history expansion 启用时)
权限
ls -l 的长表示
此时我们 WSL 中的权限为
其中第一列的字符表示文件或目录的类型和UGO权限
$$
\underbrace{ \textcolor{Red}{\text{-}} }{ \text{ 文件类型 } }
\underbrace{ \textcolor{Green}{\text{rw-}} }
\underbrace{ \textcolor{Orange}{\text{r--}} }} { \text{ G.用户组权限 } }
\underbrace{ \textcolor{Black}{\text{r--}} }
$$
- 文件类型
- - 表示普通文件
- d 表示目录
- l 表示符号链接
- c 表示字符设备文件
- b 表示块设备文件
- s 表示套接字文件
- p 表示管道文件
- 权限
- } r 读
- w 写
- x 执行
- - 无权限
第二列的 1 是硬链接数
第三列的 root 是所有者名称
第四列的 root 是所属组名称
第五列的 61 是文件大小,以字节(1B) / Linux 数据块(512B) 为单位
第六列的是创建 / 最近一次修改时间
第七列为文件名
chown 修改所属用户或用户组
将 [File]/[Directory] 的所属用户改为 UserName
同上
chgrp 修改所属组
chmod 修改权限

- Mode 格式:
[ugoa...][[+-=][rwxX]...][,...]- u 表示该文件的拥有者,g 表示与该文件的拥有者属于同一个群体(group)者,o 表示其他以外的人,a 表示这三者皆是。
-
- 表示增加权限、- 表示取消权限
- r 表示可读取,w 表示可写入,x 表示可执行
- 参数
-R: 递归变更
Example
将文件 file1.txt 与 file2.txt 设为该文件的拥有者和与其所属同一个群体者可写入,但其他以外的人则不可写入
执行完后:
shebang #!
带有 shebang 的文本文件中的其余部分会在 Unix 类系统下被 program loader 当作解释器指令
#!/bin/sh– Execute the file using the Bourne shell, or a compatible shell, assumed to be in the /bin directory#!/bin/bash– Execute the file using the Bash shell#!/usr/bin/pwsh– Execute the file using PowerShell#!/usr/bin/env python3– Execute with a Python interpreter, using the env program search path to find it#!/bin/false– Do nothing, but return a non-zero exit status, indicating failure. Used to prevent stand-alone execution of a script file intended for execution in a specific context, such as by the.command from sh/bash,sourcefrom csh/tcsh, or as a .profile, .cshrc, or .login file.
注意,脚本并不一定只有用 bash 写才能在终端里调用。比如说,这是一段 Python 脚本,作用是将输入的参数倒序输出:
内核知道去用 python 解释器而不是 shell 命令来运行这段脚本,是因为脚本的开头第一行的 shebang。
在 shebang 行中使用 env 命令是一种好的实践,它会利用环境变量中的程序来解析该脚本,这样就提高来您的脚本的可移植性。env 会利用我们第一节讲座中介绍过的PATH 环境变量来进行定位。 例如,使用了env的shebang看上去是这样的#!/usr/bin/env python。
管道 | 输出的最后更改日期,grep
stat -c %y semester没有用管道stat semester | grep Modify > /home/last-modified.txt输出内容为:Modify: 2024-02-05 16:07:02.751721116 +0800
grep 简明使用方法
默认情况下,| grep TEXT 会输出 输入流中含有 TEXT 的行
也可以指定文件名,使用 grep TEXT file.txt
常用选项:
- -i:忽略大小写进行匹配。
- -C:查看上下文 (Context) Eg. -C 5 输出前后 5 行
- -v:反向查找,只打印不匹配的行。
- -n:显示匹配行的行号。
- -r:递归查找子目录中的文件。
- -R:递归地进入子目录并搜索所有的文本文件。
- -l:只打印匹配的文件名。
- -c:只打印匹配的行数。
- -E:使用(扩展)正则表达式
/sys
这一题要求查看电量或 CPU 温度
由于笔者使用的是 WSL,就使用了 find 来定位电量文件 capacity