# 常用的Linux命令

## 权限处理

`-rw-r--r--`:

| -                  | rw-        | r--         | r--         |
| ------------------ | ---------- | ----------- | ----------- |
| 文件类型（-文件 d目录 l软连接） | u(user)所有者 | g(group)所属组 | o(other)其他人 |

> r 读取权限 read w 写入权限 write x 执行权限 excute

所有者，当前登陆用户所拥有的权限 所属组，当前登陆用户所在的用户组的拥有的权限 其他，非当前用户，用户组，即其他用户所拥有的权限

### chmod命令

change mode， 修改权限

```bash
chmod [选项] 模式 文件名

选项:
-R 递归

模式：
[ugoa][+-=][rwx]
[mode=421]
```

修改权限：

```bash
chmod u+x cangls.av #给文件所有者添加执行权限
chmod g+w,o+w furong.av #给文件添加所属组和其他人的修改权限
chmod u=rwx,g=rw fengjie.av  #直接设置权限，比较方便
chmod a=rwx fengjie.av #设置所有人的权限为读写执行，通常不用
```

使用数字代表权限修改文件的权限：

| 权限 | 代表数字 |
| -- | ---- |
| r  | 4    |
| w  | 2    |
| x  | 1    |

如果要设置如下权限，则可以使用如下命令`rwxr-xr-x`:

```bash
rwx=4+2+1=7
r-x=4+1=5

即
chome 755 文件名

常用的权限：
777 最高权限
755 执行权限
644 文件权限，所有者可更改，其他只可读取
```

### 权限对文件的作用

读取：cat、more、head、tail 写入：vi、echo，不包含删除权限 执行：可执行

> 注: echo 111 >> test.txts echo也是一个写入操作

### 权限对目录的作用

读：可以查看目录下的文件 (ls) 写: 具有修改目录结构的权限 （touch rm mv cp） 执行：可以进入目录（cd）

## 文件目录基本操作

### ls 浏览目录子文件

命令英文原意：list

```shell
ls 选项[-ald] [文件或目录]
-a 显示所有文件，包括隐藏文件
-l 详细信息显示
-d 查看目录属性
```

### pwd 展示当前所在的路径

命令英文原意：print working directory

```shelll
pwd
```

### cd 切换目录

命令英文原意：change directory

```shell
cd /
cd ..
# 切换到家目录
cd ~
# 切换到上一个目录
cd -
```

### mkdir 创建目录

命令英文原意：make directory

```shell
mkdir [目录名]
mkdir newdir
```

### rmdir 删除空目录

命令英文原意：remove directory

```shell
rmdir [目录名]
rmdir newdir
```

### rm 删除文件或者目录

英文原意，remove

```shell
rm [参数] <目标文件路径>
-f ：就是force的意思，忽略不存在的文件，不会出现警告消息
-i ：互动模式，在删除前会询问用户是否操作
-r ：递归删除，最常用于目录删除，它是一个非常危险的参数

删除某个文件: rm myfiles（文件名）
删除当前目录下的所有文件：rm *
递归删除某个目录（包含该目录下所有文件及子目录）： rm -r myfolder（目录名）
强迫删除所有后缀名为txt文件：rm –f *.txt
删除当前目录下的所有文件：rm –i * （删除文件时会询问,可按Y或N键表示允许或拒绝删除文件）
```

### mv 移动文件和目录

```shell
mv 文件1 文件1新位置（新位置如果是目录则移入目录，如果是文件名则移动并改名）
```

## 文件拷贝

### cp 拷贝文件或者目录

英文原译， copy

```shell
cp [参数] <源文件路径> <目标文件路径>
-p ：连同文件的属性一起复制，而非使用默认方式，常用于备份
-i ：若目标文件已经存在时，在覆盖时会先询问操作的进行
-r ：递归持续复制，用于目录的复制行为
-u ：目标文件与源文件有差异时才会复制

将test1.txt复制成test2.txt：
cp test1.txt test2.txt

将test3.txt复制到/tmp目录中：
cp test3.txt /tmp （目录）

目录拷贝：
cp –r test1(目录） test2(目录）
```

## 文件压缩解压

### tar

英文原译：tape archive

```shell
tar [参数] <文件>
-t ：查看打包文件的内容含有哪些文件名
-c ：新建打包文件
-x ：解打包或解压缩的功能，可以搭配-C（大写）指定解压的目录，注意-c,-t,-x不能同时出现在同
一条命令中
-j ：通过bzip2的支持进行压缩/解压缩
-z ：通过gzip的支持进行压缩/解压缩
-v ：在压缩/解压缩过程中，将正在处理的文件名显示出来
-f filename ：filename为要处理的文件
-C dir ：指定压缩/解压缩的目录dir

# 当前目录的所有文件打包成test.tar：
tar -cvf test.tar *
# 将当前目录的所有文件打包成test.tar,再用gzip命令压缩： 
tar -czvf test.tar.gz *
# 查看test.tar文件中包括了哪些文件： 
tar -tf test.tar
# 将test.tar解打包：
tar -xvf test.tar
# 将foo.tar.gz解压缩并解打包：
tar -xzvf foo.tar.gz
```

## 文件内容读取

### cat 连接文件并打印到标准输出设备上

命令英文原意：concatenate and display files

```shell
-E 在每一行的末尾显示$
-n 为显示行添加行号

cat m1 （在屏幕上显示文件ml的内容）
cat m1 m2 （同时显示文件ml和m2的内容）
```

### more 分页显示文件内容

```shell
more [文件名]

(空格) 或f 显示下一页
(Enter) 显示下一行
q或Q 退出
```

### less 分页显示文件内容

```shell
less [文件名]

(空格) 或f 显示下一页
(Enter) 显示下一行
q或Q 退出

除此之外，还可以使用方向键上下滚动文件
```

### head 显示文件前几行的内容

```shell
head [参数] <文件名>
-n：显示前n行，不指定此参数显示前10行
```

### tail 显示文件后几行的内容

```shell
tail [参数] <文件名>
-n：显示后n行，不指定此参数显示后10行
+n：从第n行显示到文件尾
-F：用于跟踪显示不断增长的文件结尾内容
```

## 搜索命令

### 命令搜索 whereis

1. 用于搜索命令所在的路径以及帮助文档所在的位置，不能搜索用户自己创建的文件等信息
2. **不能看到shell命令**(自带的命令，比如cd命令)，只能看到外部安装的命令（环境变量中的命令）
   * `-b`:只查找可执行文件
   * `-m`:只查找帮助文件

### 命令搜索 which

与whereis命令相同，不能看到shell命令，但是还可以看到命令文件的所在位置。

### 文件搜索：locate

> locate ： 定位，Ubuntu下没有该命令

`locate [文件名]`

1. locate搜索数据库，搜索速度非常快
2. 数据库文件的位置在`/var/lib/mlocate`，这个数据库中包含了所有的文件名
3. 该数据库文件每天更新一次，当我们作新建文件，或是其他等操作，系统不会主动更新数据库，需要 使用`updatedb` 命令更新
4. locate命令搜索遵循`/etc/updatedb.conf`配置文件

   ```config
   #是否开启搜索限制
   PRUNE_BIND_MOUNTS="yes"
   # 搜索时，不搜索的文件类型
   # PRUNENAMES=".git .bzr .hg .svn"
   # 搜索时，不搜索的文件路径
   PRUNEPATHS="/tmp /var/spool /media /home/.ecryptfs"
   # 搜索时，不搜索的文件系统
   PRUNEFS="NFS nfs nfs4 rpc_pipefs afs binfmt_misc proc smbfs autofs iso9660 ncpfs coda devpts  ftpfs devfs mfs shfs sysfs cifs lustre tmpfs usbfs udf fuse.glusterfs fuse.sshfs curlftpfs ecryptfs fusesmb  devtmpfs"
   ```

### 文件搜索 find

`find [搜索范围] [搜索条件]`

1. 搜索范围：
   * 避免大范围搜索，会非常消耗系统资源
   * `find / -name nginx.conf` 在根路径下查找名为nginx.conf的配置文件
   * `find /etc -name *.conf` 在etc路径下查找名为nginx.conf的配置文件 注意，在MacOS下，如果使用通配符，需要使用单引号或者双引号包裹：`find /etc -name "*.conf"`
2. 搜索条件：
   1. 时间
      * `-mtime +10`：查找10天前修改的文件
      * `-mtime 10`：查找10天前当天修改的文件
      * `-mtime -10`：查找10天内修改的文件
   2. 类型
      * `-atime` 文件访问时间
      * `-ctime` 改变文件属性
      * `-mtime` 修改文件内容
   3. 根据文件名称
      1. `-name` 可以使用通配符
      2. `-iname`：不区分要搜索的文件名的的大小写
      3. 可用的通配符
         * `*`匹配任意内容
         * `?`匹配任意一个字符
         * `[]`匹配任意一个括号内的字符
   4. 文件大小
      1. `-size`：文件大小用小写k和大写M
   5. 所属用户
      1. `-user root`：搜索属于root用户的文件
      2. `-nouser`：搜索没有所属者的文件，liunx中，每个文件都有所属者，如果没有，有可能有以下几种情况：垃圾文件、内核产生的文件（proc/,sys/）、外来文件（U盘拷入）
3. 其他选项
   * `-a` 表示and
   * `-o` 表示or

举例：

```shell
find /etc -size +20k -a -size -50k -exec ls -lh {} ;
# -exec {} \; 固定格式，表示直接对前面的搜索结果进行后面的命令处理
```

## Linux三剑客

* 正则表达式是一套规则与方法
* 正则工作时以行为单位，一次处理一行文本
* Linux下仅有三剑客支持正则处理，其他命令无法使用

三剑客：

1. grep：文本过滤工具
2. sed：stream editor，流编辑器，文本编辑工具
3. awk：Linux的文本报告生成器（格式化文本），实际是上一个指向`gawk`的软连接

### 正则表达式

基本的正则表达式BRE：

| 符号      | 作用                                                                            |
| ------- | ----------------------------------------------------------------------------- |
| `^`     | 匹配开头，比如`^kube`，匹配以kube开头的行                                                    |
| `$`     | 匹配结尾，比如`service$`，匹配以service结尾的行                                              |
| `^$`    | 匹配开头空，空结尾的行，也就是空行                                                             |
| `.`     | 匹配一个任意字符，且不可以是空行                                                              |
| `*`     | 匹配前一个表达式0次或者多次，等同于`{0,}`，比如`ab*`代表匹配a后面没有b的或者有一个或者多个b的字符串，将会匹配`a`、`ab`、`abbb` |
| `.*`    | 组合符，匹配所有的内容，匹配任意一个字符(`.`)重复0次或者多次(`*`)                                        |
| `^.*`   | 组合符，匹配任意多个字符开头的行，包含空行                                                         |
| `/*$`   | 组合符，匹配任意多个字符结尾的行，包含空行                                                         |
| `[abc]` | 匹配`[]`内的任意一个字符，`a`或`b`或`c`                                                    |
| `[^]`   | 匹配除了`^`后的任意字符，`^`表示取反                                                         |
| `\`     | 转义字符，对特殊含义字符转义，`\.`表示`.`字符，但是不能匹配空行                                           |

扩展正则表达式ERE，需要使用`grep -E`才可以生效：

| 符号       | 作用                      |
| -------- | ----------------------- |
| `+`      | 匹配前一个字符1次或者多次           |
| `[ab]+`  | 匹配a或者b出现一次或者多次          |
| `?`      | 匹配前一个字符0次或者1次           |
| \`       | \`                      |
| `()`     | 表示分组过滤，被括起来的内容表示一组，一个整体 |
| `a{n,m}` | 匹配前一个字符a至少出现n次，最多出现m次   |
| `a{n,}`  | 匹配前一个字符a最少出现n次          |
| `a{,m}`  | 匹配前一个字符a最多出现m次          |
| `a{n}`   | 匹配前一个字符a正好出现n次          |

### grep

Gloab search REgular expression and Print out the Line. 是一个根据用户指定的模式（过滤条件）对目标文本进行匹配检查并打印匹配到的行的文本搜索工具。他的主要模式由正则表达式的元字符以及文本字符锁边写出的过滤条件。

```shell
grep [option] [pattern] file

# 常用的option
-E: 支持使用扩展的正则表达式元字符
-i: ignorecase，忽略大小写
-o: 仅显示匹配到的字符串本身，而不是显示他所在的行
-v: 排除匹配到的行，显示没有匹配的行
-n: 显示匹配的行的行号
-c: 统计匹配结果的行数
--color=auto 显示颜色
```

示例：

```shell
# 找出空行的数量
grep -Ec "^$" a.txt

# 找出除了空行外的行
grep -Ev "^$" a.txt

# 找出包含java的行
grep "java" a.txt

# 剔除所有的空行以及注释行（以#开头）
grep "^#" a.txt -v | grep "^$" -v

# 匹配以.结尾的行
grep "\.$" a.txt -n

# 匹配任意字符，但是不匹配空行，也就是去除空行
grep "." a.txt -n
```

### sed

是操作、过滤、转换文本内容的强大工具，他的处理流程如下：

1. sed会以行为单位进行读取
2. 读取一行数据后将数据放入sed模式空间（内存中）
3. 对改行进行模式匹配，如果匹配失默认进行标准输出（不做修改）
4. 如果模式匹配成功，将会根据模式编辑文本并进行标准输出

```shell
sed [OPTION]... {script-only-if-no-other-script} [input-file]...
```

其中，匹配规则与处理规则写在`{script-only-if-no-other-script}`中。处理脚本大致分为两个部分：

1. 匹配规则
2. 字符命令

比如：

```shell
# 删除input.txt文件的第二行与第三行并重新输出到output.txt中
sed '4d' input.txt > output.txt
# 其中，`2,3`代表模式，匹配了第二行到第三行，d代表字符命令删除。
```

| 模式                      | 说明                                            |
| ----------------------- | --------------------------------------------- |
| `空地址`                   | 全文匹配                                          |
| `单地址`                   | 指定匹配某一行，比如`3`匹配第三行                            |
| `n,m`                   | 匹配第n行到第m行                                     |
| `n,+x`                  | 匹配第n行向下的x行                                    |
| `n~y`                   | 步长匹配，匹配第`n`，第`n+y`，第`n+2y`行...，通常用于匹配奇数行或者偶数行 |
| `/pattern/`             | 正则匹配通过的行                                      |
| `/pattern1/,/pattern2/` | 匹配多个正则                                        |

| 字符命令            | 说明                              |
| --------------- | ------------------------------- |
| `模式p`           | print， 打印匹配行的内容，通常和 `-n` 一同使用   |
| `模式a 追加的文本行`    | append， 文本追加，在指定的行后添加一**行**或者多行 |
| `模式i 插入的文本行`    | insert， 文本插入，在指定的行前添加一**行**或者多行 |
| `模式d`           | delete， 删除匹配的行                  |
| `模式s/正则/替换内容/g` | 匹配正则内容，然后替换内容，g代表全局替换           |

此外，sed支持以下几种常用的选项：

| sed选项 | 说明                        |
| ----- | ------------------------- |
| `-n`  | 取消默认的sed输出，通常与`p`字符命令一通使用 |
| `-i`  | 直接将修改结果写入文件，而不是修改内存内容     |
| `-e`  | 多次编辑，处理之后再处理一次，该选项可以替代管道  |
| `-r`  | 支持正则扩展                    |

案例：

```shell
# 删除第五行到结尾，并打印到屏幕
sed '5,$d' a.txt
# 将文件中的所有My换成I，并写入
sed "s/My/I/g" a.txt -i
# 将文件第三行中的所有My换成I，并写入
sed "3/My/I/g" a.txt -i
# 将文件中的所有I换成My，然后再将所有Cat换成Dog
sed -e "s/I/My/g" -e "s/Cat/Dog" a.txt
# 在第四行前一行插入一行文本
sed "4i My Dog is Dingdang!" a.txt
# 添加多行信息
sed "3a I like girl!\nI love pretty girl!"
# 在每一行下方插入 ----
sed "a ---" a.txt
#引用分组 使用\1引用分组1 \2引用分组2
sed  -r -i 's/(PASS_MAX_DAYS)\s+([0-9]+)/\1 90/'  /etc/login.defs
```

找出本机的IP地址：

```shell
ifconfig eth0 | sed -e "2s/^.*inet//" -n -e "2s/net.*$//p" -n 
```

### awk

文本格式化：

```shell
awk [options] 'pattern[action]' file ...
```

## envsubst(替换配置文件的替换项)

假设应用程序下有如下配置文件`application.properties`:

```properties
db.name=mysql
db.user=root
db.password=root
```

此时如果我想修改数据库用户和密码，需要使用vim打开文件，然后修改值再保存重启。但是如果当前目录下有100个类似的文件，这样的操作就很繁琐了（建议使用配置中心）。

所以，可以使用`envsubst`命令，统一替换所有的配置文件，步骤如下：

```shell
# 建立application.properties的模板配置文件：application.template
db.name=${dbname}
db.user=${dbusername}
db.password=${dbpassword}

# 建立unified-config.conf文件，用于存放变量值
export dbname=mysql
export dbusername=root
export dbpassword=root

# 执行source unified-config.conf，将这些之定义为环境变量，这是环境变量中就会拥有这些值了
source unified-config.conf

# 执行envsubst命令
# 1. 加载application.template
# 2. 然后处理后再从管道流输出到application.properties中
envsubst < application.template > application.properties
```

## curl

**get请求**：

```shell
$ curl https://baidu.com
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>bfe/1.0.8.18</center>
</body>
</html>
```

**展示响应头信息（`-i`，`--include`）**：

```shell
$ curl -i https://baidu.com
HTTP/1.1 302 Moved Temporarily
Server: bfe/1.0.8.18
Date: Tue, 14 Sep 2021 14:22:21 GMT
Content-Type: text/html
Content-Length: 161
Connection: keep-alive
Location: http://www.baidu.com/

<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>bfe/1.0.8.18</center>
</body>
</html>
```

**只查看响应头（`-I`，`--head`）**：

```shell
$ curl -I https://baidu.com
HTTP/1.1 302 Moved Temporarily
Server: bfe/1.0.8.18
Date: Tue, 14 Sep 2021 14:23:24 GMT
Content-Type: text/html
Content-Length: 161
Connection: keep-alive
Location: http://www.baidu.com/
```

**如果是3开头的，则自动进行请求重定向地址(`-L`，`--Location`)**：

```shell
$ curl -iL https://baidu.com
HTTP/1.1 302 Moved Temporarily
Server: bfe/1.0.8.18
Date: Sat, 06 Aug 2022 07:53:22 GMT
Content-Type: text/html
Content-Length: 161
Connection: keep-alive
Location: http://www.baidu.com/

HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: keep-alive
Content-Length: 2381
Content-Type: text/html
Date: Sat, 06 Aug 2022 07:53:22 GMT
Etag: "588604c8-94d"
Last-Modified: Mon, 23 Jan 2017 13:27:36 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/

<!DOCTYPE html>
<!--STATUS OK-->......省略

```

**保存响应内容**：

```shell
-o, --output <file> Write to file instead of stdout  # 用文件写入替换标准输出

$ curl -o baidu.html  https://baidu.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   161  100   161    0     0    809      0 --:--:-- --:--:-- --:--:--   809
(base)
$ cat baidu.html
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>bfe/1.0.8.18</center>
</body>
</html>
```
