shell area
资源
资源 | 组织 | 类型 |
---|---|---|
wangdoc |
Tips
sh/bash
-s: 类 unix 操作系统中用于运行带参数的 shell 脚本的命令。-s 选项用于指定脚本应该从标准输入而不是文件中读取其输入。
1 | wget -O - https://raw.githubusercontent.com/nektos/act/master/install.sh | sh -s - -b /usr/local/bin |
set
-
set -o errexit 或 set -e 表示如果任何命令的退出状态码非零(即命令执行失败),则立即退出脚本。这有助于在脚本中遇到错误时停止执行后续的命令。
-
set -o nounset 或 set -u 表示如果使用未定义的变量,则立即退出脚本。这有助于避免在脚本中使用未初始化的变量导致的错误。
-
set -o pipefail 表示如果管道中的任何命令失败,则整个管道的退出状态码将是失败。默认情况下,管道的退出状态码是最后一个命令的退出状态码。这有助于在管道中的任何命令失败时及时捕获错误。
-
set -x: 打开调试模式。在调试模式下,shell 会将执行的每个命令及其参数都打印出来,以便用户可以更好地了解脚本的执行过程和调试脚本中的错误。
log
颜色高亮输出,兼容 sh/bash.
[!TIP]
在 POSIX sh 中,可以使用 ANSI 转义序列来实现颜色高亮输出。ANSI 转义序列是一些特殊的字符序列,它们可以在输出中表示一些特殊的含义,如颜色、样式等等。具体来说,ANSI 转义序列以\033[
开头,后面跟着一些数字和字符,用于指定要应用的颜色或样式。例如,\033[31m
表示将文本颜色设置为红色,\033[1m
表示将文本加粗等等。
links:
info
1 | echo "---------------- Env echo ----------------" |
arch
1 |
|
if
变量匹配正则
1 | branch=xxx_release_v2 |
命令执行正确
1 | if curl -m 3 github.com ; then |
使用逻辑运算符 &&(和)和 ||(或)来组合多个条件
1 | if [ $var -gt 10 ] && [ $var -lt 20 ]; then |
-
n: 用于判断字符串是否非空,如果字符串的长度大于 0,则返回 true,否则返回 false。
-
z: 用于判断字符串是否为空,如果字符串的长度等于 0,则返回 true,否则返回 false。
全单词匹配,以单词开头或空格为分界
1 |
|
-
=~
:正则表达式匹配操作符,用于判断左侧的字符串是否与右侧的正则表达式匹配。 -
(^|[[:space:]])
:表示匹配字符串的开头或者一个空格字符。 -
$pattern
:表示要匹配的模式,即变量 $pattern 的值。 -
($|[[:space:]])
:表示匹配字符串的结尾或者一个空格字符。
function
-
$0: 获取当前脚本或函数的名称
-
$1: 获取第一个参数
shift
获取第二个参数后面的所有参数,可以使用 shift 命令来移动参数位置,然后使用 $@或 $ 来获取剩余的参数。
1 | print_args() { |
在这个函数中,shift 命令用于将第一个参数移动到 $1 中,将第二个参数移动到 $2 中,以此类推。然后,函数使用 $@来获取剩余的参数,并将它们作为一个单词列表输出。
例如,如果你调用 printargs 函数并传递 "hello"、“world"和"how"作为参数,它将打印出"The remaining arguments are: world how”。
返回值
函数可以使用 echo 命令来返回一个字符串。具体来说,echo 命令用于将一个或多个字符串输出到标准输出流中。如果需要将多个字符串连接起来返回,可以使用命令替换和引号来实现。
1 | concat() { |
在这个函数中,$1 和 $2 分别表示第一个和第二个参数。函数使用 $1 和 $2 将它们连接起来,并将结果存储在名为 result 的本地变量中。最后,函数使用 echo 命令将 result 的值输出到标准输出流中。
:= 和 :-
在 shell 中:=
和 :-
是 bash shell 中的变量赋值操作符。它们的作用是在变量未定义或为空时,给变量赋默认值。
-
:=
是在变量未定义或为空时赋值 -
:-
是在变量为空时赋值
get dir to script
获取执行路径到脚本的相对路径
1 | SCRIPT_DIR=$(dirname "$(readlink -f "$0")") |
使用当前执行路径和脚本所在路径计算相对路径
1 | RELATIVE_PATH=$(dirname "$0") |
使用脚本 $0
获取路径.
getopt
getopts 是 Bash shell 中用于解析命令行参数的工具。
处理多个参数值
如果处理多个参数值,可以使用一个循环来读取它们。例如
1 | while getopts "a:" opt; do |
在这个例子中,-a 选项后面可以跟多个参数值,每个值都会被循环读取并处理。
处理长选项
1 | OPTIONS=$(getopt -o a:b:c --long alpha:,beta:,gamma: -- "$@") |
处理必选参数
处理必选参数,可以在 getopts 循环外部检查它们是否存在。
1 | if [ -z "$1" ]; then |
在这个例子中,检查了是否存在必选参数 foo,如果不存在则退出脚本。
get filesystem type
获取文件系统类型
1 | filesystem=$(df -T . | awk 'NR==2 {print $2}') |
for
1 | # 查看当前文件属性 |
command and check
执行命令并检查是否执行成功
1 | # 执行失败设置错误退出码 |
here doc(EOF)
Shell 脚本中使用的两种特殊的输入重定向语法
-
‘EOF’: 使用单引号将 EOF 引起来可以防止文本中的变量扩展和命令替换
1 | cat <<-'EOF' > temp.sh |
-
-
: 允许使用 EOF 时内部进行缩进
1 | cat <<-EOF |
更多使用示例
1 | cat <<EOF | docker-compose up -f - |
array or map
map 访问
1 | declare -A patterns_map |
str to array
1 | input="[clash,devcontainer]" |
string operation boilerplate
常用的字符串运算符:
-
{string#pattern}
: 从字符串的开头开始匹配并删除最短的 pattern。 -
{string##pattern}
: 从字符串的开头开始匹配并删除最长的 pattern。 -
{string/old/new}
: 替换字符串中第一个匹配的 old 为 new。 -
{string//old/new}
: 替换字符串中所有匹配的 old 为 new。 -
{string/#pattern/new}
: 如果字符串以 pattern 开头,则用 new 替换。 -
{string/%pattern/new}
: 如果字符串以 pattern 结尾,则用 new 替换。
links:
${string//old/new}
全局替换匹配操作中的 //
表示全局替换,即将字符串中的所有匹配项都替换。/ 是用于分隔替换的模式
和替换字符串
的字符。
1 | echo ${string//,/ } |
${string/%pattern/new}
结尾匹配操作中的 %
是一个模式运算符,用于从字符串的末尾开始匹配并删除指定模式的内容
1 | # 删除后缀 |
envsubst
envsubst 用于文件变量替换
1 | apt install gettext-base |
1 | export username=test |
date
Linux 打印显示时间
1 | # 输出当前年月日 |
echo
-
-e: 启动转义
-
-n: 不追加换行
watch
1 | # 每个1s运行后面的命令 |
curl
-
-s/–silent: 静默,一旦发生错误,不会显示错误信息。不发生错误的话,会正常显示运行结果。
-
-w: 选项支持很多不同的格式占位符,以便可以输出 cURL 请求的各种指标。以下是常见的格式占位符:
- %{time_total}:请求总时间,包括传输和处理时间。
- %{time_namelookup}:DNS 解析时间。
- %{time_connect}:建立连接所花费的时间。
- %{time_appconnect}:SSL / TLS 握手和建立连接所花费的时间。
- %{time_pretransfer}:从请求发出到开始传输数据所花费的时间。
- %{time_starttransfer}:从请求发出到第一个字节接收到所花费的时间。
- %{speed_download}:下载速度,以字节 / 秒为单位。
- %{speed_upload}:上传速度,以字节 / 秒为单位。
- %{http_code}:HTTP 响应码。
- %{url_effective}:请求的 URL(包括任何重定向后的 URL)。
-
-d: --data-urlencode POST 方法传递数据,区别在于会自动将发送的数据进行 URL 编码。
- URL 编码:将特殊字符替换编码,如空格替换为 %20。
- @: 读取本地文件,请求,如 curl -d ‘@./data.txt’ https://wangchujiang.com/upload
-
-H: -H “头部信息” 传递多个头部信息
-
-m/–max-time: 设置最大传输时间 (s)
1 | # -s silent: 静默输出 |
sed
安装
-
MacOS 用户可以在 MacPorts 或 Homebrew 上找到 GNU sed。
-
在 Windows 上,你可以通过 Chocolatey 来 安装 GNU sed。
pattern space and hold space
pattern space
sed 一次只能处理一行。因为它没有可视化模式,所以会创建一个 模式空间 (pattern space),这是一个内存空间,其中包含来自输入流的当前行(删除了尾部的任何换行符)。填充模式空间后,sed 将执行你的指令。当命令执行完时,sed 将模式空间中的内容打印到输出流,默认是 标准输出,但是可以将输出重定向到文件,甚至使用 --in-place=.bak 选项重定向到同一文件。然后,循环从下一个输入行再次开始。
hold space
为了在遍历文件时提供一点灵活性,sed 还提供了 保留空间 (hold space)(有时也称为 保留缓冲区 (hold buffer)),即 sed 内存中为临时数据存储保留的空间。你可以将保留空间当作剪贴板,实际上,这正是本文所演示的内容:如何使用 sed 复制 / 剪切和粘贴。
常用说明
-n
-n: 禁用显示输出。
1 | sed -n -e '/three/h' example.txt |
h H d
1 | $ cat example.txt |
h: 以覆盖的方式复制到 hold space。
H: 以追加的方式复制匹配行到 hold space。
g: 获得 hold space 内容,并替代当前 pattern space 中的文本。
G: 获得 hold space 内容,并追加到当前 pattern space 文本的后面。
1 | # 复制、删除、粘贴 |
常用 sed 操作
这里总结了常用的 sed 使用模式样例。
-
a\ 在当前行下面插入文本。
-
i\ 在当前行上面插入文本。
-
c\ 把选定的行改为新的文本。
1 | # 删除#开头的行 |
reference
jq
json 操作命令。
1 | # 追加键值 |
apt
apt package grades.
1 | apt update && apt install --install-suggests --no-install-recommends xxx |
gzip/gunzip
[!CAUTION]
gzip 在 ubuntu/debian 使用 -d 解压存在重定向问题,建议使用 -dc 在保留原文件下解压.
1 | gzip -c linux_bin > linux.gz |
vi
-
/{xxx}: 搜索 xxx
-
:{line_number}: 转到指定行数
tree
-
-P pattern: <范本样式> 只显示符合范本样式的文件和目录名称。
-
-I pattern: Do not list files that match the given pattern.
1 | tree path/to/tree -I <pattern to ignore> |
parallel
常用选项:
-
::: 后面接参数
-
:::: 后面接文件
-
-j、–jobs 并行任务数
-
-N 每次输入的参数数量
1 | apt update && apt install parallel |
grep
-
-o
: 选项表示只输出匹配的部分 -
-E
: 选项表示使用扩展正则表达式 -
-P
: 选项表示使用 Perl 兼容的正则表达式(PCRE)进行匹配。PCRE 支持更多的正则表达式语法和功能,比传统的基本正则表达式更强大。
1 | # 获取每行最后一个字符串,`[^[:space:]]+` 表示匹配一个或多个非空白字符,`$` 表示匹配行尾。 |
dirname/realpath/readlink
-
dirname: 去除文件名中的非目录部分
-
realpath: 获取相对路径,比如
realpath --relative-to=src dest
用于获取src
到dest
的相对路径结果 -
readlink: 获取链接或规范文件名,比如
readlink -f src
用于获取src
绝对路径
$@
, $*
$@
和 $*
都是特殊变量,用于获取所有传递给脚本或函数的参数。它们之间的区别在于如何对待参数中的空格。
$@
将每个参数视为单独的单词,因此可以在引号中引用参数中的空格。
1 | # script.sh |
1 | ./script.sh arg1 "arg2 with spaces" arg3 |
那么在脚本中,$@将展开为:
1 | arg1 |
$*
将所有参数视为单个字符串,并在参数之间插入一个字符。默认情况下,这个字符是空格。如果使用相同的命令调用脚本,$*
将展开为:
1 | arg1 arg2 with spaces arg3 |
uname
uname 用于打印系统信息
-
-a, --all 按顺序打印全部信息,如果 -p 和 -i 的信息是未知,那么省略。
-
-s, --kernel-name 打印内核名称。
-
-n, --nodename 打印网络节点主机名称。
-
-r, --kernel-release 打印内核 release。
-
-v, --kernel-version 打印内核版本。
-
-m, --machine 打印机器名称。
-
-p, --processor 打印处理器名称。
-
-i, --hardware-platform 打印硬件平台名称。
-
-o, --operating-system 打印操作系统名称。
tee
tee 从标准输入读取数据并重定向到标准输出和文件
-
-a, --append 追加到文件中而不是覆盖。
-
-i, --ignore-interrupts 忽略中断信号(Ctrl+c 中断操作无效)。
1 | echo $USER=\(root\) NOPASSWD:ALL | tee /etc/sudoers.d/$USER |
systemctl
systemctl 命令 是系统服务管理器指令,它实际上将 service 和 chkconfig 这两个命令组合到一起。
1 | systemctl start nfs-server.service . # 启动nfs服务 |
彻底关闭防火墙:
1 | sudo systemctl status firewalld.service |
一般修改完服务配置需要重载
1 | sudo systemctl daemon-reload |
删除服务,服务文件通常位于 /etc/systemd/system/ 或 /usr/lib/systemd/system/ 目录下
1 | sudo rm /etc/systemd/system/[service-name] |
mktemp
mktemp 是一个在 Unix 或类 Unix 系统(如 Linux 或 MacOS)中使用的命令,用于创建一个临时目录。
-
mktemp 是一个命令行工具,用于创建一个临时文件或目录。
-
-d 选项告诉 mktemp 创建一个目录,而不是文件。
-
-t 选项用于指定临时文件或目录的模板字符串。
1 | # 创建一个名为 example.XXXXXX 的临时目录,其中 XXXXXX 是自动生成的随机字符。 |
tmux
tmux 是一个终端复用工具,它允许在一个终端窗口中同时运行多个终端会话。以下是 tmux 的一些常用命令和用法:
1 | apt-get install tmux |
创建新窗口
-
使用快捷键 Ctrl + b,然后按下 c 创建一个新窗口。
-
或者使用命令:
tmux new-window
切换窗口
-
使用快捷键 Ctrl + b,然后按下数字键 0 到 9 切换到对应的窗口。
-
或者使用命令:
tmux select-window -t <window-index>
滚动窗口
-
使用快捷键 Ctrl + b,然后按下
[
进入复制模式。 -
使用上下箭头或 Page Up/Page Down 键滚动。
-
按下 q 退出复制模式。
分割窗格
-
使用快捷键 Ctrl + b,然后按下
%
垂直分割当前窗格。 -
使用快捷键 Ctrl + b,然后按下 ` 水平分割当前窗格。
切换窗格
-
使用快捷键 Ctrl + b,然后按下方向键切换到相邻的窗格。
-
或者使用命令:
tmux select-pane -[UDLR]
, 其中,[UDLR] 表示上下左右方向。
退出 tmux 会话
-
使用快捷键 Ctrl + b,然后按下 d 将会话放入后台。
-
或者使用命令:
tmux detach-client
shfmt
shfmt 广泛使用的 shell 格式化工具
说明说明
1 | # 检查 |
getent
getent 是一个用于获取系统数据库中的条目的命令。它可以用于获取用户、组、主机等信息。通过指定不同的数据库类型,可以获取不同类型的条目。
要获取系统中所有用户的列表,可以使用以下命令:getent passwd
要获取系统中所有组的列表,可以使用以下命令:getent group
或 getent group <group_name> | cut -d: -f4 | tr ',' '\n'
tail
-
+<num>
: 从 num 行开始显示,如docker ps | tail +2
代表跳过第一行表头数据显示
head
-
-<num>
: 从头显示 num 行,如ps -ef | grep dockerd | head -1
代表从第一行显示一行
tr
将字符进行替换压缩和删除
1 | input="[clash,devcontainer]" |
find
1 | # 查找子文件夹下jobs和templates下yml后缀并用sed操作每个文件 |
ping
1 | ping -c 3 google.com |
update-alternatives
1 | # 列出所有可用的java |