# 前言 shell命令的操作和脚本开发从来都不是运维人员的专属技能,高级/资深前端工程师往往已经能够熟练使用大量shell命令来为自己提效,掌握shell命令不仅可以在服务器运维时大显身手,日常开发中也能帮你替代大量的鼠标操作...,本文将为你提供最全的常用 shell 命令操作速查手册。 虽然但是,你不禁还是要问 **我一个前端为啥要会shell?** 了解基本的 Shell 命令和脚本编写对前端开发人员来说是必要的,你看看以下几点能不能够说服你: 1. **提高工作效率**: 熟练使用shell可以大大优化前端开发者的常见操作,如文件处理、程序运行、远程连接、发起网络请求等,还可以自动化许多重复性任务,减少手动操作的错误,极大提升工作效率。 查看本机ip?别再去网络设置里看了,用命令1s内搞定。 如果你要上传一个文件到服务器,想一想它有多少个步骤,编写几行脚本,一个回车就能解决不香么? 简单测试下限制10次/s的限流器是否生效,你会怎么做,试试用 shell 写个脚本,几行搞定,其他项目还能复用。 > 不能说用鼠标点击很low,但是当你用习惯命令行时会发现鼠标点击真的很慢,效率很低。 1. **掌握部署运维**: 部署和运维前端项目通常需要用到shell脚本,了解shell能更好地进行自动化部署。 这个没啥说的,掌握基本运维操作是一个高级前端应该具备的技能,可能不需要你去写部署的脚本,但是类似让你自己修改下nginx的配置这种是应该可以分分钟搞定的。 1. **调试项目问题**: 查看日志文件,检查环境变量等都需要shell命令,有助于快速定位和解决各种问题。 2. **配合开发工具**: 许多前端工具都需要配合shell命令使用,如Webpack、npm scripts、Jenkins等,当你自研脚手架或写自己的 npm 包时就更需要。 3. **拓宽技术视野**: 计算机科学中shell是非常基础和重要的知识,对前端开发有启发作用,同时也能提升你在团队的技术影响力。 ## 命令行执行脚本时参数的传递和获取 ### 顺序参数 假设在命令行执行以下脚本: `sh bin/start.sh -p 30128 -n myproject -e prod` 其中的 `-p 30128 -n myproject -e prod` 即为参数传递的方式,在 `start.sh` 脚本中,你可以使用特殊变量 `$1`、`$2`、`$3` 等来获取命令行传入的参数。这些特殊变量分别表示第一个、第二个、第三个参数,以此类推。 例如,假设你的 `start.sh` 脚本内容如下: ```Shell bash 复制代码 #!/bin/bash # 获取第一个参数值,即 -p 后面的值 PORT=$2 # 获取第二个参数值,即 -n 后面的值 NAME=$4 # 获取第三个参数值,即 -e 后面的值 ENVIRONMENT=$6 echo "Port: $PORT" echo "Name: $NAME" echo "Environment: $ENVIRONMENT" echo "$@" # 输出所有参数,每个作为一个词,整体则为数组 echo "$*" # 输出所有参数,作为一个整体字符串 ``` > 注意 `$1` `$2` `$3` `$4` `$5` `$6` 分别对应 -p 30128 -n myproject -e prod 当你执行以上命令时:输出将会是: ```MakeFile makefile 复制代码 Port: 30128 Name: myproject Environment: prod -p 30128 -n myproject -e prod -p 30128 -n myproject -e prod ``` ### 相关扩展:$ 和 @ 符号 $和@属于shell的特殊字符,用来表示传递给脚本或函数的位置参数(Positional Parameters)。 具体来说: - $n:读取第n个位置参数的值。 - $@:以数组的形式读取所有位置参数。 - $*:以字符串的形式读取所有位置参数。 - $0:当前脚本或函数的名称 - $#:位置参数的个数 - ### 无序参数 使用 getopts 无需按照顺序获取参数 ```Shell bash 复制代码 #!/bin/bash # 使用 getopts 来解析命令行参数 # 当传入 -p、-n、-e 选项时,分别将参数值保存到 PORT、NAME、ENVIRONMENT 变量 while getopts ":p:n:e:" opt; do case "$opt" in # 如果是 -p 选项 p) PORT=$OPTARG ;; # 如果是 -n 选项 n) NAME=$OPTARG ;; # 如果是 -e 选项 e) ENVIRONMENT=$OPTARG ;; # 如果遇到非法的选项参数,打印错误提示 \?) echo "Invalid option: -$OPTARG" 1>&2 ;; # 如果缺少参数值,自定义错误提示 :) echo "Option -$OPTARG requires an argument" 1>&2 ;; esac done # 打印出解析后的参数值 echo "Port: $PORT" echo "Name: $NAME" echo "Environment: $ENVIRONMENT" ``` ### 相关扩展: getopts 命令 getopts是Linux/Unix系统shell脚本中处理命令行选项和参数的工具。 `":p:n:e:"` 是一个选项字符串,定义了可以接受哪些选项以及这些选项是否需要参数。 - `:`:在选项字符串的开头表示如果 `getopts` 遇到一个选项需要参数,但用户没有提供参数,那么 `getopts` 将把该选项的名称存储在 `OPTARG` 变量中,并设置 `opt` 变量为 `:`。这就是为什么在 `case` 语句中有一个 `:` 分支,用于处理这种情况。另外,加上首个冒号之后代表选项参数是可选的,去掉首个冒号代表参数是必填的。 - `p`:表示脚本可以接受 `-p` 这个选项。 - `p:`:后面的 `:` 表示这个选项需要一个参数。 在上述示例中,`getopts`命令后面的冒号表示参数可选,而选项字符(如`p`、`n`、`e`)则是你希望解析的选项(键),会存储到 opt上。每个选项后的冒号表示这个选项可以带一个值。 在`getopts`的`while`循环中,`$opt`会保存当前解析到的键,而`$OPTARG`会保存该选项的值(如果有的话)。 如果你运行脚本时使用了未定义的选项,那么`$opt`会被设置为`?`,可以在`case`语句中处理未知选项。 ### 相关扩展: >& 操作符 `1>&2` 是一种重定向文件描述符操作,用于将标准输出(文件描述符 1)重定向到标准错误输出(文件描述符 2)。 在 Unix 和类 Unix 系统中,当你运行一个命令或脚本时,它通常有三个默认的文件描述符(也就是数据流): - 标准输入(stdin),文件描述符为 0 - 标准输出(stdout),文件描述符为 1 - 标准错误输出(stderr),文件描述符为 2 所以,`1>&2` 的意思就是将标准输出重定向到标准错误输出。这样,原本会打印到屏幕或被重定向到文件的输出信息,现在会被打印到标准错误输出。这在你希望将错误信息和正常输出分开处理时非常有用。 `echo "Option -$OPTARG requires an argument" 1>&2` 这行代码就是将错误消息 “Option -$OPTARG requires an argument” 打印到标准错误输出,而不是标准输出。这样,如果用户将脚本的输出重定向到文件,这个错误消息仍然会被打印到屏幕,而不会被写入文件。 为了方便理解,举个例子: 假设我们有一个名为 `myscript.sh` 的 Bash 脚本,内容如下: ```Shell bash 复制代码 echo "This is a normal message." echo "This is an error message." 1>&2 ``` 这个脚本会打印两条消息,一条是正常的消息,另一条是错误消息。 如果我们直接运行这个脚本,那么两条消息都会被打印到终端: ```Shell bash 复制代码 $ ./myscript.sh This is a normal message. This is an error message. ``` 但是,如果我们将脚本的输出重定向到文件,那么只有正常的消息会被写入文件,错误消息仍然会被打印到终端: ```Shell shell 复制代码 $ ./myscript.sh > output.txt This is an error message. ``` 然后,如果我们查看 `output.txt` 文件的内容,我们只会看到正常的消息: ```Shell bash 复制代码 $ cat output.txt This is a normal message. ``` 这就是 `1>&2` 的作用:即使你将脚本的输出重定向到文件,错误消息仍然会被打印到终端 ### 相关扩展:用于输出的命令和操作符:echo、printf、>、>>、tee 1. **echo**:`echo` 是一个内置命令,用于在标准输出(通常是终端)上打印一行文本。例如: ```Shell bash 复制代码 echo "Hello, world!" ``` 这条命令会在终端上打印 “Hello, world!”,并且自带换行。 1. **printf**:`printf` 是一个更强大的内置命令,可以格式化输出文本。例如: ```Perl perl 复制代码 printf "Hello, world!\n" printf "Hello, %s!\n" "world" ``` 这条命令会在终端上打印 “Hello, world!”。`%s` 是一个占位符,表示一个字符串,`\n` 表示新行。 当使用格式化字符串时,printf 会保留换行空格等特殊字符,这在你需要保持原始字符串或者json数据时很有用。 ```Shell bash 复制代码 name="Hello,\nworld!" printf "Hello, %s!" "$name" # 输出 # Hello, Hello,\nworld!! ``` 1. **>** :`>` 是一个重定向操作符,用于将标准输出重定向到文件。如果文件已存在,则会覆盖文件的内容。例如: ```Shell bash 复制代码 echo "Hello, world!" > file.txt ``` 这条命令会将 “Hello, world!” 写入 `file.txt`,覆盖 `file.txt` 中的任何现有内容。 1. **>>** :`>>` 也是一个重定向操作符,与 `>` 类似,但如果文件已存在,则会将内容追加到文件的末尾,而不是覆盖现有内容。例如: ```Shell bash 复制代码 echo "Hello, again!" >> file.txt ``` 这条命令会将 “Hello, again!” 追加到 `file.txt` 的末尾。 1. **tee**:`tee` 是一个命令,可以将输入同时发送到标准输出和一个或多个文件。例如: ```Shell bash 复制代码 echo "Hello, world!" | tee file.txt ``` 这条命令会在终端上打印 “Hello, world!”,并将其写入 `file.txt`。如果你希望追加内容而不是覆盖,你可以使用 `-a` 选项: ```Shell bash 复制代码 echo "Hello, again!" | tee -a file.txt ``` 输出到多个文件 ```Shell bash 复制代码 echo "Hello, world!" | tee file1.txt file2.txt file3.txt ``` ## 快速获取本机 ip 地址 ```Shell bash 复制代码 ifconfig | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}' ``` - `ifconfig`:这个命令用于显示和配置网络接口的信息,包括 IP 地址、MAC 地址等。 - `|`:管道操作符,它将前一个命令的输出作为后一个命令的输入。在这个命令中,`ifconfig` 的输出将作为后续命令的输入。 - `grep inet`:这个命令使用 `grep` 工具来搜索包含 "inet" 的行,这些行通常包含了 IP 地址的信息。 - `grep -v 127.0.0.1` 用于排除 "127.0.0.1" 这个回环地址,因为这是本地回环接口的地址,不是真正的网络接口。 > "127.0.0.1" 是一个特殊的IP地址,通常称为 "回环地址" 或 "本地主机"。回环地址是IPv4地址范围中的一部分,它的主要作用是用于本地主机上的自我测试和通信。 > 当计算机上的应用程序尝试连接到 "127.0.0.1" 时,它实际上是在尝试与自己进行通信。这种通信通常用于测试和开发目的,不需要实际的网络连接。 - `grep -v inet6` 用于排除 IPv6 地址,只保留 IPv4 地址。 - `awk '{print $2}'`:使用 `awk` 工具来提取每行的第二个字段,这通常是 IP 地址部分。例如: `ifconfig | grep inet | grep -v 127.0.0.1 | grep -v inet6` 如果输出为: inet 10.203.80.135 netmask 0xfffff000 broadcast 10.203.95.255 使用 awk 提取第二个字段即为 10.203.80.135 ### 相关扩展:grep 工具 `grep`是一个强大的文本搜索工具,它可以在文本文件中搜索与指定模式匹配的行。它是“全局正则表达式打印”(Global Regular Expression Print)的缩写。 基本语法: ```Shell bash 复制代码 grep [选项] 搜索模式 [文件名] ``` - `选项`:`grep` 支持多种选项,用于控制搜索的行为。 - `搜索模式`:是你要查找的文本字符串,可以是普通文本或正则表达式。 - `文件名`:是你要搜索的文件名。如果不提供文件名,`grep` 将从标准输入(通常是键盘输入)读取文本。 #### 选项概览 以下是一些常用的 `grep` 选项: - `-i`:`i` 代表 "ignore case",表示不区分大小写搜索。 - `-v`:`v` 代表 "invert match",表示反转匹配,只显示不匹配的行。 - `-l`:`l` 代表 "files with matches",表示只显示包含匹配项的文件名,而不是匹配的行。 - `-c`:`c` 代表 "count",表示只计数匹配的行数,而不显示匹配的行。 - `-r`:`r` 代表 "recursive",表示递归搜索,用于搜索目录及其子目录中的文件。 - `-E`:`E` 代表 "extended regex",表示启用扩展正则表达式(支持更多正则表达式语法)。 - `-A`:`A` 代表 "after context",表示显示匹配行及其后的几行。 - `-B`:`B` 代表 "before context",表示显示匹配行及其前的几行。 - `-n`:`n` 代表 "line number",表示显示匹配的行及其行号。 - `-o`:`o` 代表 "only matching",表示仅显示匹配的文本,而不是整行。 常见用法示例: #### 使用 `-i` 选项进行不区分大小写搜索行 假设有一个文本文件 `example.txt` 包含以下内容: ```Plain Text 复制代码 Apple Banana apple banana ``` 要在不区分大小写的情况下搜索 "apple",可以使用 `-i` 选项: ```Shell bash 复制代码 grep -i "apple" example.txt ``` 输出: ```Plain Text 复制代码 Apple apple ``` #### 使用 `-v` 选项反转匹配,搜索不匹配的行 假设有一个文本文件 `fruits.txt` 包含以下内容: ```Plain Text 复制代码 Apple Banana Cherry ``` 要查找不包含 "Banana" 的行,可以使用 `-v` 选项: ```Shell bash 复制代码 grep -v "Banana" fruits.txt ``` 输出: ```Plain Text 复制代码 Apple Cherry ``` #### 使用 `-l` 选项搜索包含匹配项的文件名 ```Shell bash 复制代码 grep -l "404" *.log #只显示包含404的日志文件 grep -l "Pattern" file1.txt file2.txt #搜索多个文件 ``` 还可以搜索一个目录,举例来说,假设有一个名为 `mydir` 的目录,它包含以下结构: ```Markdown markdown 复制代码 mydir/ file1.txt file2.txt subdir/ file3.txt file4.txt ``` 如果要在 `mydir` 目录及其子目录中搜索包含 "pattern" 的文件并显示文件名,可以使用以下命令: ```Perl perl 复制代码 grep -rl "pattern" mydir ``` 输出将是: ```Shell bash 复制代码 mydir/file1.txt mydir/subdir/file3.txt ``` 这将返回所有包含 "pattern" 的文件的路径列表,包括它们的相对路径。 #### 使用 `-r` 选项递归搜索目录,返回匹配行 假设有一个目录 `mydir` 包含多个文本文件,我们想要递归搜索整个目录及其子目录中的 "pattern"。 ```Shell bash 复制代码 grep -r "pattern" mydir ``` 这将搜索 `mydir` 目录及其子目录中的所有文件,查找包含 "pattern" 的行。 加上 -l 则返回匹配的文件名,加上 -n 则返回行号。 #### 使用 `-n` 选项显示匹配的行及其行号 假设有一个文本文件 `example.txt` 包含以下内容: ```SCSS scss 复制代码 Line 1 This is Line 2 Line 3 Another Line 3 ``` 要显示包含 "Line 3" 的行及其行号,可以使用 `-n` 选项: ```Shell bash 复制代码 grep -n "Line 3" example.txt ``` 输出: ```MakeFile makefile 复制代码 3:Line 3 4:Another Line 3 ``` #### 使用 `-c` 选项计算匹配的行数 假设有一个文本文件 `example.txt` 包含以下内容: ```Plain Text 复制代码 Apple Banana apple banana ``` 要计算包含 "apple" 的行数,可以使用 `-c` 选项: ```Shell bash 复制代码 grep -c "apple" example.txt ``` 输出: ```Plain Text 复制代码 2 ``` #### 使用 `-E` 选项启用扩展正则表达式搜索行 假设我们有一个文本文件 `example.txt` 包含以下内容: ```Plain Text 复制代码 apple apples applies ``` 要查找包含 "apples" 或 "applies" 的行,可以使用 `-E` 选项启用扩展正则表达式: ```Shell bash 复制代码 grep -E "apples|applies" example.txt ``` 输出: ```Plain Text 复制代码 apples applies ``` #### 使用 `-A` 和 `-B` 选项搜索匹配行及其前后的几行 假设有一个文本文件 `example.txt` 包含以下内容: ```SCSS scss 复制代码 Line 1 Line 2 Match: Line 3 Line 4 Line 5 ``` 要显示包含 "Match: Line 3" 的行及其前后的两行,可以使用 `-A` 和 `-B` 选项: ```Shell bash 复制代码 grep -A 2 -B 2 "Match: Line 3" example.txt ``` 输出: ```SCSS scss 复制代码 Line 1 Line 2 Match: Line 3 Line 4 Line 5 ``` #### 使用 `-o` 选项仅显示匹配的文本,而不是整行 假设有一个文本文件 `example.txt` 包含以下内容: ```MakeFile makefile 复制代码 apple:fruit banana:fruit cherry:fruit ``` 要仅显示匹配 "banana" 的文本,可以使用 `-o` 选项: ```Shell bash 复制代码 grep -o "banana" example.txt ``` 输出: ```Plain Text 复制代码 banana ``` `grep` 非常强大,你可以根据具体的需求组合不同的选项和参数(指定文件名、文件扩展名、目录、多个文件等)来定制你的搜索。 ### 相关扩展:awk 工具 `awk` 是一种用于文本处理的强大工具和编程语言,它可以在命令行环境下用于对文本文件进行各种操作,包括提取、转换、格式化和分析数据,`awk` 既是工具,也是一种编程语言。 具体来说: - **工具:** `awk` 是一个命令行工具,你可以通过在命令行输入 `awk` 命令来处理文本数据。 - **编程语言:** `awk` 还是一种编程语言,它具有变量、条件语句、循环、函数等编程元素,允许你编写复杂的脚本来处理文本数据。 在命令行中使用 `awk` 工具: ```Shell bash 复制代码 awk 'pattern { action }' file.txt ``` 其中,`pattern` 是一个条件,当满足条件时,执行 `action` 中指定的操作。你可以在 `action` 中使用 `awk` 的编程语言特性来处理文本数据。 具体使用示例: #### 打印文本文件的某一列 ```Go go 复制代码 ``` bash awk '{print $2}' file.txt ``` 这会打印 `file.txt` 文件的每一行的第二列。 ``` #### 根据条件过滤并打印行 ```Go go 复制代码 ```bash awk '$3 > 50 {print $1, $3}' data.txt ``` 这会从 `data.txt` 文件中筛选出第三列大于 50 的行,并打印出第一列和第三列的内容。 ``` #### 使用自定义分隔符 ```Go go 复制代码 ```bash awk -F':' '{print $1, $3}' data.txt ``` 这会以 `:` 作为分隔符,打印 `data.txt` 文件中的第一列和第三列。 ``` #### 使用条件语句 ```Swift swift 复制代码 ```bash awk '{if ($2 > 50) print $1, "passed"; else print $1, "failed"}' scores.txt ``` 这会根据第二列的分数判断学生是否通过,并相应地输出结果。 ``` #### 计算总和、平均值等 ```Go go 复制代码 ```bash awk '{sum+=$3} END {print "Total:", sum, "Average:", sum/NR}' grades.txt ``` 这会计算 `grades.txt` 文件中第三列的总和和平均值,并在文件末尾输出结果。 > `NR` 是 "Number of Records" 的缩写,表示处理过程中已读取的记录(行)数量。它是一个内置变量,用于跟踪当前处理的行数。 ``` #### 在特定条件下修改数据 ```Swift swift 复制代码 ```bash awk '{if ($3 > 90) $4="A"; else if ($3 > 80) $4="B"; else $4="C"}1' marks.txt ``` 这会根据第三列的分数,在第四列中分配对应的等级。 ``` ## 查询域名 ip 地址 ```Shell bash 复制代码 dig +short baidu.com A ``` - `dig`:dig命令用于执行 DNS 查询操作。 - `+short`:这是一个 `dig` 命令的参数,它的作用是让 `dig` 命令输出更简洁,只显示查询结果的结果值,而不显示详细的查询信息。在查询结果中,仅输出记录的数据部分。 - `gnodetest.koolearn.com`:这是要查询的域名。 - `A`:这是查询的 DNS 记录类型,其中 `A` 记录用于将域名解析为 IPv4 地址。 ### 相关扩展: dig 工具 `dig`(Domain Information Groper)是一个用于查询 DNS(Domain Name System)信息的命令行工具。它通常用于查找域名的 DNS 记录、解析 IP 地址、查询域名服务器等操作。以下是一些常见的用法示例: #### 查询域名的 A 记录(IP 地址记录): ```Go go 复制代码 ```bash dig example.com ``` ``` #### 查询特定类型的 DNS 记录: ```Shell bash 复制代码 ```bash dig example.com MX # 查询 MX 记录 dig example.com TXT # 查询 TXT 记录 dig example.com NS # 查询 NS 记录 ``` ``` #### 查询指定 DNS 服务器的记录: ```Go go 复制代码 ```bash dig example.com @8.8.8.8 # 查询 example.com 在 Google DNS 上的记录 ``` ``` #### 反向 DNS 查找(将 IP 地址解析为域名): ```Go go 复制代码 ```bash dig -x 8.8.8.8 ``` ``` #### 显示详细的查询信息: ```Go go 复制代码 ```bash dig +trace example.com # 显示 DNS 查询的详细跟踪信息 ``` 相反 +short 可以显示更简洁的信息 ``` #### 查询特定类型的 DNS 记录,并输出为 JSON 格式: ```Go go 复制代码 ```bash dig example.com MX +json ``` ``` ## 升级 bash 1. **安装新版本的 Bash**: 首先,通过 Homebrew 安装新版本的 Bash。执行以下命令: ```Shell bash 复制代码 brew install bash ``` 1. **将新版本的 Bash 添加到可用的 Shell 列表中**: 安装完成后,使用以下命令将新版本的 Bash 添加到可用的 Shell 列表中: ```Shell bash 复制代码 sudo bash -c "echo /usr/local/bin/bash >> /etc/shells" ``` 这将把新版本的 Bash 路径添加到 `/etc/shells` 文件中,使其成为系统可识别的 Shell。 1. **更改默认 Shell**: 将默认 Shell 更改为新安装的 Bash ```Shell bash 复制代码 chsh -s /usr/local/bin/bash ``` 这将将默认 Shell 更改为新版本的 Bash。 1. **重启终端**: 退出当前终端窗口并重新打开一个新的终端窗口,以使更改生效。 1. **验证 Bash 版本**: 在新打开的终端窗口中,运行以下命令来验证 Bash 的版本: ```Shell bash 复制代码 bash --version ``` 确保输出显示的是你安装的新版本 Bash 的版本信息。 ## 查看机器信息 查看当前服务器的信息,包括 Linux 版本,你可以使用以下命令: #### 查看 Linux 版本和发行版信息: ```Shell bash 复制代码 cat /etc/os-release ``` 或者 ```Shell bash 复制代码 lsb_release -a ``` 结果示例 ```Shell bash 复制代码 NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7" ``` #### 查看内核版本: ```Shell bash 复制代码 uname -r # 打印全部系统信息 uname -a ``` #### 查看服务器硬件信息(CPU、内存等): ```Shell bash 复制代码 lshw ``` #### 查看服务器 CPU 信息: ```Shell bash 复制代码 cat /proc/cpuinfo ``` #### 查看服务器内存信息: ```Shell bash 复制代码 cat /proc/meminfo ``` #### 查看磁盘空间和分区信息: ```Shell bash 复制代码 df -h ``` 1. 查看网络接口信息: ```Shell bash 复制代码 ifconfig -a ``` #### 查看服务器启动时间和运行时间: ```Shell bash 复制代码 uptime ``` #### 要查看服务器的 CPU 核心数: 这个命令将输出有关 CPU 的详细信息,包括核心数、线程数等。 ```Shell bash 复制代码 lscpu ``` 这个命令将直接输出 CPU 的核心数。 ```Shell bash 复制代码 nproc ``` #### 使用 `nproc` 命令: ```Shell bash 复制代码 bashCopy code nproc ``` 这个命令将直接输出 CPU 的核心数。 #### 使用 `cat /proc/cpuinfo` 命令: ```Shell bash 复制代码 cat /proc/cpuinfo | grep processor | wc -l ``` 这个命令将输出 CPU 信息,然后通过 `grep` 和 `wc` 命令来计算核心数。 `wc -l` 是一个用于统计行数的命令。在 Linux 和类 Unix 系统中,`wc` 命令用于计算文件或输入中的行数、字数和字节数。 - `-l` 选项表示只统计行数。 所以,当你在命令行中使用 `wc -l` 时,它会统计输入中的行数并将结果显示出来。在查看 CPU 核心数的上下文中,它被用来计算 `/proc/cpuinfo` 文件中的处理器行数,从而得出 CPU 核心数。 ### 相关扩展: wc(word count) 命令 `wc` 是 "word count"(词汇统计)的缩写。虽然它的名称是 "word count",但它实际上可以用于统计文件或输入中的行数、字数和字节数,而不仅限于词汇。 - **统计文件的行数**:`wc -l file.txt`。这条命令会输出 `file.txt` 文件的行数。 - **统计文件的字数**:`wc -w file.txt`。这条命令会输出 `file.txt` 文件的字数。 - **统计文件的字节数**:`wc -c file.txt`。这条命令会输出 `file.txt` 文件的字节数。 - **统计文件的最长行的长度**:`wc -L file.txt`。这条命令会输出 `file.txt` 文件中最长行的长度。 如果你不指定任何选项,那么 `wc` 命令将输出三个统计结果:行数、字数和字节数: ```Shell bash 复制代码 wc file.txt ``` 你也可以同时指定多个选项,例如 `wc -lw file.txt` 会同时输出行数和字数。 ## vim 编辑器快捷键 Vim 是一个强大的文本编辑器,掌握下面这些快捷键和命令可以让你更高效地进行文本编辑。以下是一些常用的 Vim 快捷操作: > vim 快捷键与我们计算机系统的快捷键是不一样的,例如撤销操作,我们首先想到的是 ctrl+z,vim是 u 键,大家首先要了解这一点才方便更好滴学习。 #### **基本移动和编辑命令:** 1. **移动光标:** - `h` - 左移 - `j` - 下移 - `k` - 上移 - `l` - 右移 1. **跳转:** - `w` - 向前跳一个单词 - `b` - 向后跳一个单词 - `0` - 行首 - `$` - 行尾 - `gg` - 文档开头 - `G` - 文档末尾 1. **复制、剪切和粘贴:** - `yy` - 复制当前行 - `dd` - 剪切当前行 - `p` - 粘贴 1. **撤销和重做:** - `u` - 撤销 - `Ctrl + r` - 重做 1. **查找和替换:** - `/pattern`:向前搜索指定模式。 - `?pattern`:向后搜索指定模式。 - `n`:跳转到下一个搜索结果。 - `N`:跳转到上一个搜索结果。 - `:s/old/new/g` - 替换单行所有匹配的字符串 - `:%s/old/new/g`:全局替换 `old` 为 `new`。 #### **模式和编辑命令:** 1. **插入模式:** - `i` - 在光标前插入 - `I` - 在行首插入 - `a` - 在光标后插入 - `A` - 在行尾插入 - `o` - 在当前行下插入新行 - `O` - 在当前行上插入新行 1. **可视模式:** 可视模式允许用户选择文本块以进行操作。在可视模式下,你可以使用键盘来选择文本,然后对所选择的文本执行各种操作,如复制、剪切、替换等。 - `v` - 字符可视模式 - `V` - 行可视模式 - `Ctrl + v` - 块可视模式 1. **命令模式:** - `:` - 进入命令模式,可以执行命令(例如保存、退出等) #### **文件操作:** 1. `:w` - 保存文件 2. `:q` - 退出 Vim 3. `:q!` - 强制退出 Vim,不保存修改 4. `:wq` - 保存并退出 #### **窗口分割:** 1. `:sp` - 横向分割窗口 2. `:vsp` - 纵向分割窗口 3. `Ctrl + w` 后跟方向键 - 在窗口之间切换 #### **多文件操作:** 1. `:e filename` - 打开新文件 2. `:bnext` - 切换到下一个缓冲区文件 3. `:bprev` - 切换到上一个缓冲区文件 #### **自动补全:** 1. `Ctrl + n` - 向下补全 2. `Ctrl + p` - 向上补全 #### **标记和跳转:** 1. `m` + 字母 - 创建标记 2. `'` + 字母 - 跳转到标记 3. ``` + 字母 - 跳转回上一个位置 #### **宏录制和重放:** 1. `q` + 字母 - 开始录制宏 2. `q` - 停止录制宏 3. `@` + 字母 - 重放宏 #### **折叠和展开:** 1. `zf` + 移动命令 - 创建折叠 2. `zo` - 展开折叠 3. `zc` - 折叠 4. `zR` - 展开所有折叠 未尽事项,可以使用 `:help` 命令在 Vim 中访问内置的帮助文档。 ## 如何在脚本内获取终端执行命令的目录 #### **使用 `pwd` 命令:** 在终端中直接运行 `pwd` 命令可以获取当前工作目录。 ```Shell bash 复制代码 pwd ``` #### **使用 `dirs` 命令:** `dirs` 命令会列出当前终端会话中的目录堆栈,第一行就是当前目录。 ```Shell bash 复制代码 dirs -l -p | head -n 1 ``` 1. `dirs`: 这是一个用于管理目录堆栈的内置命令。当你在终端中切换目录时,Bash 会将这些目录添加到堆栈中。 2. `-l`: 表示输出完整的目录路径。如果不使用 `-l` 选项,将只输出目录的名称而不包括路径。 3. `-p`: 表示输出的目录路径将包括所有的路径组成部分,而不是使用简化的路径。 4. `|`: 管道操作符,用于将一个命令的输出作为另一个命令的输入。 5. `head -n 1`: `head` 命令用于显示文本文件的前几行,默认显示前 10 行。 `-n 1` 选项表示只显示第一行。 `dirs -l -p | head -n 1` 的意思是: - 通过 `dirs` 命令获取目录堆栈中的所有目录路径,使用完整路径,不进行路径简化。 - 将获取的目录路径通过管道传递给 `head` 命令,只显示第一行,即当前目录。 ## 获取当前被执行脚本的所在目录 #### 使用 `dirname` 命令和 `$0` 变量: ```Shell bash 复制代码 script_dir=$(dirname "$0") echo "脚本所在目录:$script_dir" ``` - `$0`:这个特殊变量在 Bash 脚本中表示当前脚本的名称,包括路径。例如,如果脚本的完整路径是 `/home/user/myscript.sh`,那么`$0` 将包含这个完整路径。 - `dirname`:用于获取一个路径的目录部分,即去掉路径中的文件名部分。例如,`dirname /home/user/myscript.sh` 将返回 `/home/user`。 - `script_dir=$(dirname "$0")`:这行代码将获取当前脚本的完整路径(包括文件名),然后使用 `dirname` 命令提取出其中的目录部分,最终将这个目录路径存储在 `script_dir` 变量中。 ## 获取当前git仓库名称(从文件路径中提取文件名) 如果你有多个项目,需要将它们遍历处理进行处理,例如将它们推送到不同的新仓库,你需要获取每个本地仓库的仓库名称,以推送到远程的新仓库 在脚本中使用以下命令即可 ```Shell bash 复制代码 # 获取当前仓库名称 repo_url=$(git config --get remote.origin.url) repo_name=$(basename $repo_url .git) ``` `repo_url=$(git config --get remote.origin.url)` 这一行命令使用 git config 命令获取当前 Git 仓库的远程 origin 的 URL,并将其存储在变量 repo_url 中。remote.origin.url 是 Git 配置中用于存储远程仓库 URL 的键名。--get 标志用于获取配置值。 `repo_name=$(basename $repo_url .git)` 这一行命令使用 basename 命令从 repo_url 中提取仓库名称,并去掉了 .git 后缀。提取后的仓库名称存储在变量 repo_name 中。 ### 相关扩展 basename `basename` 是一个命令行工具,用于从文件路径中提取文件名部分。它的作用是获取一个文件的基本名称,通常用于从文件路径中获取文件名,而不包括路径或文件扩展名。 基本的用法是: ```Shell bash 复制代码 basename [路径] [后缀] ``` - `路径`:要提取文件名的路径字符串。 - `后缀`:可选参数,如果提供,将会去除文件名中的后缀。 以下是一些示例: 1. **基本用法**: ```Shell bash 复制代码 basename /path/to/file.txt ``` 输出:`file.txt` 这会返回文件路径 `/path/to/file.txt` 中的文件名 `file.txt`。 1. **去除后缀**: ```Shell bash 复制代码 basename /path/to/file.txt .txt ``` 输出:`file` `basename` 去除了文件名中的 `.txt` 后缀,返回了 `file`。 ## 总结 这篇文章旨在让大家能够快速查阅到自己想要的操作,文章会尽可能的全而详细地收录所有常用操作,并且会持续更新,与大家共勉,争取早日 shell 命令敲的飞起,节省下来的时间多和大家分享知识(手动狗头)~ 感谢你花费宝贵的时间阅读本文,如果本文给了你一点点帮助或者启发,还请三连支持一下,点赞、关注、收藏,作者会持续与大家分享更多干货。