前言
提示:这里可以添加本文要记录的大概内容:
2021-2022学年第二学期,我们学习了Linux操作系统,但是发现学习成果非常不好,就连老师布置的实验都不会做,所以特来复习一遍。
本次学习使用的参考书为《Linux命令行大全》(第2版),因为也跟着老师走了一遍Linux的课程,所以本次复习主要是来熟练命令行操作,话不多说,开干!
一、什么是Shell
Shell 是一个程序,他接收由键盘输入的命令并将其传递给操作系统来执行。
几个简单的命令:
命令 | 含义 |
---|---|
date | 显示当前的时间和日期 |
cal | 默认显示当前月份的日历 |
df | 查看磁盘当前可用空间 |
free | 查看可用内存容量 |
exit | 结束终端(关闭终端仿真器窗口Ctrl+D) |
二、导航
使用命令pwd/ls/cd在LInux文件系统中导航:
命令 | 作用 |
---|---|
pwd | 显示当前工作目录 |
ls | 列出当前工作目录中的文件和子目录 |
cd | 更改当前工作目录 |
一些有用的便捷写法:
便捷写法 | 效果 |
---|---|
cd | 更改为用户主目录 |
cd - | 切换回前一个工作目录 |
cd ~user_name | 更改为用户 user_name 的主目录 |
. | 当前目录 |
. . | 父目录 |
~ | 用户主目录 |
三、探索 Linux 系统
命令 | 作用 |
---|---|
ls | 列出目录内容 |
file | 确定文件类型 |
less | 查看文件内容(文本文件) |
ls
常用的 ls 命令选项:
选项 | 描述 |
---|---|
-a, --all | 列出所有文件(包括以点开头的隐藏文件) |
-A, --almost-all | 与 -a 选项类似,但不列出 .(当前工作目录)和 …(父目录) |
-d, --directory | 通常,如果指定了目录,ls 命令会列出该目录中的内容而非目录本身。将此选项与 -l 结合使用,可查看目录的详细信息,而不是其中的内容 |
-F, --classify | 该选项会在每个列出的名称后面加上类型指示符(如目录名后面会有 “ / ”) |
-h, --human-readable | 在长格式的输出结果中,以可读形式显示文件大小 |
-l | 以长格式显示输出结果 |
-r, --reverse | 以降序显示输出结果 |
-S | 按照文件大小排序输出结果 |
-t | 按照修改日期排序输出结果 |
注:在 Linux 中,命令选项和文件名一样,区分大小写。
file
进一步了解长格式:
一个文件的不同字段及其含义:
字段 | 含义 |
---|---|
dr-xr-xr-x | 文件访问权限。第一个字符指明了文件类型(连字符-表示普通文件,d表示目录),接下来分别是文件属主、文件属组和其他人的访问权限 |
1 | 文件的硬链接数量 |
root | 文件属主 |
root | 文件属组 |
49152 | 文件大小(字节数) |
2月 28 14:12 | 文件最后的修改日期和时间 |
bin | 目录名/文件名 |
less
less 命令:
命令 | 操作 |
---|---|
上翻页键(Puge Up)或 b | 后翻一页 |
下翻页键(Page Down)或 空格 | 前翻一页 |
上方向键 | 向后一行 |
下方向键 | 向前一行 |
G | 移动到文本文件末尾 |
1G 或 g | 移动到文本文件开头 |
/characters | 向前搜索指定的字符串 |
n | 重复上一次搜索 |
h | 显示帮助信息 |
q | 退出 less 命令 |
注:如果不小心查看了非文本文件,终端窗口中会充斥这混乱的字符,可用输入 reset 命令来恢复正常。
粘贴复制小技巧:双击复制文件名,单击中键粘贴。
四、操作文件和目录
命令 | 作用 |
---|---|
mkdir | 创建目录 |
cp | 复制文件和目录 |
mv | 移动和重命名文件和目录 |
rm | 删除文件和目录 |
ln | 创建硬链接和符号连接 |
通配符
通配符及其含义:
通配符 | 含义 |
---|---|
* | 匹配任意多个字符 |
? | 匹配任意单个字符 |
characters | 匹配属于字符集合 characters 中的任意单个字符 |
!characters | 匹配不属于字符集合 characters 中的任意单个字符 |
[[:class:]] | 匹配属于字符类 class 中的任意单个字符 |
常用的字符类
字符类 | 含义 |
---|---|
[:alnum:] | 匹配任意单个字母数字(alphanumeric)字符 |
[:alpha:] | 匹配任意单个字母 |
[:digit:] | 匹配任意单个数字 |
[:lower:] | 匹配任意单个小写字母 |
[:upper:] | 陪陪任意单个大写字母 |
mkdir
用法为:mkdir [-p] directory...
注意,如果参数后面出现3个点号,则表示该参数可用重复出现,即 mkdir 命令可用创建一个或多个目录:mkdir dir1
或 mkdir dir1 dir2 dir3
(参数 -p 确保目录名称存在,不存在的就建一个)
cp
用法为:cp item1 item2
或 cp item... directory
cp 常用命令选项:
选项 | 含义 |
---|---|
-a, --archive | 复制文件和目录及其包括所有权与权限在内的所有属性 |
-i, --interactive | 在覆盖已有文件以前,提示用户确认 |
-r, --recursive | 递归复制目录及其内容(在复制目录时,需要与-a选项二选一) |
-u, --update | 在将文件从一个目录复制到目标目录时,只复制目标目录中不存在或比目标目录中现有文件更新的文件 |
-v, --verbose | 在进行复制时显示相关信息 |
cp 命令示例:
命令 | 结果 |
---|---|
cp file1 file2 | 将文件file1复制为文件file2。如果文件file2存在,使用文件file1的内容将覆盖。如果文件file2不存在,则创建文件file2 |
cp-i file1 file2 | 和前一个命令一样,除了当文件file2存在时,在覆盖之前会提示用户 |
cp file1 file2 dir1 | 将文件file1和文件file2复制到目录dir1。该目录必须实现存在 |
cp dir1/* dir2 | 使用通配符,将目录dir1中所有文件复制到目录dir2。目录dir2必须事先存在 |
cp-r dir1 dir2 | 将目录dir1的内容复制到目录dir2。如果dir2不存在,先创建,否则直接复制 |
mv
mv 的用法和 cp 一样:mv item1 item2
或 mv item... directory
mv 的选项也一样,同 cp 都有 -i, -u, -v
rm
用为法:rm item...
rm 命令选项:
选项 | 含义 |
---|---|
-i, --interactive | 删除提示 |
-r, --recursive | 递归删除目录(删除目录必选) |
-f, --force | 忽略不存在的文件,不提示(该选项会屏蔽掉 --interactive 选项) |
-v, --verbose | 显示相关信息 |
ln
ln 命令创建硬链接:ln file link
ln 命令创建符号链接:ln -s item link
( item 可以是文件或目录)
五、和命令打交道
这里将介绍以下命令:
命令 | 作用 |
---|---|
type | 显示命令类型 |
which | 显示可执行文件的位置 |
help | 获取 Shell 内建命令的帮助信息 |
man | 显示命令的手册页 |
apropos | 显示命令的命令清单 |
whatis | 显示手册页的简述 |
info | 显示命令的 info 条目 |
alias | 创建自己的命令 |
六、重定向
I/O 重定向可以在命令和文件之间改变输入和输出,还可以连接多个命令,形成功能强大的管道。这里将介绍以下命令:
命令 | 作用 |
---|---|
cat | 拼接文件 |
sort | 排序文本行 |
uniq | 报告或忽视重复的行 |
wc | 统计文件中换行符、单词以及字节的数量 |
grep | 输出与模式匹配的行 |
head | 输出文件的开头部分 |
tail | 输出文件的结尾部分 |
tee | 读取标准输入并将结果写入标准输出和文件 |
简单来说,I/O 重定向允许我们修改输出结果的去处和输入的来源。通常来说,输出结果会显示在屏幕,输入则来自键盘,但有了 I/O 重定向,两者我们都可以改变。
标准输出重定向
要想把标准输出重定向到其他文件而非出现在屏幕上,可以使用重定向操作符 >,后面跟上文件名即可。不过需要注意的是,当使用重定向符 > 对标准输出进行重定向时,会完全重写目标文件。当重定向错误时就会停止写入操作,那么从这里可以引申出一个小技巧:只需使用不加任何命令的重定向操作符,就可以截断现有文件或创建一个新的空文件:> ls-output.txt
另外,使用重定向操作符 >> 会将标准输出追加到文件尾部。同样的,如果指定的文件不存在,则像操作符 > 一样,新建该文件。
标准输出重定向命令示例:
ls -l /usr/bin > ls-output.txt
ll ls-output.txt
less ls-output.txt
> ls-output.txt
ls -l /usr/bin >> ls-output.txt
标准错误重定向
虽然我们将前三个文件流称为标准输入、标准输出及标准错误,但在 Shell 内部分别是用文件描述符 0、1 及 2 引用它们的。Shell 提供了使用文件描述编号来重定向文件的写法。由于标准错误对应的文件描述符为 2,因此可以用下列写法来重定向标准错误:ls -l /bin/usr 2> ls-error.txt
如果我们想将标准输出和标准错误重定向到同一个文件中,可以这样做:ls -l /bin/usr &> ls-output.txt
或 ls -l /bin/usr &>> ls-output.txt
或者我们想着丢弃用不着的输出结果,就可以用以下命令来丢弃命令的错误信息:ls -l /bin/usr 2> /dev/null
标准输入重定向
cat 命令读取一个或多个文件并将其复制到标准输出:cat filename
。而在缺少文件名参数的时候(cat
),cat 命令会将标准输入(键盘)复制到标准输出上(Ctrl-D结束输入),于是我们便可以利用此行为创建短小的文本文件:cat > filename
(当我们想要查看结果的时候,可以再次使用 cat 命令将文件复制到标准输出:cat filename
)。
现在我们知道除文件名参数之外,cat 是如何接收标准输入的,现在让我们尝试重定向标准输入:cat < filename
(通过重定向操作符 <,我们将标准输入方式从键盘改为文件 filename)
管道
Shell 的管道特性利用了命令能够从标准输入读取数据并将数据发送到标准输出的能力。通过管道操作符 |,可以将一个命令的标准输出传给另一个命令的标准输入:command1 | command2
。而对于那些将结果发往标准输出的命令,我们都可以使用 less 命令将其输出结果逐页显示出来:ls -l /usr/bin | less
管道往往用来执行复杂的数据操作。我们也可以把多个命令组合在一起形成管道,这种方式中用到的命令通常被称为过滤器(filter)。过滤器获取输入,对其做出改动,然后输出。
sort——排序列表
排序列表可以使用 sort 命令。假设我们现在要把 /bin 和 /usr/bin 目录下的所有可执行文件合并成一个列表,然后排序并查看最终结果:ls /bin /usr/bin | sort | less
在这里,因为我们指定了两个目录(/bin 和 /usr/bin),所以 ls 命令的输出结果包含了两个排序列表,分别对应每个目录。在管道中加入 sort 命令,就可以修改 ls 命令的输出结果,生成单个有序列表。
> 和 | 之间的差异
简单说,重定向操作符将命令与文件连接在一起,而管道操作符将一个命令的输出结果与另一个命令的输出结果连接在一起:command1 > file1
和 command1 | command2
uniq——报告或忽略重复行
uniq 命令通常与 sort 命令配合使用。nuiq 命令可以从标准输入或单个文件名参数中获取有序的数据列表,默认删除所有重复行:ls /bin /usr/bin | sort | uniq | less
如果想看都有哪些重复行,则可以使用 uniq 命令的 -d 选项:ls /bin /usr/bin | sort | uniq -d | less
wc——统计文件中换行符、单词以及字节的数量
wc(word count,译为单词统计)命令可用于统计文件中换行符(行数)、单词以及字节的数量:wc filename
(和之前的命令一样,如果没有指定命令行参数,wc 命令会从标准输入中读取)。而 -l 选项限制只输出文件行数,将该命令加入管道中,能够方便地完成统计工作。要想知道有序列表包含多少行,可以这样:ls /bin /usr/bin | sort | uniq | wc -l
grep——输出与模式匹配的行
grep 命令可用于在文件中查找文本模式,用法如下:grep pattern filename
当 grep 命令在文件中遇到“模式”的时候,会输出包含该模式的行。假设我们想从程序列表中找出名称中包含单词 zip 的所有文件,利用这种方法,我们可以得知系统中有多少程序和文件压缩有关,实现方法为:ls /bin /usr/bin | sort | uniq | grep zip
此外,grep 命令还有两个很方便的选项:-i(忽略大小写)和 -v(只输出不匹配指定模式的行)。
head/tail——输出文件的开头/结尾部分
head 命令和 tail 命令默认分别能够输出文件的前 10 行和后 10 行,不过行数可以通过 -n 选项来调整:head -n num filename
或 tail -n num filename
(输出文件 filename 的前后 num 行),运用在管道中为:ls /usr/bin | tail -n 5
另外,通过 -f 选项,tail 命令会持续观察该文件,一旦添加了新行,立即就会显示在屏幕中。这个过程直到按 Ctr-C 组合键后才会停止。该选项适合同步观察日志被写入的过程,比如查看 /var/log/messages 文件或者 /var/log/syslog 文件:tail -f /var/log/messages
tee——读取标准输入并将输出结果写入标准输出和文件
tee 命令就是在 管道上安装的一个“T”形头,它从标准输入读取内容,然后将其复制到标准输出(允许数据沿着管道继续向下流动)和其他文件中(捕获管道处理过程中的某个中间阶段的数据会很有用),例如我们可以在 grep 命令过滤管道内容之前加入 tee 命令,将整个目录保存到 ls.txt 中:ls /usr/bin | tee ls.txt | grep zip
七、Shell
echo 命令显示一行文本(将其文本参数输出到标准输出)
扩展
每次输入命令并按 Enter 建的时候,在执行命令之前,Bash 会执行一些文本替换操作,这一处理过程称作扩展(如通配符*)。
路径名扩展:echo .[!.]*
= ls -A
浪纹线扩展:echo ~user name
(浪纹线 ~ 用于单词之前,会扩展为同名用户的主目录。如果为指定单词,则扩展为当前用户的主目录 echo ~
)
算数扩展 echo $((expression))
(Shell 可以通过扩展执行证书算数运算,支持加减乘除求模和求幂,如:echo $(( (5**2) * 3))
花括号扩展
echo Front-{A,B,C}-Back
echo Number_{1..5}
echo {01..15}
echo {001..15}
echo {Z..A}
echo a{A{1,2},B{3,4}}b
mkdir {2012..2022}-{01..12}
结果如下:
Front-A-Back Front-B-Back Front-C-Back
Number_1 Number_2 Number_3 Number_4 Number_5
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
003 004 005 006 007 008 009 010 011 012 013 014 015
Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
aA1b aA2b aB3b aB4b
按照日期创建一大堆文件夹用
参数扩展:其实也就是变量,用法为:echo $变量名
,要想查看可用变量列表,可以这样:printenv | less
命令替换:允许我们使用命令的输出结果作为扩展结果:echo $(ls)
这里有作者最喜欢的一种用法:ls -l $(which cp)
,在这里,我们将 which cp
的输出结果作为 ls
命令的参数,因而得以在无须知道完整路径的情况下获得 cp
命令的详细信息。
命令替换其实并不仅限于简单命令,整个通道都可以用来替换:file $(ls -d /usr/bin/* | grep zip)
,在这个例子中,管道的输出结果变成了 file
命令的参数列表。
引用
先来看两个例子:
echo this is a test
echo The total is $100.00
结果为:
this is a test
The total is 00.00
为什么会这样呢?原来,在第一个例子中,Shell 通过单词分割(word splitting),删除了 echo
命令参数列表中多余的空白字符。在第二个例子中,参数扩展将 $1 扩展成了空字符(因为改变了并未定义)。
为解决类似上面的例子,Shell 提供的引用机制可以有选择地选择不需要的扩展。
第一种引用类型是双引号,双引号里面的所有特殊字符都将丧失其特殊含义,而被视作普通字符。$(美元符号)、\(反斜线)、`(反引号)除外。这意味着单词分割、路径名扩展、浪纹线扩展、花括号扩展全部失效,但是参数扩展、算数扩展、命令替换仍然可用( $(参数)、 $(算术表达式)、 $(命令))。
如果我们想禁用所有扩展,可用使用单引号。下面比较了无引号、双引号以及单引号的效果:
转义字符只会在双引号(或文件名)中起作用,用法为在单个有特殊字符前加反斜线\:echo "The balance for user $USER is: \$5.00"
反斜线除了转义字符,还可以用于描述某些为控制码的特殊字符,以下是部分常见的反斜线转义序列:
转义序列 | 含义 |
---|---|
\a | 响铃(使计算机发出蜂鸣声) |
\b | 退格符 |
\n | 新行符 |
\r | 回车符 |
\t | 制表符 |
echo 的 -e 选项能够解释转义序列(当然,也可以将其放入 $‘’ 内),由此原理我们可以得到一个简单的计时器:
sleep 10; echo -e "Time's up\a"
或 sleep 10; echo "Time's up" $'\a'
八、高级键盘技巧
这里我们主要学习两个命令:
命令 | 作用 |
---|---|
clear | 清除终端屏幕 |
history | 显示或操作命令示例列表 |
编辑命令行
光标移动的组合键:
组合键 | 操作 |
---|---|
Ctrl-A | 将光标移动到行首 |
Ctrl-E | 将光标移动到行尾 |
Ctrl-F | 将光标向前移动一个字符;等同于右方向键 |
Ctrl-B | 将光标向后移动一个字符;等同于左方向键 |
Alt-F | 将光标向前移动一个单词 |
Alt-B | 将光标向后移动一个单词 |
Ctrl-L | 清除屏幕,将光标移动到左上角。等同于 clear 命令 |
修改命令行文本的组合键
组合键 | 操作 |
---|---|
Ctrl-D | 删除光标处的字符 |
Ctrl-T | 将光标处字符与其之前的字符对调 |
Alt-T | 将光标处的单词与其之前的单词对调 |
Alt-L | 将从光标处到单词结尾的字符转换为小写 |
Alt-U | 将从光标处到单词结尾的字符转换为大写 |
剪切和粘贴文本的组合键
组合键 | 操作 |
---|---|
Ctrl-K | 剪切从光标处到行尾的文本 |
Ctrl-U | 剪切从光标处到行首的文本 |
Alt-D | 剪切从光标处到但钱单词结尾的文本 |
Alt-BackSpace | 剪切从光标处到但钱单词开头的文本。如果光标已位于单词开头,则剪切上一个单词 |
Ctrl-Y | 粘贴 |
补全功能
Shell 可以通过补全机制帮助我们提高效率:在输入命令时按 Tab 键就能够触发补全功能。最常见的用法是路径名补全,但补全功能同样适用于变量(如果单词以 $ 开头)、用户名(如果单词以 ~ 开头)、命令(如果单词是行中的首个单词)及主机名(如果单词以 @ 开头)。
下面是与补全功能关联的组合键:
组合键 | 操作 |
---|---|
Alt-$ | 显示可能的补全结果(也可以同时按两次 Tab 键) |
Alt-* | 插入所有可能的补全结果 |
命令历史记录
可以使用下列命令随时查看命令历史记录的内容:history | less
;如果我们想找出用来列出 /usr/bin 目录内容的命令可以这样做:history | grep /usr/bin
在使用 history 命令后的输出结果中,第一个显示的是历史记录中该命令的编号,我们可以使用历史扩展来立即重用这个命令,直接在编号前加一个!就可以:!编号
或者可以这样做:使用 Ctrl-R 组合键开启增量搜索,如果找到了匹配项,可以直接回车执行,或者使用 Ctrl- J 组合键将该匹配项复制到当前命令行,要想查找下一个匹配项则再次使用 Ctrl-R 组合键,如若退出搜索,使用 Ctrl-G 或 Ctrl-C 组合键即可。
以下是部分可用于操作命令历史记录的组合键:
组合键 | 操作 |
---|---|
Ctrl-P | 移动到上一条历史记录(上方向键) |
Ctrl-N | 移动到下一条历史记录(下方向键) |
Alt-< | 移动到历史记录列表的开头(顶部) |
Alt-> | 移动到历史记录列表的结尾(底部),也就是当前命令行 |
Ctrl-R | 反向增量搜索,从当前命令行开始向上增量搜索历史记录列表 |
Alt-P | 非反向增量搜索,在这种类型的搜索中,先输入带搜索的字符串,然后回车即可 |
Alt-N | 非增量向前查找 |
Ctrl-O | 执行历史记录列表中的当前命令并移动到下一条命令(重复顺序执行历史命令时使用) |
这里是一些其他的历史扩展命令:
序列 | 操作 |
---|---|
!! | 重复上一个命令 |
!number | 重复命令历史记录列表中第 number 个命令 |
!string | 重复以 string 开头的最后一个命令 |
!?string | 重复包含 string 的最后一个命令 |
九、权限
接下里我们会学习系统安全的基础知识和以下命令:
命令 | 作用 |
---|---|
id | 查看用户身份 |
chmod | 修改文件模式 |
umask | 设置默认权限 |
su | 以其他用户身份启动 Shell |
sudo | 以其他用户命令执行命令 |
chown | 更改文件属主个属性 |
chgrp | 更改文件属组 |
passwd | 修改密码 |
属主、属组以及其他用户
用户可以拥有文件和目录,而如果文件或目录属于某个用户,则该用户(属主)拥有访问权。用户反过来也可以属于由一个或多个用户组成的组(属组),属组用户被文件和目录的属主授予访问权。除了属组授权,属主还可以为所有用户授权,想要查看用户身份信息,可以使用 id
命令。
在创建用户时,会为用户分配一个称为用户 ID(uid )的数字,为了便于使用,uid 又被映射为用户名。用户还会得到一个属组 ID(gid),还可以归属于其他属组。属主定义在 /etc/passwd 文件中,属组定义在 /etc/group 文件中。在创建用户和属组时,这些文件随 /etc/shadow 文件一并改动,后者保存了用户的密码信息。对于每一个用户,/etc/passwd 文件定义了用户(登录)名、uid、gid、用户的真实姓名、主目录以及登录 Shell
读取、写入和执行
文件和目录的访问权限是按照读取、写入、执行来定义的,观察 ls 命令的输出结果就可以看出来列表项的前 10 个字符是文件属性,其中第一个字符是文件类型,后面 9 个字符是文件模式,分别代表文件属主、文件属组、其他用户的读取、写入、执行权限。
下面是常见的文件类型:
属性 | 文件类型 |
---|---|
- | 普通属性 |
d | 目录 |
l | 符号链接(对于符号链接,剩下的文件属性始终是虚设的,只有符号链接指向的文件的属性才是真正的文件属性) |
c | 字符设备文件(这种文件类型指的是按字节流处理数据的设备,例如终端或 /dev/null |
b | 块设备文件(这种文件类型指的是按块处理数据的设备,例如硬盘或 DVD 设备 |
以下是设置权限属性后的效果:
属性权限 | 文件 | 目录 |
---|---|---|
r | 允许打开并读取文件 | 允许列出目录内容(如果也设置了执行属性) |
w | 允许写入或截断文件;但是不允许重命名或删除文件(文件的删除或重命名是由目录属性决定的) | 允许在目录内创建、删除、重命名文件(如果也设置了执行属性) |
x | 允许将该文件作为程序执行(以脚本语言编写的程序文件必须设置为可读才能被执行 | 允许进入该目录(例如 cd directory) |
文件属性示例:
文件属性 | 含义 |
---|---|
-rwx------ | 可由文件属主读取、写入、执行的普通文件(属组和其他用户没有任何访问权) |
-rw------- | 可由文件属主读取、写入的普通文件(属组和其他用户没有任何访问权) |
-rw-r–r– | 可由文件属主读取、写入的普通文件,属组和其他用户都可以读取该文件 |
-rwxr-xr-x | 可由文件属主读取、写入的普通文件,属组和其他用户都可以读取、执行该文件 |
-rw-rw---- | 可由文件属主和属组读取、写入的普通文件 |
lrwxrwxrwx | 符号链接(权限“虚设”,真正的权限是由符号链接指向的文件决定的 |
drwxrwx— | 目录。属主和属组可以进入该目录并在其中创建、重命名、删除文件 |
drwxr-x— | 目录。属主可以进入该目录并在其中创建、重命名、删除文件。属组可以进入该目录,但不能在其中创建、重命名、删除文件 |
chmod
命令可以修改文件或目录的模式(权限),不过只有文件属主或超级用户才能做到。另外,该命令支持两种截然不同的模式表示方法:八进制表示法和符号表示法。
以二进制形式和八进制形式表示的文件模式:
八进制形式 | 二进制形式 | 文件模式 |
---|---|---|
0 | 000 | - - - |
1 | 001 | - -x |
2 | 010 | -w- |
3 | 011 | -wx |
4 | 100 | r- - |
5 | 101 | r-x |
6 | 110 | rw- |
7 | 111 | rwx |
利用八进制表示法修改文件模式示例:
尽管要记忆八进制和二进制之间的映射关系可能显得不太方便,但其实常用的也就那几个而已:7(rwx)、6(rw-)、5(r-x)、4(r- -)、0(- - -)
chmod
命令也支持文件模式的符号表示法,符号表示法分为三个部分:改动会影响到谁;执行什么操作;设置什么权限。可通过字符 u, g, o, a 的组合来指定要影响的对象:
符号 | 含义 |
---|---|
u | user 的缩写,代表的是文件或目录的属主 |
g | group 的缩写,代表的是属组 |
0 | other 的缩写,代表的是其他用户 |
a | all 的缩写,效果等同于u、g、o 三者的结合 |
以下是一些符号表示法的示例:
表示法 | 含义 |
---|---|
u+x | 为属主添加执行权限 |
u-x | 去除属主的执行权限 |
+x | 为属主、属组、其他用户添加执行权限(等同于 a+x ) |
o-rw | 去除其他用户的读写权限 |
go=rw | 为属组和其他用户设置了读写权限(如果还有执行权限,则去除) |
u+x,go=rx | 为属主添加执行权限,为属组和其他用户设置了读权限和执行权限 |
如果没有指定字符,则使用 all。操作符“+”表示添加权限,“-”表示去除权限,“=”表示只赋予指定权限,同时去除其他所有权限,当设置多组权限时,彼此之间用逗号分隔。
关于这个 umask
命令(设置默认权限),我属实是没看懂,先把操作粘过来好了:
我在网上查找到了这个:“drwxr-xr-x”=“777-022=755”,但是放在上面的命令中也不是啊?
补充:原来,文件的最大默认权限是 666,目录的默认权限最大可以是 777,请移步:Linux umask详解:令新建文件和目录拥有默认权限
虽然通常看到的八进制权限都表示为3位数字,但从技术上而言,它是用4位数字来表示的,原因在于,除读取、写入、执行权限之外,还有其他一些较少用到的权限设置:setuid 位(4000)、setgid 位(2000)和 sticky 位(1000)。
对于 setuid 位,如果,将其应用于可执行文件,会将有效用户 ID 从真实用户(实际执行程序的用户)ID 更改为程序属主的有效用户 ID。大多数情况下,少数超级用户的程序才会做此设置。当普通用户执行 steuid root 程序时,该程序将以超级用户的权限来执行,可以访问普通用户通常被禁止访问的文件和目录。这显然会带来安全隐患,因此允许设置 setuid 位的程序数量必须控制在最小范围内。
对于 setgid 位,类似于setuid 位,它会将有效组 ID 从真实用户的真实组 ID 更改为文件属主的有效组 ID。如果对目录设置 setgid 欸,那么在该目录下新创建的文件将由该目录的属组所有,而非文件创建者的属组所有。这在共享目录中非常有用,当一个共同属组的成员需要访问目录中的所有文件时,不用管文件属主的属组是什么。
关于粘滞(sticky)位,用于将可执行文件标记为“不可交换”。Linux 会忽略文件上设置的粘滞位,但如果是对目录设置了粘滞位,则能够阻止用户删除或重命名其中的文件,除非用户是该目录的属主,或者是文件的属主,又或者是超级用户。粘滞位常用来控制对共享目录设置 setuid 位。
改变用户身份
改变身份的方法有 3 种:
- 注销,然后以其他用户身份重新登录
- 使用
su
命令 - 使用
sudo
命令
在 Shell 会话中,su
允许你“扮演”其他用户,以该用户的 ID 启动新的 Shell 会话或是以该用户的身份执行单个命令。sudo
命令允许超级用户设置名为 /etc/sudoer 的配置文件,定义允许特定用户在假定的身份下执行特定的命令。
su
命令能够以其他用户的身份启动 Shell,其用法为:su [-[l]] [user]
。如果加入了 -l 选项,则启动的 Shell 会话将作为指定用户的登录 Shell,这意味着会加载用户环境并将工作目录更改为该用户的主目录(这通常也是我们想要的结果,如果没有指定用户,则假定其为超级用户。注意:-l 可以缩写为 - ,而且这也是常用的写法),最后可以通过 exit
命令返回之前的 Shell 环境。
来看下面例子:
另外,我们也可以使用 su
命令执行单个命令,而不用启动一个全新的交互式 Shell :su -c 'command'
,采用这种形式,该命令被传入新 Shell 执行,不过一定记得将命令放进引号(因为我们不是想扩展发生在当前 Shell 中,而是要留到新 Shell 中扩展。
关于 sudo
命令,我们只需知道它最常用的方式即可:允许普通用户在可控的方式下以超级用户执行命令(在输入命令后,系统会提示用户输入自己的密码,没错,不是超级用户的密码而是自己的密码,只要通过认证,就能执行指定的命令)。
su 命令和 sudo 命令之间一个重要区别在于,sudo 命令不需要启动新 Shell,也不用加载其他用户的环境(这意味着使用 sudo 命令的时候无需引用命令)
注意,如果出现 “username 不在 sudoers 目录中。此事将被报告”的错误信息时,需要手动进入 root 超级用户中更改 sudoers 配置信息,具体操作请参考至此
chown 命令可用于更改文件属主和属组,该命令需要超级用户权限(需要使用 sudo 命令),用法为:chown [owner][:[group]] file...
chown 命令能够根据第一个参数更改文件属主和文件属组,以下给出了示例:
参数 | 结果 |
---|---|
bob | 将文件所有权由当前属主更改为用户 bob |
bob:users | 将文件所有权由当前属主更改为用户 bob,将文件属组更改为 users 组 |
:admins | 将文件属组更改为 admins 组,文件属主不变 |
bob: | 将文件所有权由当前属主更改为用户 bob,将文件属组更改为用户 bob 的登录组 |
修改密码
我们可以为自己设置密码(如果拥有超级用户权限,也可以为其他用户设置密码),这可以通过 passwd 命令实现,用法为:passwd [user]
十、进程
命令 | 作用 |
---|---|
ps | 查看进程 |
top | 动态查看进程 |
jobs | 查看启动的作业 |
fg | 将作业置于前台 |
bg | 将作业置于后台 |
kill | 向进程发送信号 |
killall | 按名称终止进程 |
shutdown | 关闭或重启系统 |
进程的工作方式
系统启动时,内核会以进程为形式展开一些自身的操作活动并运行一个名为 init 的程序。init 再依次运行一系列初始化脚本(位于 /etc),由这些脚本启动所有的系统服务。一个程序能够启动其他程序(父进程生成子进程),内核维护着每个进程的相关信息,以确保组织有序。例如,每个进程都被分了一个叫做进程 ID(Process ID)的数字,PID 是按照递增顺序分配的,init 的 PID 始终为 1。内核还记录分配给每个进程的内存和用来恢复进程运行的就绪信息。和文件类似,进程有属主、用户 ID、有效用户 ID 等。
查看进程
常用的进程查看命令是 ps 命令,该命令选项众多,最简单的形式如下(不加任何选项):
这个例子的输出结果列出了进程2893和进程3080两个进程,本别对应于 bash 和 ps 。在默认情况下,ps 命令只输出于当前终端会话关联的进程信息。TTY(电传打字机,teletype 的缩写),指的是进程的控制终端;TIME 字段是进程消耗的CPU时间总和(可以看出两个进程都没有加重计算机的负载)。
添加一个选项后,我们就可以更全面地了解系统当前的工作状态:ps x
,x 选项(注意这里没有前置的连字符)会使 ps 命令显示所有的进程,不管这些进程是由哪个终端(如果有的话)控制的。
不加前置连字符的选项使 ps 命令按照“BSD风格“运行,TTY 列出现的?表示没有控制终端,而 STAT 列则描述了进程状态
进程状态:
状态 | 含义 |
---|---|
R | 运行状态。该进程正在运行或准备运行 |
S | 睡眠状态。该进程正在等待某个事件,例如按键或网络分组 |
D | 不可中断的睡眠状态。该进程正在等待I/O,例如磁盘设备的I/O |
T | 已停止。该进程按照指示停止 |
Z | 已“死”的(defunct)或“僵尸”进程。这是已终止但未被其父进程清理的子进程 |
< | 高优先级进程。该进程可以被赋予更高的优先级,分配更多的CPU |
N | 低优先级进程(友善进程) |
另一组常用选项是 aux(没有前置连字符),可以输出更多进程信息,输出结果中将包含所有用户的进程:
BSD风格的ps命令的列信息
列名 | 含义 |
---|---|
USER | 用户ID(该进程的属主) |
%CPU | CPU 占用率 |
%MEM | 内存占用率 |
VSZ | 虚拟内存大小 |
RSS | 驻留集大小(该进程占用的 RAM 数量(以 KB 为单位) |
START | 进程启动时间(如果数值超过24h,则使用日期来显示) |
虽然 ps 命令能够大量揭示出服务器的当前操作,但它提供的只是在运行 ps 命令那一刻的服务器状态信息,要想动态查看服务器的活动,需要使用 top 命令。top 命令会依据进程活动顺序显示持续更新(默认每 3s 更新一次)的系统进程列表。而 top 命令的输出结果分为两部分——上部分显示系统的总体状态信息,下部分显示按 CPU 活动排序的进程列表:
系统总体状态信息包含大量内容,下表提供了 top 命令信息字段:
行 | 字段 | 含义 |
---|---|---|
1 | top | 程序名称 |
1 | 13:40:22 | 当前时刻 |
1 | up 1:52 | 正常运行时间(uptime),这是自上次重启之后的事件总和(在这里,系统已经持续运行了将近两个小时) |
1 | 2 users | 有两个登录用户 |
1 | load average | 平均负载,指的是等待运行运行的进程数量,也就是处于可运行状态且共享 CPU 的进程数量(其显示的3个值分别对应于不同的时间段,分别为过去60s、过去5min、过去15min的平均值。低于1.0的值表明系统并不繁忙) |
2 | Tasks: | 统计了进程数量及其状态 |
3 | %Cpu(s): | 这一行描述了 CPU 正在运行的活动特征 |
3 | 8.3 us | CPU 8.3%的时间被用于用户进程(内核之外的进程) |
3 | 2.4 sy | CPU 2.4%的时间被用于系统(内核)进程 |
3 | 0.2 ni | CPU 0.2%的时间被用于”友善“(低优先级)进程 |
3 | 88.8 id | CPU 88.8%的时间是空闲的 |
3 | 0.0 wa | CPU 0.0%的时间被用于等待I/O |
4 | Mem: | 使用了多少物理内存 |
5 | Swap: | 使用了多少交换空间(虚拟内存) |
top 命令可以接收许多键盘命令,其中常用的有两个:h 和 q。前者会显示程序的帮助界面,后者用来退出 top 命令。
进程控制
我们选用 gedit 程序作为实验对象来进行进程控制的学习(该程序gedit是一个GNOME桌面环境下兼容UTF-8的文本编辑器,用来当作示例程序)
我们可以使用 Ctrl-C 组合键中断程序;当向在运行程序时理解将其置于后台,可以在命令后面加一个&来实现(输出为作业编号和PID,使用 ps
命令可以查看到此进程,使用 jobs
命令则能够查看从 Shell 启动的作业列表),置于后台的作业其实仍然在运行;使进程返回前台可以使用 fg
命令,用法为 fg
命令后面加上百分号和作业号(作业参数,若只有一个后台作业,则该参数可省),之后再使用 Ctrl-C 组合键就可以终止程序即可;想要停止(暂停)进程而不是将其终止也是可以的,使用 Ctrl-Z 组合键即可,这样就可以把前台进程转移到后台并停止运行(此时我们要么使用 fg
命令让程序在前台继续运行,要么使用 bg
命令让程序在后台恢复运行)。
信号
使用kill
命令可以“杀死”进程(kill PID
或 kill %作业号
):
其实,kill
命令并不是杀死进程,而是向其发送信号。信号是系统与程序之间的通信途径之一。在使用 Ctrl-C 组合键和 Ctrl-Z 组合键时,会分别向前台发送 INT 和 TSTP 信号,程序则“监听”(listen)信号并根据接收到的信号做出相应的操作。这种行为使程序能够在接收到终止信号时保存正在进行的工作。
kill
命令可用于向进程发送信号,其语法为:kill -signal PID...
(如果为指定信号,则默认使用 TERM 信号),以下是kill
命令的常用信号:
编号 | 名称 | 含义 |
---|---|---|
1 | HUP | 挂起(hang up)信号 |
2 | INT | 中断(interrupt)信号(效果和在终端按Ctrl-C组合键一样,通常用于终止程序 |
9 | KILL | “杀死”(kill)信号(终止进程,并不会保存) |
15 | TERM | 终止(terminate)信号(这是kill命令发送的默认信号) |
18 | CONT | 继续(continue)信号(该信号可以在 STOP 信号或 STSP 信号之后恢复进程。bg 命令和 fg 命令会发送这个信号) |
19 | STOP | 停止(stop)信号(该信号并不终止进程,而只是将其暂停) |
20 | TSTP | 终端停止(terminal top)信号(效果和在终端按Ctrl-Z组合键一样) |
除了kill
命令常用的信号外还有一些其他系统的常用信号:
编号 | 名称 | 含义 |
---|---|---|
3 | QUIT | 退出(quit)信号 |
11 | SEGV | 段错误(segmentation violation)信号(如果进程违规使用内存,就会收到该信号,例如在无写入权限的内存区域执行写入操作 |
28 | WINCH | 窗口变化(windows change)信号 |
或者可以使用命令kill -l
来显示所有信号以满足好奇心
killall
命令可以向匹配指定名称或用户的多个进程发送信号,用法为killall [-u user] [-signal] name...
,示例如下:
关闭系统
关闭系统涉及有序地终止所有进程,还要在断电之前执行重要的内务整理工作(如同步所有已挂载的文件系统),有4个命令可以执行该功能:
- halt
- poweroff
- reboot
- shutdown
前三个命令通常在使用时不用加任何参数(如sudo reboot
),而通过 shutdown 命令,我们能够指定执行哪种操作(挂起、关机或重启),以提供关机延时,常见的用法是挂起系统(sudo shutdown -h now
)或重启系统(`sudo shutdown -r now)。
更多与进程相关的命令
命令 | 描述 |
---|---|
pstree | 以树状结构输出进程列表,显示进程之间的父子关系 |
vmstat | 输出结果包括内存、交换空间、磁盘I/O在内的系统资源使用情况信息 |
xload | 图形化程序,随时间绘制显示系统负载的图形 |
tload | 和 xload 类似,不过是在终端中绘制图形,按Ctrl-C组合键可以终止输出 |
使用 vmstat 命令时,如果想要查看持续的输出结果,可以在命令后面加一个更新时间间隔(以秒为单位),例如vmsta 5
,按Ctrl-C组合键可以终止输出。
总结
综上,学习 Shell 阶段至此结束,下一部分将开始配置与环境的学习。