Linux学习
Linux shell 指令相关学习
Linux 操作系统
大佬的笔记:https://gnu-linux.readthedocs.io/zh/latest/preface.html
为什么学习Linux
相比于Windows,Linux的优势?开源、高度可定制化、高性能
不要脱离操作系统的本质:资源分配、调度 –> 核心:帮助人们计算
因此,有一个问题,如何让Linux帮助我们计算 –> (基本指令)
如果想一次运行一堆指令,如何做到?(shell编程)
如何定制自己的Linux?(读源码,修改源码,编译)
基本指令
寻求帮助命令:man – manual
普通用法 man command:获取command 的使用手册
文件和文件夹
创建文件、文件夹
rm – remove指令
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
RM(1) 用户命令 RM(1) NAME rm - 删除文件或目录 格式 rm [选项]... [文件]... 描述 本手册页记录了 rm 的 GNU 版本。 rm 删除每个指定的文件。 默认情况下,它不会删除 目录。 如果给出了 -I 或 --interactive=once 选项,并且有超过三个文件或 -r、-R 或 --recursive 给出后,rm 提示用户是否继续整个操作。 如果响应不是 af- 确认后,整个命令将中止。 否则,如果文件不可写,则标准输入是终端,并且未给出 -f 或 --force 选项,或者 给出 -i 或 --interactive=always 选项,rm 提示用户是否删除文件。 如果有- 响应不是肯定的,文件被跳过。 选项 删除(unlink)文件(s)。 -f,--force 忽略不存在的文件和参数,从不提示 -i 每次删除前都会提示 -I 删除超过三个文件之前,或者递归删除时提示一次; 比 -i 更少侵入性, 同时仍能防止大多数错误 --interactive[=WHEN] 根据 WHEN 提示:从不、一次 (-I) 或总是 (-i); 没有 WHEN,总是提示 --one-file-system 递归删除层次结构时,跳过文件系统上与该层次结构不同的任何目录 相应的命令行参数 --no-preserve-root 不要特殊对待 '/' --preserve-root[=all] 不要删除“/”(默认); 使用 'all',拒绝与其父设备不同的设备上的任何命令行参数 -r, -R, --recursive 递归删除目录及其内容 -d,--dir 删除空目录 -v, --verbose 解释将要做什么 --help 显示此帮助并退出 --version 输出版本信息并退出 默认情况下,rm 不删除目录。 使用--recursive(-r或-R)选项删除每个列出目录,以及它的所有内容。 要删除名称以“-”开头的文件(例如“-foo”),请使用以下命令之一: rm -- -foo rm ./-foo 请注意,如果您使用 rm 删除文件,只要有足够的专业知识和/或时间,就有可能恢复其部分内容 为了更好地确保内容确实无法恢复,请考虑使用shred。 作者 由保罗·鲁宾、大卫·麦肯齐、理查德·M·斯托曼和吉姆·迈耶林撰写。 报告错误 GNU coreutils 在线帮助:<https://www.gnu.org/software/coreutils/> 向 <https://translationproject.org/team/> 报告任何翻译错误 版权 版权所有 © 2020 Free Software Foundation, Inc. 许可证 GPLv3+:GNU GPL 版本 3 或更高版本 <https://gnu.org/licens/gpl.html>。 这是免费软件:您可以自由更改和重新分发它。 在允许的范围内,不提供任何保证 根据法律。 也可以看看 unlink(1)、unlink(2)、chattr(1)、shred(1) 完整文档 <https://www.gnu.org/software/coreutils/rm> 或通过以下方式在本地获取:info '(coreutils) rm incalling' GNU coreutils 8.32 二月 2022 RM(1)
mv – move 移动文件、文件夹
cp – copy 复制文件、文件夹
tar、gzip压缩文件、文件夹
文件内容
cat – concatenate 拼接一个或多个文件并 –> 打印
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
CAT(1) 用户命令 CAT(1) NAME cat - 连接文件并在标准输出上打印 格式 cat [选项]... [文件]... 描述 将文件连接到标准输出。 没有 FILE 或 FILE 为 - 时,读取标准输入。 -A, --显示全部 相当于-vET -b, --number-nonblank 非空输出行数,覆盖 -n -e 相当于 -vE -E, --show-ends 在每行末尾显示 $ -n,--number 对所有输出行进行编号 -s, --squeeze-blank 抑制重复的空输出行 -t 相当于 -vT -T, --显示选项卡 将制表符显示为 ^I -u(忽略) -v, --show-nonprinting 使用 ^ 和 M- 表示法,LFD 和 TAB 除外 --help 显示此帮助并退出 - 版本 输出版本信息并退出 例子 cat f - g 输出f的内容,然后是标准输入,然后是g的内容。 cat 将标准输入复制到标准输出。 作者 由托比昂·格兰伦德和理查德·M·斯托曼撰写。 报告错误 GNU coreutils 在线帮助:<https://www.gnu.org/software/coreutils/> 向 <https://translationproject.org/team/> 报告任何翻译错误 版权 版权所有 © 2020 Free Software Foundation, Inc. 许可证 GPLv3+:GNU GPL 版本 3 或更高版本 <https://gnu.org/li‐ cens/gpl.html>。 这是免费软件:您可以自由更改和重新分发它。根据法律,在允许的范围内,不提供任何保证。 也可以看看 tac(1) 完整文档 <https://www.gnu.org/software/coreutils/cat> 或通过以下方式在本地获取:info '(coreutils) cat inspiration' GNU coreutils 8.32 二月 2022 CAT(1)
搜索文件内容
用户管理
- 添加用户 – useradd
- 修改用户密码 – passwd
- 删除用户 – userdel
- 记录用户操作 – history
- 查看用户信息 – id
- 管理用户账号 – usermod
- 创建用户分组 – groupadd
- 用户之间切换 – su
- 受限特权命令 – sudo
系统、进程相关
- mount 挂载一个文件系统
- df 查看文件系统使用情况
- free 查看内存和交换区使用情况
- 监视进程 – ps
- 即时跟踪进程 – top
- 向进程发送信号 – kill
- 优先级 nice 和 renice
- 查看进程属性 – pgrep
make指令(重要)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
MAKE(1) 用户命令 MAKE(1)
name
make - 用于维护程序组的 GNU make 实用程序
格式
make [选项]...[目标]...
描述
make工具将自动确定大型程序的哪些部分需要重新编译,并发出重新编译它们的命令。 该手册描述了 make 的 GNU 实现,由 Richard Stallman 和
Roland McGrath,目前由 Paul Smith 维护。 我们的示例显示了 C 程序,因为它们非常常见,但是您可以将 make 与任何可以使用 shell 命令运行编译 器的编程语言一起使用。事实上,make不仅仅限于程序。 您可以使用它来描述任何任务,只要其他文件发生更改,某些文件就必须自动从其他文件更新。
要准备使用 make,您必须编写一个名为 makefile 的文件,该文件描述程序中文件之间的关系,并说明更新每个文件的命令。在程序中,通常可执行文件是从目 标文件更新的,而目标文件又是通过编译源文件而生成的。
一旦存在合适的 makefile,每次更改一些源文件时,这个简单的 shell 命令:
make
就足以执行所有必要的重新编译。make 程序使用 makefile 描述和文件的最后修改时间来决定哪些文件需要更新。对于每个文件,它都会发出 makefile 中记 录的命令。
make 执行 makefile 中的命令来更新一个或多个目标名称,其中名称通常是一个程序。如果没有 -f 选项,make 将按顺序查找 makefile GNUmakefile、 makefile 和 Makefile。
通常你应该将你的 makefile 命名为 makefile 或 Makefile。 (我们推荐 Makefile,因为它显着地出现在目录列表的开头附近,紧邻其他重要文件,例如 README。)对于大多数 makefile,不建议使用第一个名称-GNUmakefile。如果您有一个特定于 GNU make 的 makefile,并且其他版本的 make 无法理 解,则应该使用此名称。 如果 makefile 为“-”,则读取标准输入。
如果目标依赖于自上次修改目标以来已修改的先决条件文件,或者目标不存在,则 make 更新目标。
选项
-b、-m
为了与其他版本的 make 兼容,这些选项将被忽略。
-B, --always-make
无条件达成所有目标。
-C dir,--directory=dir
在读取 makefile 或执行任何其他操作之前,更改到目录 dir。 如果指定了多个 -C 选项,则每个选项都相对于前一个选项进行解释: -C / -C etc 相当于 -C /etc。 这通常与 make 的递归调用一起使用。
-d 除了正常处理之外还打印调试信息。 调试信息表明哪些文件正在考虑重新制作,正在比较哪些文件时间以及结果如何,哪些文件实际上需要重新制作,哪些隐式 规则被考虑以及哪些被应用——关于 make 如何决定做什么的所有有趣的事情。
--debug[=FLAGS]
除了正常处理之外还打印调试信息。 如果省略 FLAGS,则行为与指定 -d 时的行为相同。 FLAGS 可以是 a 表示所有调试输出(与使用 -d 相同),b 表示基本调试,v 表示更详细的基本调试,i 用于显示隐式规则,j 用于命令调用的详细信息,m 用于在重新制作 makefile 时进行调试。 使用 n 禁用 所有以前的调试标志。
-e, --环境覆盖
从环境中获取的变量优先于从 makefile 中获取的变量。
-f file,--file=file,--makefile=file
使用文件作为 makefile。
-i, --ignore-errors
忽略执行重制文件的命令中的所有错误。
-I dir,--include-dir=dir
指定一个目录 dir 来搜索包含的 makefile。 如果使用多个 -I 选项指定多个目录,则按指定的顺序搜索目录。 与 make 的其他标志的参数不同,使用 -I 标志给出的目录可以直接出现在该标志之后:允许使用 -Idir 以及 -I dir。 允许使用此语法是为了与 C 预处理器的 -I 标志兼容。
-j [jobs], --jobs[=jobs]
指定同时运行的作业(命令)数量。 如果有多个 -j 选项,则最后一个有效。 如果给出的 -j 选项没有参数,make 不会限制可以运行的作业数量
同时。 当 make 调用子 make 时,make 的所有实例将协调一次运行指定数量的作业; 有关详细信息,请参阅并行 MAKE 和 JOBSERVER 部分。
--jobserver-fds [R,W]
make 使用内部选项将 jobserver 管道读取和写入文件描述符编号传递给子 make; 有关详细信息,请参阅并行 MAKE 和 JOBSERVER 部分
-k, --keep-going
发生错误后尽可能继续。虽然失败的目标以及依赖它的目标无法重新创建,但这些目标的其他依赖项仍然可以处理。
-l [load], --load-average[=load]
指定如果有其他作业正在运行且平均负载至少为 load(浮点数),则不应启动新作业(命令)。 不带参数,删除先前的负载限制。
-L, --check-symlink-times
使用符号链接和目标之间的最新 mtime。
-n, --just-print, --dry-run, --recon
打印将要执行的命令,但不执行它们(某些情况除外)。
-o file,--old-file=file,--assume-old=file
即使文件比其依赖项旧,也不要重新创建文件,并且不要因文件更改而重新创建任何内容。 本质上,该文件被视为非常旧的文件,并且其规则被忽略。
-O[type], --output-sync[=type]
当使用 -j 并行运行多个作业时,请确保将每个作业的输出收集在一起,而不是与其他作业的输出散布在一起。 如果未指定类型或类型为目标,则每个目标 的整个配方的输出将分组在一起。 如果 type 为 line,则配方中每个命令行的输出将分组在一起。 如果类型是递归,则整个递归 make 的输出将分组在 一起。 如果类型为 none,则禁用输出同步。
-p, --打印数据库
打印读取 makefile 所产生的数据库(规则和变量值); 然后照常执行或按照其他指定执行。 这还会打印 -v 开关给出的版本信息(见下文)。 打印 数据库而不尝试重新创建任何文件,请使用 make -p -f/dev/null。
-q, --question
“提问模式”。 不要运行任何命令,或打印任何内容; 如果指定的目标已经是最新的,则仅返回退出状态为零,否则返回非零。
-r, --no-builtin-rules
消除使用内置隐式规则。 还要清除后缀规则的默认后缀列表。
-R,--no-builtin-variables
不要定义任何内置变量。
-s,--silent, --quiet
沉默运行; 执行命令时不要打印命令。
-S,--no-keep-going, --stop
取消-k选项的效果。 这从来没有必要,除非在递归 make 中,其中 -k 可能通过 MAKEFLAGS 从顶级 make 继承,或者如果您在环境中的 MAKEFLAGS 中设置 -k 。
-t,--touch
触摸文件(将它们标记为最新而不真正更改它们)而不是运行它们的命令。 这用于假装命令已完成,以欺骗将来的 make 调用。
--trace
打印有关每个目标的配置的信息(为什么要重建目标以及运行哪些命令来重建它)。
-v,--version
打印 make 程序的版本以及版权、作者列表和不提供任何保证的通知。
-w, --print-directory
在其他处理之前和之后打印包含工作目录的消息。 这对于跟踪复杂的递归 make 命令嵌套中的错误可能很有用。
--no-print-directory
关闭 -w,即使它是隐式打开的。
-W file, --what-if=file, --new-file=file, --assume-new=file
假设目标文件刚刚被修改。 当与 -n 标志一起使用时,这会显示如果您要修改该文件会发生什么。 如果没有 -n,它与运行 make 之前在给定文件上运行 touch 命令几乎相同,只不过修改时间仅在 make 的想象中改变。
--warn-undefined-variables
当引用未定义的变量时发出警告。
EXIT STATUS
如果所有 makefile 均已成功解析并且没有构建失败的目标,GNU make 将以零状态退出。 如果使用 -q 标志并且 make 确定需要重建目标,则将返回状态 1。如果遇到任何错误,将返回状态 2。
也可以看看
make 的完整文档作为 Texinfo 手册进行维护。 如果e info 和 make 程序已正确安装在您的站点上,使用command:
info make
应该可以让您访问完整的手册。 此外,该手册也可以在线获取:https://www.gnu.org/software/make/manual/html_node/index.html
PARALLEL MAKE AND THE JOBSERVER
使用 -j 选项,用户可以指示 make 并行执行任务。 通过指定 -j 的数字参数,用户可以指定要运行的并行任务数量的上限。
当构建环境是顶级 make 调用子 make(例如,每个子目录都包含自己的 Makefile 的样式)时,没有单独的 make 实例知道有多少任务正在并行运行,因此保 持 如果所有正在运行的 make 实例之间没有通信,则任务数量不可能低于上限。 虽然像让顶层 make 作为中央控制器这样的解决方案是可行的,或者可以创建使 用其他同步机制(如共享内存或套接字),但当前的实现使用简单的共享管道。
该管道由顶级 make 进程创建,并传递给所有子 make。 顶层 makeprocess 将 N-1 个一字节令牌写入管道(假设顶层 make 为自己保留一个令牌)。 每当 任何 make 进程(包括顶级 make )需要运行新任务时,它都会从共享管道中读取一个字节。 如果没有剩余令牌,则必须等待令牌被写回管道。 一旦任务完成, make 进程就会将一个令牌写回管道(因此,如果令牌已耗尽,则解除对第一个等待读取令牌的 make 进程的阻塞)。 由于只有 N-1 个令牌被写入管道,因此在 任何给定时间都不能运行超过 N 个任务。
如果要运行的作业不是子make,那么make会在调用命令之前关闭jobserver管道文件描述符,这样命令就不会干扰jobserver,并且命令不会发现任何异常的文件 描述符。
BUGS
请参阅《GNU Make 手册》中的“问题和错误”一章。
作者
本手册页由斯坦福大学的 Dennis Morse 贡献。 进一步的更新由 Mike Frysinger 贡献。 罗兰·麦格拉思对其进行了重新设计。 由保罗·史密斯维护。
版权
版权所有 © 1992-1993、1996-2016 Free Software Foundation, Inc。此文件是 GNU make 的一部分。
GNU Make 是自由软件; 您可以根据自由软件基金会发布的 GNU 通用公共许可证的条款重新分发和/或修改它; 许可证的版本 3,或(由您选择)任何更高版 本。
GNU Make 的发布是希望它有用,但不提供任何保证; 甚至没有适销性或特定用途适用性的默示保证。 有关更多详细信息,请参阅 GNU 通用公共许可证。
您应该随该程序一起收到 GNU 通用公共许可证的副本。 如果没有,请参阅 http://www.gnu.org/licenses/。
GNU 2016 年 2 月 28 日 MAKE(1)
Makefile
转载:make工具 —— make命令和makefile文件_梦幻龙族makeinb工具-CSDN博客
1. 简介
makefile文件由一组依赖关系和规则构成。 每个依赖关系由一个目标(即将要创建的文件)和一组该目标所依赖的源文件组成。 make 命令会去读取makefile文件的内容,它先确定目标文件或要创建的文件,然后比较该目标所依赖的源文件的日期和时间以决定该采用哪条规则来构造目标。 通常在创建最终的目标文件之前,它需要先创建一些中间目标。make命令会根据makefile文件来确定目标文件的创建顺序以及正确的规则调用顺序。
2. 依赖关系
在makefile文件中,规范的写法是:先写目标的名称,然后紧跟着一个冒号,接着是空格或制表符tab,最后是用空格或制表符tab隔开的文件列表(这些文件用于创建目标文件)。 例子:
1
2
hello: hello.cpp
hello.cpp: head.cpp main.cpp
它表示目标hello依赖于hello.cpp,而hello.cpp依赖于head.cpp 和 main.cpp。这组依赖关系形成一个层次结构,它显示了源文件之间的关系。可以很容易看出,如果文件head.h或main.cpp发生改变,你就需重新产生hello.cpp,而由于hello.cpp发生了改变,你还需要重新创建目标hello。
如果想一次创建多个文件,可以利用伪目标all。假设应用程序由二进制文件hello1和hello2组成,可以用下面这行语句进行定义:
1
all: hello1 hello2
注意:如果未指定一个all目标,则make命令将只创建它在文件makefile中找到的第一个目标。
3. 规则
makefile文件的第二部分内容是规则,它们定义了目标的创建方式。
注 意:makefile文件中有一个非常奇怪而又令人遗憾的语法现象 —— 空格和制表符tab是有区别的。规则所在的行必须以制表符tab开头,用空格是不行的。此外,如果makefile文件中的某行以空格结尾,它也可能会导 致make命令执行失败。但这些都是历史遗留问题,而且因为已有太多的makefile文件存在,企图将其全部改正是不现实的,所以请小心编写 makefile文件。
一个简单的makefile文件
1
2
3
4
hello: hello.cpp
g++ hello.cpp -o hello
hello.cpp: head.cpp main.cpp
cat head.cpp main.cpp > hello.cpp
make 命令处理makefile文件中定义的依赖关系,确定需要创建的文件以及创建顺序。虽然把如何创建目标hello列在最前面,但make命令能够自行判断 出创建文件的正确顺序。它调用你在规则部分给出的命令来创建相应的文件,同时会在执行时在屏幕上将命令显示出来。
注意:改变需要编译的某一文件,重新make编译,make命令读取makefile文件,确定重建hello所需的最少命令,并以正确的顺序执行它们。(因为可以根据文件的修改时间来决定是否是最新文件,并决定是否要重新编译)
4. makefile中的注释
makefile文件中的注释以#号开头,一直延续到这一行的结束。
5. makefile中的宏
makefile文件允许你使用宏,以一种更通用的格式来书写它们。 在makefile文件中定义宏: MACRONAME=value 引用宏的方法: $(MACRONAME) 或 ${MACRONAME} (make的有些版本还允许 $MACRONAME) 把一个宏的值设置为空的方法: MACRONAME= (即,将等号后面留空)
注意: (1) makefile文件中的宏常被用于设置编译器的选项。 (2) makefile文件的另一个问题:它假设编译器的名字是 gcc,而在其他UNIX系统中,编译器的名字可能是cc或c89。如果想将makefile文件移植到另一版本的UNIX系统中,或在现有系统中使用另 一个编译器,为了使其工作,你将不得不修改makefile文件中许多行的内容。—— 宏是用来收集所有这些与系统相关内容的好方法,通过使用宏定义,你可以方便地修改这些内容。 (3) 宏通常都是在makefile文件中定义的,但你也可以在调用make命令时在命令行上给出宏定义。例如,命令 make CC=c89 (4) 命令行上的宏将覆盖在makefile文件中的宏定义。 (5) 当在makefile文件之外使用宏定义时,要注意宏定义必须以单个参数的形式传递,所以应避免在宏定义中使用空格或应给宏定义加上引号,例如,make “CC = c89” 。 (6) make命令将$(CC)、$(CFLAGS) 和 $(INCLUDE) 替换为相应的宏定义,这与 C 语言编译器对#define语句的处理方式很相似。现在,如果想改变编译器命令,只需要修改makefile文件中的一行即可。
事实上,make命令内置了一些特殊的宏定义,通过使用它们,可以让makefile文件变得更加简洁。这些宏在使用前才展开,所以它们的含义会随着makefile文件的处理进展而发生变化 —— 这才是特殊宏用法的关键。 几个较常用的宏:
| 符号 | 描述 |
|---|---|
| $? | 当前目标所依赖的文件列表中比当前目标文件还要新的文件 |
| $@ | 当前目标的文字 |
| $< | 当前依赖文件的名字 |
| $* | 不包括后缀名的当前依赖文件的名字 |
在makefile文件中,可能还会看到下面两个有用的特殊字符,它们出现在命令之前:
| 符号 | 描述 |
|---|---|
| - | 告诉make命令忽略所有错误。 |
| @ | 告诉make命令在执行某条命令前不要将该命令显示在标准输出上。如果想用echo命令给出一些说明信息,这个字符将非常有用。 |
6. clean和install选项
clean:用于将不需要的中间文件清除
install:用于将成功编译的目标文件放入到另一个文件夹
具体用法还需查阅,此处只是标记,供以后查找
shell元字符
| 字符 | 含义 |
|---|---|
| ~ | 通配符:home 目录 |
| ? | 通配符:匹配任意一个字符 |
| * | 通配符:匹配 0 个或多个字符 |
| [] | 通配符:匹配一组字符中的任意一个字符 |
| {} | 通配符:匹配一组字符中的任意一个字符串或识别变量的边界 |
| ; | 在同一行中分隔多条命令 |
| # | 注释 |
| & | 在后台运行命令 |
| $ | 引用变量 |
| \ | 转义符 |
| ’ | 取消所有替换(强引用) |
| ” | 取消部分替换(弱引用) |
| ` | 命令替换 |
| ! | 历史列表:事件标记 |
| < | 重定向输入 |
| > | 重定向输出 |
| | | 管道 |
| () | 在子 Shell 中运行命令 |
通配符
通配符实际上是一种 Shell 实现的路径扩展功能。当命令中包含通配符时,Shell 会先解释通配符的意义,然后在将命令重组,最后运行该命令。
| 字符 | 含义 | 实例 |
|---|---|---|
| * | 匹配 0 或多个字符 | a*b 匹配 aabcb、axyzb、a012b、ab … |
| ? | 匹配任意一个字符 | a?b 匹配 aab、abb、acb、a0b … |
| [list] | 匹配 list 中的任意单一字符 | a[xyz]b 匹配 axb、ayb、azb |
| [!list] | 匹配除 list 中的任意单一字符 | a[!0-9]b 匹配 axb、aab、a-b … |
| [a-f] | 匹配 a~f 中的任意单一字符 | a[a-f]b 匹配 aab、abb、acb … |
| {abc, …} | 匹配大括号内的任意一个字符串 | a{abc,xyz,123}b 匹配 aabcb、axyzb、a123b |
注:通配符看起来有点像正则表达式语句,但是它与正则表达式不同,不能相互混淆。把通配符理解为 Shell 特殊字符就行。而且涉及的只有
* ? [] {}这几种。在使用
[]和{}时,字符中间不能有空格。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 一次性创建多个文件
[Linux]$ touch number{1,2,3,4}.txt
[Linux]$ ls
number1.txt number2.txt number3.txt number4.txt
[Linux]$ touch number{1..9}.txt
[Linux]$ ls
number1.txt number3.txt number5.txt number7.txt number9.txt
number2.txt number4.txt number6.txt number8.txt
# 在使用命令前可以先使用 echo 命令验证结果
[Linux]$ echo {10..23}
10 11 12 13 14 15 16 17 18 19 20 21 22 23
[Linux]$ echo {0..3}{Z..X}
0Z 0Y 0X 1Z 1Y 1X 2Z 2Y 2X 3Z 3Y 3X
[Linux]$ echo a{A{1,2},B{3,4}}b
aA1b aA2b aB3b aB4b
命令分隔符
在大多数情况下,一条命令行只需输入一条命令。可以用 ; 将两条命令连接起来,从而在一条命令行中输入多个命令。在输入时 ; 两边可以不加空格也可以加空格,为了方便阅读可以在 ; 后边加入一个空格。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Linux]$ date; cal
Wed 19 Aug 2020 09:44:55 PM CST
August 2020
Su Mo Tu We Th Fr Sa
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
[Linux]$ whoami; pwd; date
glenn
/home/glenn/Public
Wed 19 Aug 2020 09:48:32 PM CST
还有两个特殊的命令分隔符,即
&&和||,也叫做条件执行。&&前的命令执行成功后会继续执行后面的命令,俗称和命令。||前的命令执行失败后才会执行后面的命令,俗称或命令。如果想在命令没有运行成功时,追加一条警告信息,可以使用以下命令:
1 [Linux]# update || echo 'The update program failed.'
注释
注释在命令行中基本不会用到,主要应用在脚本中。注释可以出现在脚本的任意位置,在每一行中 # 字符之后的内容都会被注释掉(在脚本执行时,会忽略所有的注释)。
1
2
3
4
5
6
7
8
9
10
# 以下两种注释相等,一般注释会单独占用一行
# 显示时间及内核
[Linux]$ date; uname
Wed 19 Aug 2020 09:58:54 PM CST
Linux
[Linux]$ date; uname # 显示时间及内核
Wed 19 Aug 2020 09:58:54 PM CST
Linux
后台运行程序
在单独的 Shell 程序中,也有前后台之分。前台即实时显示的内容,后台类似于图形界面中最小化的程序。将程序(或脚本)放入后台有两种方法:
元字符 & 将程序放入后台执行
在输入命令时在后边加入 & 符号会把命令程序直接放到后台执行,此时可以用 jobs 命令 查看后台执行程序的列表。
1
2
# 将 tar 命令放入后台执行
[Linux]$ tar -cvf web.tar /var/www/html/ &
注意
在后台运行命令时,有输出的命令(如:ping)一样会将结果输出到屏幕,所以最好将输出重定向到某个文件(如:
ping www.baidu.com >out.file 2>&1)。
使用 <Ctrl+Z> 快捷键暂停程序运行
使用 <Ctrl+Z> 快捷键放入后台的命令处于暂停状态,是不会运行的。
1
2
3
4
5
6
[Linux]$ top
# 使用 <Ctrl+Z> 快捷键可以将 top 放入后台
[Linux]$ jobs
[1]- Stopped vi
[2]+ Stopped top
注意
bg 命令和 fg 命令
在后台暂停的命令,可以使用 bg 命令让程序在后台继续执行。格式如下:
1 [Linux]$ bg %1而 fg 命令用于把后台工作恢复到前台执行,格式如下:
1 [Linux]$ fg %1在使用 bg 和 fg 命令时,
%1为后台的编号(%可以省略)。当命令不带参数执行时会对应带有+号的后台程序。
引用变量
使用一个定义过的变量,只要在变量名前面加 $ 符号即可,如:
1
2
3
4
5
[Linux]$ your_name=glenn
[Linux]$ echo $your_name
glenn
[Linux]$ echo ${your_name}
glenn
变量名外面的花括号是可选的,加不加都行。加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
1
2
[Linux]$ name=Java
[Linux]$ echo ${name}Script
如果不给 name 变量加花括号,写成 echo $nameScript ,解释器就会把 $nameScript 当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
推荐给所有变量加上花括号,这是个好的编程习惯。
已定义的变量,可以被重新赋值,如:
1
2
3
4
5
6
[Linux]$ your_name=glenn
[Linux]$ echo $your_name
glenn
[Linux]$ your_name=rose
[Linux]$ echo $your_name
rose
注意
给变量赋值时不能写成
$your_name=rose,只有使用变量的时候才加$符。=两边不要有空格,shell中空格隔开会被认为参数或命令,如
1 2 3 4 5 6 name = "I need help" # 结果是:name是无法识别的command name=I need help # 结果是:name=I, need是无法识别的command name="I need help" # 结果是:name为字符串I need help
转义字符
有时候,可能希望按字面上的含义使用元字符,而不使用其特殊含义。例如,将分号作为分号使用,而不是一个命令分隔符。在这种情况下就需要用转义符去转义元字符。 Shell 中有三种转义符。
| 字符 | 说明 |
|---|---|
| \(反斜杠) | 转义符,去除紧跟其后的元字符的特殊意义 |
| ‘(单引号) | 强引用,所有的元字符都使用其字面含义。强引用中不允许再次出现单引号 |
| “(双引号) | 弱引用,只保留 $ 、 `和\ 三种元字符的特殊含义 |
1
2
3
4
5
6
7
# 转义符转义
[Linux]$ echo It is warm and sunny\; come over and visit
It is warm and sunny; come over and visit
# 中间有空格的文件名使用引用
[Linux]$ cd 'your name'
[Linux]$ cd "your name"
注意
- 使用转义符转义单个字符
- 使用强引用引用字符串
- 使用弱引用引用字符串,保留
$、`和\三种元字符的特殊含义转义字符有强弱之分,
\大于'大于"。
命令替换
命令替换允许在一条命令中嵌入另一条命令,Shell 首先执行嵌入的命令,并且用输出替换该命令,然后在执行整条命令。通过将一条命令封装在 ` 中,可以将它嵌入另一条命令。
1
2
[Linux]$ echo "The time and date are `date`"
The time and date are Fri 21 Aug 2020 09:29:52 PM CST
命令替换还有另外一种格式,即将命令放入
$()中,$(command)等同于command。注意区分${}是引用变量。
历史列表
Shell 通过使用 ! 字符,为历史列表提供了一个特殊的扩展功能。例如用 !24 重新执行历史列表中事件编号为 24 的命令。
Shell 中还有几个好用的历史列表命令:
| 字符 | 说明 |
|---|---|
| !! | 执行上一条命令(等同于 |
| !number | 执行历史列表中第 number 行的命令 |
| !string | 执行最近的以 string 字符串开头的命令 |
| !?string | 执行最近的包含这个字符串的命令 |
| !* | 使用上一条命令的选项和参数 |
| !$ | 使用上一条命令的最后一个参数 |
应该谨慎地使用
!string和!?string格式,除非你完全确信历史列表条目的内容。
1
2
3
4
5
6
7
8
9
10
[Linux]$ ls -l Music/
total 0
[Linux]$ !!
ls -l Music/
total 0
[Linux]$ ls !*
ls -l Music/
total 0
[Linux]$ ls !$
ls Music/
输入输出重定向(很实用)
在 Shell 中,标准输入/标准输出的概念很好理解。默认情况下,大多数程序从键盘读取输入,并将输出写入到屏幕。标准输入(stdin)默认为键盘输入;标准输出(stdout)默认为屏幕输出;标准错误输出(stderr)默认也是输出到屏幕。
在 Linux 进程中,每个输入源和每个输出目标都会有一个唯一的数字标识,这个数字称为文件描述符。例如,一个进程可以从文件 #8 中读取数据,并将数据写入到文件 #6 中。默认情况下,Linux 为每个进程提供 3 个预定义的文件描述符,即 0 代表标准输入, 1 代表标准输出, 2 代表标准错误。
| 类型 | 描述符 | 默认值 | 系统文件 |
|---|---|---|---|
| 标准输入(standard input) | 0 | 从键盘获取 | /proc/self/fd/0 |
| 标准输出(standard output) | 1 | 输出到屏幕 | /proc/self/fd/1 |
| 错误输出(error output) | 2 | 输出到屏幕 | /proc/self/fd/2 |
在 Shell 中也可以改变默认的标准输入、标准输出或错误输出,来实现输入输出的重定向。比如将标准输出指向文件时,那么标准的输出就会保存到文件中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 重定向输出,用标准输出替换文件中的内容
[Linux]$ date > date.txt
[Linux]$ cat date.txt
Sat 22 Aug 2020 09:29:27 PM CST
# 重定向输出,将标准输出的内容追加到文件中
[Linux]$ cal >> date.txt
[Linux]$ cat date.txt
Sat 22 Aug 2020 09:29:27 PM CST
August 2020
Su Mo Tu We Th Fr Sa
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
注意
在重定向输出时(也包括下边的重定向标准错误),如果指定的文件不存在则会新建文件。一定要小心区分替换和追加的区别,不要丢失了重要的数据。
>替换文件中的数据>>将输出追加到文件的末尾
Shell 中定义了两种不同的输出目标:标准输出和错误输出,标准输出用于正常输出,错误输出用于错误消息输出。重定向标准错误时,需要加入错误输出文件描述符(即数字 2 ),当重定向错误输出时,不会影响标准输入和标准输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
[Linux]$ ls a.txt b
ls: cannot access 'b': No such file or directory
a.txt
[Linux]$ ls a.txt b 2> error
a.txt
[Linux]$ cat error
ls: cannot access 'b': No such file or directory
# 分开定义标准输出和错误输出
[Linux]$ ls a.txt b > out 2> error
# 将错误输出追加到文件中
[Linux]$ ls a.txt b 2>> error
如果想将标准输出和错误输出重定向到同一个位置,可以先重定向标准输出,然后在将错误输出指定到标准输出中。
1
[Linux]$ ls a.txt b > output 2>&1
除了重定向输出,还可以用 < 重定向输入。甚至同时指定重定向输入和输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Linux]$ cat a.txt
a
c
d
b
# 重定向输入
[Linux]$ sort < a.txt
a
b
c
d
# 同时指定重定向输入和输出
[Linux]$ sort < a.txt > b.txt
[Linux]$ cat b.txt
a
b
c
d
注意
在 Linux 中,有一个特殊的设备文件,即
/dev/null,它会丢弃一切写入其中的数据(但会反馈写入操作成功)。在程序员行话中, 将
/dev/null称为位桶(bit bucket)或黑洞(black hole),经常被用于丢弃不需要的输出流,或作为输入流的空文件。如果不希望看到命令的错误信息,可以将错误输出重定向到
/dev/null中。同时可以使用cat /dev/null > a.txt清空一个文件中的内容。
管道
在 Linux 设计原则里,每个命令都是一个小工具,每个工具只出色的完成一件事情。当靠一个工具无法解决问题时,能够使用一组命令来完成任务。Shell 允许创建一序列命令,将一个命令的标准输出发送到下一个命令的标准输入,两个命令之间需要用 | 符号连接,这时,一序列命令称为管道线(pipeline), | 符号称为管道(pipe)。
1
2
# 将文件 a 和文件 b 的内容发送到 less 命令中读取
[Linux]$ cat a.txt b.txt | less
上边的命令中,less 只处理 cat 的正确输出结果,如果文件 b.txt 不存在,则只会显示 a.txt 文件的内容。可以将 cat 命令的标准输出和错误输出一起发送给 less 命令,命令为 cat a.txt b.txt 2>&1 | less 。
注意
可以将管道想象成真实的水管,在污水处理中,污水(输出)从一端进入,经过一层过滤(命令)之后流向另一层再去过滤,直到污水被净化干净。
有时候,可能希望将程序的输出同时发送到两个地方。例如,希望将一个输出即保存在文件中,同时还发送到另一个程序。这时可以使用 tee 命令,tee 命令会从标准输入读取数据,将其内容输出到标准输出,同时保存成文件。命令语法为:
1
command 1 | tee file | command2
推荐阅读: tee 输出分流
警告
乍看起来,管道也有重定向的作用,它也改变了数据输入输出的方向,那么,管道和重定向之间到底有什么不同呢?
简单地说,重定向将命令与文件连接起来,用文件来接收命令的输出;而管道将命令与命令连接起来,用第二个命令来接收第一个命令的输出。来看一个特殊的例子:
1 2 3 # 注意这里是 root 用户 [Linux]# cd /usr/bin [Linux]# ls > less第一条命令将当前目录切换到了大多数程序所存放的目录,第二条命令是告诉 Shell 用 ls 命令的输出覆盖文件 less 中的内容。因为 /usr/bin 目录已经包含了 less(程序)文件,所以重定向会破坏西系统中的 less 程序。
这是使用重定向错误重写文件的一个教训,所以在使用时要谨慎。
在子 Shell 运行命令
当在 Shell 中执行命令时,首先 Shell 会判断这条命令是内部命令(Shell 中内置的命令)还是外部命令(单独的程序)。如果是内部命令就直接解释命令,如果是外部命令会创建一个 Shell 副本进程(即子 Shell)运行这个程序。当程序终止时,会重新将控制权交还给原 Shell (即父 Shell),并等待输入另一条命令。
将命令用小括号括起来执行,括号中的命令将会新开一个子 Shell 顺序执行,可以在括号中用 ; 组合多条命令,圆括号中的命令被称为一个编组。
1
[Linux]$ (cd ./file; ./a.py)
提示
当用 ssh 远程登陆主机执行,因为所有的命令都是 ssh 进程的子进程,所以当 ssh 断开连接时,所有的命令都会被杀死。如果想在断开连接时,命令依然在后台执行,可以将命令放入
()中执行。
1 2 3 4 [Linux]$ (ping www.baidu.com > /dev/null &) [Linux]$ ps -ef | grep ping glenn 22202 1 0 21:22 pts/0 00:00:00 ping www.baidu.com glenn 22204 21736 0 21:22 pts/0 00:00:00 grep ping可以看到进程的父 ID 是 init 而不是当前终端的进程 ID,因而关闭 ssh 连接后无任何影响。
文件
文件系统
文件颜色及常见的文件夹
文件颜色代表含义
绿色表示可执行文件
红色表示压缩文件
浅蓝色表示链接文件
白色表示其它文件
黄色表示设备文件,包括block, char, fifo
常见目录解释
目录树(部分)
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
/_
|__bin
|__boot
|__dev
|__etc_
| |__opt
| |__xml
| |__...
|__home
|__lib
|__media
|__mnt
|__opt
|__proc
|__root
|__sbin
|__tmp
|__usr_
| |__bin
| |__include
| |__sbin
| |__lib
| |__src
| |__local
| |__bin
| |__...
|
|__srv
| 目录 | 描述 |
|---|---|
| / | 根目录 |
| /bin | binary,做为基础系统所需要的最基础的命令就是放在这里。比如 ls、cp、mkdir等命令;功能和/usr/bin类似,这个目录中的文件都是可执行的,普通用户都可以使用的命令 |
| /boot | Linux的内核及引导系统程序所需要的文件,比如 vmlinuz initrd.img 文件都位于这个目录中。在一般情况下,GRUB或LILO系统引导管理器也位于这个目录;启动装载文件存放位置,如kernels,initrd,grub。一般是一个独立的分区 |
| /dev | device,一些必要的设备,声卡、磁盘等。还有如 /dev/null. /dev/console /dev/zero /dev/full 等。 |
| /etc | Editable Text Configuration,系统的配置文件存放地. 一些服务器的配置文件也在这里;比如用户帐号及密码配置文件; |
| /etc/opt | /opt对应的配置文件 |
| /etc/xml | XML配置文件 |
| /etc/… | |
| /home | 用户工作目录,和个人配置文件,如个人环境变量等,所有的账号分配一个工作目录。一般是一个独立的分区。 |
| /lib | library,库文件存放地。bin和sbin需要的库文件。类似windows的DLL。 |
| /media | 可拆卸的媒介挂载点,如CD-ROMs、移动硬盘、U盘,系统默认会挂载到这里来。 |
| /mnt | mount,临时挂载文件系统。这个目录一般是用于存放挂载储存设备的挂载目录的,比如有cdrom 等目录。可以参看/etc/fstab的定义。 |
| /opt | 可选的应用程序包 |
| /proc | 操作系统运行时,进程(正在运行中的程序)信息及内核信息(比如cpu、硬盘分区、内存信息等)存放在这里。/proc目录伪装的文件系统proc的挂载目录,proc并不是真正的文件系统,它的定义可以参见 /etc/fstab |
| /root | Root用户的工作目录 |
| /sbin | 和bin类似,是一些可执行文件,不过不是所有用户都需要的,一般是系统管理所需要使用得到的。 |
| /tmp | 系统的临时文件,一般系统重启不会被保存 |
| /usr | Unix System Resource,包含了系统用户工具和程序 |
| /usr/bin | 非必须的,普通用户可执行命令,一般是系统的 |
| /usr/include | 标准头文件 |
| /usr/sbin | sbin理解为supper bin,超级用户使用的binary,非普通用户必须的可执行文件 |
| /usr/lib | bin = binary,/usr/bin/ 和 /usr/sbin/的库文件 |
| /usr/src | src = source,内核源码 |
| /usr/local/bin | bin = binary,普通用户的可执行命令 |
| /srv | 该目录存放一些服务启动之后需要提取的数据 |