Course overview + the shell · Missing Semester (mit.edu)
Bourne Again SHell,简称bash
Using the shell
我打开Ubuntu 22.04.3 LTS(安装过程在windows中使用linux-CSDN博客
daisy@Daisy:~$
我现在所在的机器叫Daisy,用户名是daisy所在的工作文件夹是~(home),$说明不是root用户
daisy@Daisy:~$ echo $SHELL
/bin/bash
需要使用类似Bash或ZSH的Unix shell。如果你使用的是Linux或macOS操作系统,你不需要进行任何特殊操作。如果你使用的是Windows操作系统,你需要确保你没有在运行cmd.exe或PowerShell。为了确保你正在运行适当的shell,你可以尝试执行命令echo $SHELL。如果它显示类似/bin/bash或/usr/bin/zsh的内容,那就表示你正在运行正确的程序。
daisy@Daisy:~$ date
Tue Jan 30 14:42:51 CST 2024
daisy@Daisy:~$ echo hello
hello
echo是program,hello是参数。如果想提供含空格的参数,那么可以用'或"或\,即"My Photos" My\ Photos。
daisy@Daisy:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
daisy@Daisy:~$ which echo
/usr/bin/echo
daisy@Daisy:~$ /usr/bin/echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
echo $PATH命令用于打印环境变量PATH的值。环境变量PATH是一个由冒号分隔的目录列表。(我的电脑列出来一大串...)
which echo命令用于查找名为"echo"的程序文件的路径。
/usr/bin/echo $PATH命令通过直接指定程序文件的路径来执行"echo"命令。结果与之前打印的$PATH的值相同。
Navigating in the shell,导航
在shell中,路径在Linux和macOS上是用/分隔,在Windows上是用\分隔。
在Linux和macOS上,路径/是文件系统的“根”,所有目录和文件都位于其下,而在Windows上,每个磁盘分区(例如C:\)都有一个根目录。
以/开头的路径被称为绝对路径。任何其他路径都是相对路径,相对路径是相对于当前工作目录的。
我们可以用pwd命令查看当前工作目录,并用cd命令更改它。
pwd : print working directory
cd : change directory
.表示当前目录,..表示其父目录
daisy@Daisy:~$ pwd
/home/daisy
daisy@Daisy:~$ ls
daisy@Daisy:~$ cd ..
daisy@Daisy:/home$ ls
daisy
daisy@Daisy:/home$ cd ..
daisy@Daisy:/$ ls
bin dev home lib lib64 lost+found mnt proc run snap sys usr
boot etc init lib32 libx32 media opt root sbin srv tmp var
Daisydaisydaisy@Daisy MINGW64 /d/Daisydaisydaisy/Documents
$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Mandatory arguments to long options are mandatory for short options too.
-a, --all do not ignore entries starting with .
-A, --almost-all do not list implied . and ..
--author with -l, print the author of each file
......
-l use a long listing format
daisy@Daisy:~$ ls -l /home
total 4
drwxr-x--- 2 daisy daisy 4096 Jan 30 14:29 daisy
Daisydaisydaisy@Daisy MINGW64 /d/Daisydaisydaisy/Documents
$ ls -l
total 4544
drwxr-xr-x 1 Daisydaisydaisy 197121 0 Jan 28 12:28 23fall/
-rw-r--r-- 1 Daisydaisydaisy 197121 2798571 Jan 26 21:32 微信图片_20240126213157.jpg
- 23fall/:这是一个目录。权限部分的drwxr-xr-x表示所有者有读、写和执行的权限,而所属组用户和其他用户只有读和执行的权限。它的大小为0字节,最后修改日期为2024年1月28日。
- 微信图片_20240126213157.jpg:这是一个文件。权限部分的-rw-r--r--表示所有者有读和写的权限,而所属组用户和其他用户只有读的权限。它的大小为2798571字节。
总计(total)显示了当前目录下的文件和目录的总大小,该值为4544字节。
行首的d告诉我们23fall/是一个目录。然后是三组三个字符(rwx)。它们分别表示文件所有者(Daisydaisydaisy)、所属组(197121)和其他人对相关项目拥有的权限。修改w,执行x,读取r。
- mv:移动文件。mv [源文件/目录] [目标文件/目录]。如果目标是一个目录,那么源文件将被移动到目标目录中;如果目标是一个文件名,则源文件将被重命名为目标文件名。
- cp:复制文件或目录。cp [源文件/目录] [目标文件/目录]。如果目标是一个目录,那么源文件将被复制到目标目录中;如果目标是一个文件名,则源文件将被复制并重命名为目标文件名。
- mkdir:创建新目录。mkdir [目录名]。将在当前工作目录中创建一个新的子目录。
- man:查看命令的帮助文档、手册页(manual page)。man [命令名]。可以使用箭头键进行滚动,按q退出man页面。
daisy@Daisy:~$ man ls
Connecting programs
最简单的重定向形式是< file和> file。
Daisydaisydaisy@Daisy MINGW64 /d/Daisydaisydaisy/Documents
$ echo hello > hello.txt
Daisydaisydaisy@Daisy MINGW64 /d/Daisydaisydaisy/Documents
$ cat hello.txt
hello
cat是一个用于concatenate连接文件的程序。当给定文件名作为参数时,它按顺序将每个文件的内容打印到其输出流。
你还可以使用>>来追加到文件中。这种类型的输入/输出重定向真正发挥作用的地方是使用管道。|运算符允许你“链式”地连接程序,使得一个程序的输出成为另一个程序的输入。
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
第一行使用ls命令,并通过tail命令选择最后一行进行显示。
Daisydaisydaisy@Daisy MINGW64 /d/Daisydaisydaisy/Documents
$ tail --help
Print the last 10 lines of each FILE to standard output.
Mandatory arguments to long options are mandatory for short options too.
......
-n, --lines=[+]NUM output the last NUM lines, instead of the last 10;
or use -n +NUM to output starting with line NUM
......
第二行使用curl命令发送一个HTTP HEAD请求到google.com,并使用--silent选项使其静默运行。然后使用grep命令和--ignore-case选项查找响应头中包含"content-length"的行。最后使用cut命令和--delimiter选项指定分隔符为空格,并选择第二个字段进行显示。结果显示了一个值为219的数字。
curl(CommandLine Uniform Resource Locator)
grep 文本搜索
A versatile and powerful tool,多功能的
在大多数类Unix系统中,有一个特殊的用户,即“root”用户。root用户几乎没有任何访问限制,可以创建、读取、更新和删除系统中的任何文件。
但通常情况下,你不会以root用户身份登录到系统,因为很容易意外地出错。相反,你会使用sudo命令(super user)。当你遇到"Permission denied"(权限被拒绝)错误时,通常是因为你需要以root身份执行某些操作。
调节笔记本电脑屏幕的亮度:
$ 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
但是会出现一个权限被拒绝的错误。于是修改为
$ echo 3 | sudo tee brightness
由于tee程序是用root权限打开/sys文件进行写入操作,所以权限都是可以正常工作的。
Exercises
Solution-课程概览与 shell · the missing semester of your cs education (missing-semester-cn.github.io)
missing semester - The shell - zju_cxl - 博客园 (cnblogs.com)
2.创建一个名为missing的新目录,在/tmp目录下。
daisy@Daisy:~$ cd ..
daisy@Daisy:/home$ cd ..
daisy@Daisy:/$ cd tmp
daisy@Daisy:/tmp$ mkdir missing
daisy@Daisy:/tmp$ ls
missing
3.查找touch程序。
daisy@Daisy:/tmp$ man touch
按enter可以滚动界面。
4.使用touch命令在missing目录下创建一个名为semester的新文件。
daisy@Daisy:/tmp$ cd missing
daisy@Daisy:/tmp/missing$ touch semester
daisy@Daisy:/tmp/missing$ ls -l
total 0
-rw-r--r-- 1 daisy daisy 0 Jan 30 15:30 semester
5.逐行将以下内容写入该文件:
#!/bin/sh
curl --head --silent https://missing.csail.mit.edu
第一行可能有些棘手。了解到在Bash中,#表示注释,而!即使在双引号(")字符串中也有特殊含义。而Bash对单引号(')字符串的处理方式不同:在这种情况下,它们会起作用。查看Bash引用手册页面以获取更多信息。
Bash引用手册页面说:
引用用于消除某些字符或单词对于shell的特殊含义。引用可以用于禁用特殊字符的特殊处理,防止保留字被识别为保留字,并防止参数扩展。历史扩展字符(通常为'!')必须进行引用,以防止历史扩展。
所以需要用单引号引用第一行,用>>来追加第二行到文件中,否则会覆盖第一行。
daisy@Daisy:/tmp/missing$ echo '#!/bin/sh' > semester
daisy@Daisy:/tmp/missing$ echo curl --head --silent https://missing.csail.mit.edu >> semester
daisy@Daisy:/tmp/missing$ cat semester
#!/bin/sh
curl --head --silent https://missing.csail.mit.edu
6.尝试执行该文件,即在shell中输入脚本的路径(./semester),然后按回车键。通过查看ls命令的输出,了解为什么它无法工作(提示:查看文件的权限位)。
daisy@Daisy:/tmp/missing$ ./semester
-bash: ./semester: Permission denied
daisy@Daisy:/tmp/missing$ ls -l
total 4
-rw-r--r-- 1 daisy daisy 61 Jan 30 15:50 semester
权限位没有x。
7.通过显式启动sh解释器并将文件semester作为第一个参数提供,即sh semester,来运行该命令。为什么这样可以工作,而./semester不能?
daisy@Daisy:/tmp/missing$ sh semester
HTTP/2 200
......
content-length: 8213
daisy@Daisy:/tmp/missing$ man sh
8.查找chmod程序。
daisy@Daisy:/tmp/missing$ man chmod
9.使用chmod命令使得可以通过运行./semester来执行该命令,而不必输入sh semester。你的shell如何知道该文件应该使用sh来解释?参考这个shebang行的页面获取更多信息。
daisy@Daisy:/tmp/missing$ chmod +x semester
daisy@Daisy:/tmp/missing$ ls -l
total 4
-rwxr-xr-x 1 daisy daisy 61 Jan 30 15:50 semester
daisy@Daisy:/tmp/missing$ ./semester
HTTP/2 200
......
content-length: 8213
shebang说:
Shebang是一个由井号和感叹号(!)组成的字符序列,位于脚本开头。它在类Unix操作系统中用于指定执行脚本的解释器。当将带有shebang的文本文件视为可执行文件时,程序加载器会解析初始行的其余部分作为解释器指令。然后,它执行指定的解释器程序,并将脚本的路径作为参数传递给它。
也可以用chmod 777 semester 或chmod 744 semester来实现,
- chmod 777 semester:该命令将文件的权限设置为拥有者、组和其他用户都具有读取、写入和执行的权限。
- chmod 744 semester:该命令将文件的权限设置为拥有者具有读取、写入和执行的权限,而组和其他用户则只有读取权限。
10.使用|和>将semester输出的“上次修改”日期写入名为last-modified.txt的文件中,该文件位于你的home directory主目录下。
daisy@Daisy:/tmp/missing$ ./semester | grep last-modified > ~/last-modified.txt
daisy@Daisy:/tmp/missing$ cat ~/last-modified.txt
last-modified: Mon, 08 Jan 2024 22:40:31 GMT
11.编写一个命令,从/sys中读取你的笔记本电池电量或台式机的CPU温度。
daisy@Daisy:/tmp/missing$ cat /sys/class/power_supply/BAT1/capacity
100