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,source
from 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