Linux 学习笔记(三)- Shell 基础命令


查看目录和文件

pwd

显示当前所在的位置,即工作目录。

1
2
[blog@VM-0-13-centos ~]$ pwd
/home/blog

cd

改变目录。

日常用法:
cd /home/blog 进入 /home/blog 目录;
cd .. 返回上一层目录;
cd / 进入根目录,cd .. / .. 也是进入根目录;
cd 不带参数总是可以回到自己用户的主目录,或者 cd ~ 也是一样的效果。
FYI:在 Shell 中,.. 代表当前目录的上一级目录,而 . 则代表当前目录,另外,~ 代表用户主目录。

ls

列出目录内容。

ls 是 list 的简写。常用选项:
ls 不带参数时,会列出当前目录下的所有文件和子目录。默认情况下,目录显示为蓝色,普通文件显示为黑色,可执行文件显示为草绿色,淡蓝色则表示这个文件是一个链接文件(相当于 Windows 下的快捷方式)。

1
2
3
4
5
6
7
[blog@VM-0-13-centos ~]$ cd /etc/
[blog@VM-0-13-centos etc]$ ls
acpi e2fsck.conf libreport pm shells.rpmnew
adjtime environment libuser.conf polkit-1 skel
aliases ethertypes locale.conf popt.d sos.conf
alternatives exports localtime postfix ssh
...

ls -F 用户也可以使用带 -F 选项的 ls 命令。可以看到,-F 选项会在每个目录后加上 /,在可执行文件后加 *,在链接文件后加上 @。这个选项在某些无法显示颜色的终端上会比较有用:

1
2
3
4
5
6
7
[blog@VM-0-13-centos ~]$ cd /etc/
[blog@VM-0-13-centos etc]$ ls -F
acpi/ e2fsck.conf libreport/ pm/ shells.rpmnew
adjtime environment libuser.conf polkit-1/ skel/
aliases ethertypes locale.conf popt.d/ sos.conf
alternatives/ exports localtime@ postfix/ ssh/
...

ls -a 查看所有文件,包括隐藏文件。
ls -aF 命令的选项也可以组合使用,只需要一个 - 符号:

1
2
3
4
5
[blog@VM-0-13-centos etc]$ ls -aF
./ dracut.conf.d/ libreport/ polkit-1/ skel/
../ e2fsck.conf libuser.conf popt.d/ sos.conf
acpi/ environment locale.conf postfix/ ssh/
adjtime ethertypes localtime@ ppp/ ssl/

ls -l 查看文件的属性,从左至右依次是:文件的权限标志;文件的链接个数;文件所有者的用户名;该用户所在的用户组;文件的大小;最后一次被修改的日期;文件名。

1
2
3
4
5
[blog@VM-0-13-centos etc]$ ls -l
总用量 1536
drwxr-xr-x. 4 root root 4096 411 2018 acpi
-rw-r--r--. 1 root root 16 421 2016 adjtime
...

ls [路径] 路径作为参数,就是查看该子目录的内容:

1
2
[blog@VM-0-13-centos ~]$ ls /etc/yum
fssnap.d pluginconf.d protected.d vars version-groups.conf

dir/vdir

dir 类似 lsvdir 类似 ls -l

cat

用于查看文件内容,后面跟文件名作为参数。

1
2
$ cat helloworld
$ cat -n helloworld # 带行号的 -n

cat 会将文件的所有内容显示在屏幕上,那对于大文件来说,cat 显得毫无用处。

more

考虑到 cat 命令的缺点,Linux 提供了 more 命令一页一页的显示文件内容…

  可以看到,more 命令会在最后显示一个百分比,表示已显示内容占整个文件的比例,按下空格键向下翻动一页,按 Enter 键向下滚动一行,按 Q 键退出,或者滚到最后一行时自动就退出了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ more 404.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>The page is not found</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
/*<![CDATA[*/
body {
background-color: #fff;
color: #000;
font-size: 0.9em;
font-family: sans-serif,helvetica;
margin: 0;
padding: 0;
}
:link {
color: #c00;
}
:visited {
color: #c00;
}
a:hover {
color: #f50;
}
--More--(41%)

显示文件的开头。

tail

显示文件的结尾。

head 和 tail 可以使用 -n 参数指定显示的行数。默认不指定行数的话,我也不太清楚它显示的行数是根据什么判断的😂

1
2
3
4
5
6
$ head -n 5 404.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>The page is not found</title>
1
2
3
4
5
6
$ tail -n 5 404.html
width="88" height="31" /></a>
</div>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
$ head -n 2 index.html search.xml
==> index.html <==
<!DOCTYPE html>
<html lang=zh>

==> search.xml <==
<?xml version="1.0" encoding="utf-8"?>
<search>

两个命令如果查看多个文件的话,默认会把文件名输出,放在 ==> 和 <== 之间。

less

  less 和 more 非常相似,但其功能更为强大。less 改进了 more 命令的很多细节,并添加了许多的特性。这些特性让 less 看起来更像是一个文本编辑器,只是去掉了文本编辑功能。总体来说,less 命令提供了下面这些增强功能:

  • 使用光标键在文本文件中前后(甚至左右)滚屏;
  • 用行号或百分比作为书签浏览文件;
  • 实现复杂的检索、高亮显示等操作;
  • 兼容常用的字处理程序(如Emacs、Vim)的键盘操作;
  • 阅读到文件结束时 less 命令不会退出,按 Q 键退出;
  • 屏幕底部的信息提示更容易控制使用,而且提供了更多的信息。

下面简单地介绍 less 命令的使用方法。以博客的 index.html 文件为例,执行 less index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang=zh>
<head>
<!-- so meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="True">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5" />
<meta name="description" content="能改变自己的都是神,想改变别人的都是神经病。<U+1F34A>">
<meta property="og:type" content="website">
<meta property="og:title" content="迷">

#此处省略一部分
...
<!-- mathjax -->

:

  可以看到,less 在屏幕底部显示一个冒号“:”等待用户输入命令。如果想向下翻一页,可以按下空格键,如果想向上翻一页,按下 B 键,也可以用光标键向前、后、甚至左右移动。如果要在文件中搜索某一个字符串, 可以使用正斜杠“/”跟上想要查找的内容,less 会把找到的第一个搜索目标高亮显示,要继续查找相同的内容,只要再次输入正斜杠“/”,并按下回车键就可以了。
  使用带 -M 参数可以显示更多文件信息,less -M index.html :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang=zh>
<head>
<!-- so meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="True">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5" />
<meta name="description" content="能改变自己的都是神,想改变别人的都是神经病。<U+1F34A>">
<meta property="og:type" content="website">
#此处省略一部分
...

<!-- mathjax -->

index.html lines 1-48/338 19%

可以看到 less 在底部显示了“文件名字 当前行数范围/总行数 当前位置占总文件的百分比”。

grep

在很多时候,并不需要列出文件的全部内容,我们想做的可能只是找到包含某些关键信息的某几行。这个时候使用 more 命令肯定就很麻烦了,可以用 grep …

命令格式:grep [OPTION] PATTERN [FILE...] 。还是以博客主页为例,我们搜索“能改变自己的都是神,想改变别人的都是神经病。🍊” :

1
2
3
4
$ grep 能改变自己的都是神,想改变别人的都是神经病。 index.html
<meta name="description" content="能改变自己的都是神,想改变别人的都是神经病。🍊">
<meta property="og:description" content="能改变自己的都是神,想改变别人的都是神经病。🍊">
<p>能改变自己的都是神,想改变别人的都是神经病。🍊</p>

  把包含这行文字的标签都列出来了,并且在控制台是高亮显示的。
  命令和参数是以空格来分割的,那如果我们想查找的关键字是 Red Hat 这种包含空格呢?这个时候必须用单引号把空格包含进去:

1
2
$ grep 'html lang=zh' index.html
<html lang=zh>

和其他几个查看文件的命令一样,grep 也支持多个文件,并且在结果中列出文件名:

1
2
3
4
5
6
$ grep 迷 index.html search.xml
index.html:<meta property="og:title" content="迷">
index.html:<meta property="og:site_name" content="迷">
index.html: <title>迷</title>
index.html: <h1>迷</h1>
search.xml:<li>法号:迷</li>

  严格地说,grep 通过“基础正则表达式(basic regular expression)”进行搜索,和 grep 相关的一个工具是 egrep,除了使用“扩展的正则表达式(extended regular expression)”,egrep 和 grep 完全一样, “ 扩展正则表达式”能够提供比“基础正则表达式”更完整地表达规范。正则表达式我还没太学会…🤓

find

迅速在指定范围内查找到文件。

find 命令的基本语法:find [OPTION] [path...] [expression]
例如在 usr/bin/ 目录中查找 zip 命令:

1
2
$ find /usr/bin/ -name zip -print
/usr/bin/zip

也可以使用通配符 * 指定文件名,例如查找类型为 go 的文件:

1
2
3
4
5
6
$ find / -name *.go -print
/usr/share/doc/git-1.8.3.1/contrib/persistent-https/client.go
/usr/share/doc/git-1.8.3.1/contrib/persistent-https/main.go
find: ‘/usr/share/polkit-1/rules.d’: 权限不够
find: ‘/home/tommy’: 权限不够
...

  对于提示“权限不够(Permission denied)”的目录,说明当前登录的用户没有权限进入这两个目录,find 在扫描时会跳过这两个目录。
  find命令还能够指定文件的类型。在Linux中,包括目录和设备都以文件的形式表现,可以使用 -type 选项来定位特殊文件类型。例如,在 /etc/ 目录中查找名叫 init.d 的目录:

1
2
3
4
$ find /etc/ -name init.d -type d -print
find: /etc/ssl/private: Permission denied
find: /etc/cups/ssl: Permission denied
/etc/ init.d

-type 选项可以使用的参数:

参数 含义 参数 含义
b 块设备文件 f 普通文件
c 字符设备文件 p 命名管道
d 目录文件 l 符号链接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ find --help
用法: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

默认路径为当前目录;默认表达式为 -print
表达式可能由下列成份组成:操作符、选项、测试表达式以及动作:

操作符 (优先级递减;未做任何指定时默认使用 -and):
( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2
EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2

positional options (always true): -daystart -follow -regextype

normal options (always true, specified before other expressions):
-depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
--version -xautofs -xdev -ignore_readdir_race -noignore_readdir_race

比较测试 (N 可以是 +N 或 -N 或 N): -amin N -anewer FILE -atime N -cmin N
-cnewer 文件 -ctime N -empty -false -fstype 类型 -gid N -group 名称
-ilname 匹配模式 -iname 匹配模式 -inum N -ipath 匹配模式 -iregex 匹配模式
-links N -lname 匹配模式 -mmin N -mtime N -name 匹配模式 -newer 文件
-nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN
-readable -writable -executable
-wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N
-used N -user NAME -xtype [bcdpfls]
-context 文本


操作: -delete -print0 -printf 格式 -fprintf 文件 格式 -print
-fprint0 文件 -fprint 文件 -ls -fls 文件 -prune -quit
-exec 命令 ; -exec 命令 {} + -ok 命令 ;
-execdir 命令 ; -execdir 命令 {} + -okdir 命令 ;

locate

如果我们不记得文件具体在哪个位置,又非常需要找到它,find 就略显尴尬了,locate 会是个不错的选择。

1
2
3
$ locate 404.html
/404.html
/usr/share/nginx/html/404.html

  “这些搜索结果几乎是一瞬间就出现了。这不禁让人疑惑,locate 究竟是如何做到这一点的?事实上,locate 并没有进入子目录搜索,它有一点类似于 Google 的桌面搜索,通过检索文件名数据库来确定文件的位置。locate 命令自动建立整个文件名数据库,不需要用户插手。如果希望立刻生成该数据库文件的最新版本,那么可以使用 updatedb 命令,运行这个命令需要有 root 权限,更新整个数据库大概耗时1分钟。” 以上这段是书上的描述,在我的虚拟机上没有用时1分钟,很快。然后在 Mac OS (衍生自 Unix) 首次使用 locate 命令时,提示我们需要手动建立文件名数据库:

1
2
3
4
5
6
7
8
9
$ locate 'Linux 从入门到精通'

WARNING: The locate database (/var/db/locate.database) does not exist.
To create the database, run the following command:

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist

Please be aware that the database can take some time to generate; once
the database has been created, this message will no longer appear.

查找命令和系统信息

whereis

whereis 命令主要用于查找程序文件,并提供这个文件的二进制可执行文件、源代码文件和使用手册页存放的位置。

例如,查找刚刚用到的 locate 命令:

1
2
$ whereis locate
locate: /usr/bin/locate /usr/share/man/man1/locate.1.gz

如果只想查找可执行文件,可以使用 -b 选项:

1
2
$ whereis -b find
find: /usr/bin/find

这样有点儿类似于 which 命令:

1
2
$ which locate
/usr/bin/locate

who

查看当前系统中有哪些人登录,以及工作在哪个控制台上。

1
2
3
$ who
tommy pts/0 2022-03-11 15:07 (0.0.0.0)
tommy pts/1 2022-03-11 16:17 (0.0.0.0)

whoami

我是谁?有些时候,可能会忘记自己是以什么身份登录到系统,特别当需要以特定身份启动某个服务器程序时。

uname

用于显示当前系统的版本信息。带 -a 选项的 uname 命令会给出当前操作系统的所有有用信息。

1
2
$ uname -a
Linux VM-0-13-centos 3.10.0-1160.31.1.el7.x86_64 #1 SMP Thu Jun 10 13:32:12 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

在大部分时候,需要的只是其中的内核版本信息。此时可以使用 -r 选项。

1
2
$ uname -r
3.10.0-1160.31.1.el7.x86_64

man

在 Linux 中获取帮助是一件非常容易的事情。Linux 为几乎每一个命令和系统调用编写了帮助手册。使用man命令可以方便地获取某个命令的帮助信息。

以前查看命令的帮助,一般使用 --help 选项,但是 man 命令获取到的帮助信息明显“好看”多了。那我们看看 man man 是什么吧,哈哈哈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
MAN(1)                                        Manual pager utils                                       MAN(1)

NAME
man - an interface to the on-line reference manuals

SYNOPSIS
man [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L locale] [-m system[,...]] [-M path]
[-S list] [-e extension] [-i|-I] [--regex|--wildcard] [--names-only] [-a] [-u] [--no-subpages] [-P
pager] [-r prompt] [-7] [-E encoding] [--no-hyphenation] [--no-justification] [-p string] [-t]
[-T[device]] [-H[browser]] [-X[dpi]] [-Z] [[section] page ...] ...
man -k [apropos options] regexp ...
man -K [-w|-W] [-S list] [-i|-I] [--regex] [section] term ...
man -f [whatis options] page ...
man -l [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L locale] [-P pager] [-r prompt]
[-7] [-E encoding] [-p string] [-t] [-T[device]] [-H[browser]] [-X[dpi]] [-Z] file ...
man -w|-W [-C file] [-d] [-D] page ...
man -c [-C file] [-d] [-D] page ...
man [-?V]

DESCRIPTION
...
Manual page man(1) line 1 (press h for help or q to quit)

看到最后一行,是不是觉得眼熟,less … so…man 命令在显示手册页时实际调用的是 less 程序。

whatis

man 手册中的长篇大论有时候显得太哕嗦了一很多情况下,人们只是想要知道一个命令大概可以做些什么。于是,whatis 满足了大家的好奇心。whatis 从某个程序的使用手册页中抽出一行简单的介绍性文字,帮助用户了解这个程序的大致用途。whatis 的原理同 locate 命令基本一致。

1
2
$ whatis uname
uname (1) - print system information

我发现 Linux 的命令有意思的一点是“我否定我自己,我完善我自己” 。😂

apropos

和 whatis 相反,通过搜索使用手册中的关键字,帮我们反查到想要的命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ apropos search
apropos (1) - search the manual page names and descriptions
ausearch (8) - a tool to query audit daemon logs
ausearch-expression (5) - audit search expression format
badblocks (8) - search a device for bad blocks
bzgrep (1) - search possibly bzip2 compressed files for a regular expression
find (1) - search for files in a directory hierarchy
git-bisect (1) - Find by binary search the change that introduced a bug
manpath (1) - determine search path for manual pages
npm-help-search (1) - Search npm help documentation
npm-search (1) - Search for packages
oldfind (1) - search for files in a directory hierarchy
Pod::Simple::Search (3pm) - find POD documents in directory trees
Search::Dict (3pm) - look - search for key in dictionary file
vgscan (8) - Search for all volume groups
xzegrep (1) - search compressed files for a regular expression
xzfgrep (1) - search compressed files for a regular expression
xzgrep (1) - search compressed files for a regular expression
zgrep (1) - search possibly compressed files for a regular expression
zipgrep (1) - search files in a ZIP archive for lines matching a pattern

基础的 Shell 命令暂时学到这里。