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
2
3
4
5
6
7
echo "---------------- Env echo ----------------"
echo "it is $(date)"
echo "current path: ""$PWD"
echo "who is this: ""$(whoami)"
echo "who is this : ""$USER"
echo "pip3 version: ""$(pip3 --version)"
echo "distribution:$(. /etc/os-release;echo $ID$VERSION_ID)"

arch

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
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) msclock. All rights reserved.
# Licensed under the MIT License.
#-------------------------------------------------------------------------------------------------------------
#
#
# shellcheck disable=SC2034,SC2086
#
# Maintainer: msclock

# setup_arch set arch and suffix,
# fatal if architecture not supported.
find_arch() {
case ${ARCH:=$(uname -m)} in
amd64)
ARCH=amd64
SUFFIX=$(uname -s | tr '[:upper:]' '[:lower:]')-${ARCH}
;;
x86_64)
ARCH=amd64
SUFFIX=$(uname -s | tr '[:upper:]' '[:lower:]')-${ARCH}
;;
arm64)
ARCH=arm64
SUFFIX=-${ARCH}
;;
s390x)
ARCH=s390x
SUFFIX=-${ARCH}
;;
aarch64)
ARCH=arm64
SUFFIX=-${ARCH}
;;
arm*)
ARCH=arm
SUFFIX=-${ARCH}hf
;;
*)
fatal "unsupported architecture ${ARCH}"
;;
esac
}

if

变量匹配正则

1
2
3
4
branch=xxx_release_v2
if echo "$branch" | grep -q 'release'; then
echo "This is a release version."
fi

命令执行正确

1
2
3
4
5
6
7
8
if curl -m 3 github.com ; then
docker_hub=github.com ;
elif curl -m3 ghproxy.com/https://github.com ; then
docker_hub=ghproxy.com/https://github.com ;
else
echo "no docker registry" ;
exit -1 ;
fi

使用逻辑运算符 &&(和)和 ||(或)来组合多个条件

1
2
3
if [ $var -gt 10 ] && [ $var -lt 20 ]; then
echo "Variable is between 10 and 20"
fi
  • n: 用于判断字符串是否非空,如果字符串的长度大于 0,则返回 true,否则返回 false。

  • z: 用于判断字符串是否为空,如果字符串的长度等于 0,则返回 true,否则返回 false。

全单词匹配,以单词开头或空格为分界

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

version="Skip v1.0.0.beta tag creation in dry-run mode"
pattern="v1.0.0"

if [[ $version =~ (^|[[:space:]])$pattern($|[[:space:]]) ]]; then
echo "Match found"
else
echo "No match found"
fi
  • =~:正则表达式匹配操作符,用于判断左侧的字符串是否与右侧的正则表达式匹配。

  • (^|[[:space:]]):表示匹配字符串的开头或者一个空格字符。

  • $pattern:表示要匹配的模式,即变量 $pattern 的值。

  • ($|[[:space:]]):表示匹配字符串的结尾或者一个空格字符。

function

  • $0: 获取当前脚本或函数的名称

  • $1: 获取第一个参数

shift

获取第二个参数后面的所有参数,可以使用 shift 命令来移动参数位置,然后使用 $@或 $ 来获取剩余的参数。

1
2
3
4
print_args() {
shift
echo "The remaining arguments are: $@"
}

在这个函数中,shift 命令用于将第一个参数移动到 $1 中,将第二个参数移动到 $2 中,以此类推。然后,函数使用 $@来获取剩余的参数,并将它们作为一个单词列表输出。

例如,如果你调用 printargs 函数并传递 "hello"、“world"和"how"作为参数,它将打印出"The remaining arguments are: world how”。

返回值

函数可以使用 echo 命令来返回一个字符串。具体来说,echo 命令用于将一个或多个字符串输出到标准输出流中。如果需要将多个字符串连接起来返回,可以使用命令替换和引号来实现。

1
2
3
4
5
6
7
concat() {
local result="$1$2"
echo $result
}

result=$(concat "hello" "world")
echo "The result is: $result"

在这个函数中,$1 和 $2 分别表示第一个和第二个参数。函数使用 $1 和 $2 将它们连接起来,并将结果存储在名为 result 的本地变量中。最后,函数使用 echo 命令将 result 的值输出到标准输出流中。

:= 和 :-

在 shell 中:=:- 是 bash shell 中的变量赋值操作符。它们的作用是在变量未定义或为空时,给变量赋默认值。

  • := 是在变量未定义或为空时赋值

  • :- 是在变量为空时赋值

get dir to script

获取执行路径到脚本的相对路径

1
2
3
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
CURRENT_DIR=$(readlink -f ".")
RELATIVE_PATH=$(realpath --relative-to="$CURRENT_DIR" "$SCRIPT_DIR")

使用当前执行路径和脚本所在路径计算相对路径

1
RELATIVE_PATH=$(dirname "$0")

使用脚本 $0 获取路径.

getopt

getopts 是 Bash shell 中用于解析命令行参数的工具。

处理多个参数值

如果处理多个参数值,可以使用一个循环来读取它们。例如

1
2
3
4
5
6
7
8
9
10
11
12
while getopts "a:" opt; do
case $opt in
a)
for arg in "${OPTARG[@]}"; do
echo "Option a: $arg"
done
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done

在这个例子中,-a 选项后面可以跟多个参数值,每个值都会被循环读取并处理。

处理长选项

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
OPTIONS=$(getopt -o a:b:c --long alpha:,beta:,gamma: -- "$@")
eval set -- "$OPTIONS"
while true; do
case $1 in
-a|--alpha)
echo "Option alpha: $2"
shift 2
;;
-b|--beta)
echo "Option beta: $2"
shift 2
;;
-c|--gamma)
echo "Option gamma"
shift
;;
--)
shift
break
;;
*)
echo "Invalid option: $1" >&2
exit 1
;;
esac
done

处理必选参数

处理必选参数,可以在 getopts 循环外部检查它们是否存在。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if [ -z "$1" ]; then
echo "Missing required argument: foo" >&2
exit 1
fi

while getopts "a:" opt; do
case $opt in
a)
echo "Option a: $OPTARG"
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done

在这个例子中,检查了是否存在必选参数 foo,如果不存在则退出脚本。

get filesystem type

获取文件系统类型

1
2
3
4
5
6
7
8
9
10
11
12
filesystem=$(df -T . | awk 'NR==2 {print $2}')

if [[ $filesystem == "ext4" ]]; then
echo "The file system is ext4."
elif [[ $filesystem == "xfs" ]]; then
echo "The file system is xfs."
elif [[ $filesystem == "btrfs" ]]; then
echo "The file system is btrfs."
else
echo "Unknown file system and skip the code check because of the performance."
exit 0
fi

for

1
2
# 查看当前文件属性
for f in *; do file $f;done

command and check

执行命令并检查是否执行成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 执行失败设置错误退出码
status=0
pre-commit run --all-files || status=$?

# 执行命令
ls

# 判断命令执行结果
# 等同于 `if ls; then`
if [ $? -eq 0 ]; then
echo "命令执行成功"
else
echo "命令执行失败"
fi

if command -v cmake &>2 /dev/null; then
echo "cmake is working"
fi

here doc(EOF)

Shell 脚本中使用的两种特殊的输入重定向语法

  • ‘EOF’: 使用单引号将 EOF 引起来可以防止文本中的变量扩展和命令替换

1
2
3
cat <<-'EOF' > temp.sh
echo $VAR # $VAR 输出到文件时, 不会被环境变量替换
EOF
  • -: 允许使用 EOF 时内部进行缩进

1
2
3
cat <<-EOF
Hello World! # 前面的缩进在输出时,被忽略
EOF

更多使用示例

1
2
3
4
5
6
7
8
9
10
11
12
cat <<EOF | docker-compose up -f -
# ...
EOF

cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
# ...
EOF

# cat <<EOF > /etc/rancher/k3s/registries.yaml
cat > /etc/rancher/k3s/registries.yaml <<EOF
# ...
EOF

array or map

map 访问

1
2
3
4
5
6
7
declare -A patterns_map
patterns_map["category1"]="pattern1"
patterns_map["category2"]="pattern2"
patterns_map["category3"]="pattern3"

echo "Keys: ${!patterns_map[@]}" # keys are treated as separate elements
echo "Values: ${patterns_map[@]}" # values are treated as separate elements

str to array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
input="[clash,devcontainer]"

# 将字符串转换为数组
IFS=' ' read -r -a array <<< "$(echo $input | tr -d '[]' | tr ',' ' ')"

# 遍历输出数组元素
for element in "${array[@]}"; do
echo $element
done

IFS=' ' read -ra ry <<< "$(echo ${input//,/ } | tr -d '[]')"
for element in "${ry[@]}"; do
echo $element
done

array=$(echo $input | tr -d '[]' | tr ',' '\n')

readarray -t array <<< "$array"

for item in "${array[@]}"; do
echo "$item"
done

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
2
3
4
echo ${string//,/ }
# 将冒号替换为空格
echo ${string//: / }
echo ${string//;/\n}

${string/%pattern/new}

结尾匹配操作中的 % 是一个模式运算符,用于从字符串的末尾开始匹配并删除指定模式的内容

1
2
3
4
5
6
7
8
# 删除后缀
echo "${filename%.*}"
# 删除后缀**
echo "${word%**}"
# 删除后缀一个数字
echo "${number%[0-9]}"
# 删除末尾空格
echo "${sentence% }"

envsubst

envsubst 用于文件变量替换

1
apt install gettext-base
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export username=test
# here doc
cat <<EOF > a.bash
echo "pwd is ${PWD}"
echo "username is ${username}"
EOF

# envsubst
cat <<'EOF' | envsubst > b.bash
echo "pwd is ${PWD}"
echo "username is ${username}"
EOF

# 只替换 username
cat <<'EOF' | envsubst '${username}' >b.bash
echo "pwd is ${PWD}"
echo "username is ${username}"
EOF

date

Linux 打印显示时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 输出当前年月日
$ echo $(date +%F)
2022-10-21
# 输出当前时间(时分)
$ echo $(date +%R)
16:50
# 输出当前时间(时分秒)
$ echo $(date +%T)
16:51:18
# 输出星期
$ echo $(date +%A)
Friday
# 自定义输出年月日
$ echo $(date +%Y/%m/%d)
2022/10/21
# 自定义暑促胡时分秒
$ echo $(date +%H:%M:%S)
16:52:50
# 组合输出日期及时间
$ echo $(date +%F%n%T)
2022-10-21 16:53:26

echo

  • -e: 启动转义

  • -n: 不追加换行

watch

1
2
3
4
5
6
7
8
# 每个1s运行后面的命令
watch -n1 minikube kubectl -- get pod -A
# 每秒钟监视一次文件的变化,并在屏幕上显示文件的详细信息
watch -n 1 ls -l /path/to/file
# 每秒钟监视一次进程的状态
watch -n 1 ps aux
# 每秒钟监视一次网络连接
watch -n 1 netstat -an

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
2
3
4
5
# -s silent: 静默输出
# -w '\n%{http_code}\n': 添加换行格式化输出 http 的 code 码
# -d '{"log_verbose_level":1}': 请求输出
# —X POST: 请求 POST 方法
curl -s -w '\n%{http_code}\n' -d '{"log_verbose_level":1}' -X POST localhost:8000/v2/logging

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
2
3
4
$ cat example.txt
Line one
Line three
Line two

h: 以覆盖的方式复制到 hold space。

H: 以追加的方式复制匹配行到 hold space。

g: 获得 hold space 内容,并替代当前 pattern space 中的文本。

G: 获得 hold space 内容,并追加到当前 pattern space 文本的后面。

1
2
3
4
5
# 复制、删除、粘贴
$ sed -n -e '/three/h;/three/d;/two/G;p' example.txt
Line one
Line two
Line three

常用 sed 操作

这里总结了常用的 sed 使用模式样例。

  • a\ 在当前行下面插入文本。

  • i\ 在当前行上面插入文本。

  • c\ 把选定的行改为新的文本。

1
2
3
4
5
6
# 删除#开头的行
sed -i '/^#/ d' path/to/file
# 在第二行后插入一行 "default-runtime": "nvidia",
sed -i '2i\ "default-runtime": "nvidia",' /etc/docker/daemon.json
# bash\r: No such file or directory
sed $'s/\r$//' ./install.sh > ./install.Unix.sh

image.
image.

reference

jq

json 操作命令。

1
2
3
4
5
6
7
# 追加键值
echo {\"default-runtime\":\"nvidia\"} $(cat /etc/docker/daemon.json) | jq -s '.[0] + .[1]' | tee /etc/docker/daemon.json

# 条件操作
$ echo '2' | jq 'if . == 0 then "zero" elif . == 1 then "one" else "many" end'
"many"

apt

apt package grades.

1
apt update && apt install --install-suggests --no-install-recommends xxx

gzip/gunzip

[!CAUTION]
gzip 在 ubuntu/debian 使用 -d 解压存在重定向问题,建议使用 -dc 在保留原文件下解压.

1
2
gzip -c linux_bin > linux.gz
gzip -dc linux.gz > /usr/local/bin/linux_bin && rm 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
2
3
apt update && apt install parallel
parallel echo ::: a b c d e | tee a.txt
cat a.txt | parallel echo

grep

  • -o: 选项表示只输出匹配的部分

  • -E: 选项表示使用扩展正则表达式

  • -P: 选项表示使用 Perl 兼容的正则表达式(PCRE)进行匹配。PCRE 支持更多的正则表达式语法和功能,比传统的基本正则表达式更强大。

1
2
3
4
# 获取每行最后一个字符串,`[^[:space:]]+` 表示匹配一个或多个非空白字符,`$` 表示匹配行尾。
grep -oE '[^[:space:]]+$' file.txt
# 第一个字符串
grep -oE '^\S+' file.txt
  • dirname: 去除文件名中的非目录部分

  • realpath: 获取相对路径,比如 realpath --relative-to=src dest 用于获取 srcdest 的相对路径结果

  • readlink: 获取链接或规范文件名,比如 readlink -f src 用于获取 src 绝对路径

$@, $*

$@$* 都是特殊变量,用于获取所有传递给脚本或函数的参数。它们之间的区别在于如何对待参数中的空格。

$@ 将每个参数视为单独的单词,因此可以在引号中引用参数中的空格。

1
2
# script.sh
echo $@
1
./script.sh arg1 "arg2 with spaces" arg3

那么在脚本中,$@将展开为:

1
2
3
arg1
arg2 with spaces
arg3

$* 将所有参数视为单个字符串,并在参数之间插入一个字符。默认情况下,这个字符是空格。如果使用相同的命令调用脚本,$* 将展开为:

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
2
3
4
5
6
systemctl start nfs-server.service . # 启动nfs服务
systemctl enable nfs-server.service # 设置开机自启动
systemctl disable nfs-server.service # 停止开机自启动
systemctl status nfs-server.service # 查看服务当前状态
systemctl restart nfs-server.service # 重新启动某服务
systemctl list-units --type=service # 查看所有已启动的服务

彻底关闭防火墙:

1
2
3
sudo systemctl status firewalld.service
sudo systemctl stop firewalld.service
sudo systemctl disable firewalld.service

一般修改完服务配置需要重载

1
2
sudo systemctl daemon-reload
sudo systemctl restart kubelet

删除服务,服务文件通常位于 /etc/systemd/system/ 或 /usr/lib/systemd/system/ 目录下

1
2
3
4
5
sudo rm /etc/systemd/system/[service-name]
sudo rm /usr/lib/systemd/system/[service-name]
sudo systemctl daemon-reload
# 重置失败的单元
sudo systemctl reset-failed

mktemp

mktemp 是一个在 Unix 或类 Unix 系统(如 Linux 或 MacOS)中使用的命令,用于创建一个临时目录。

  • mktemp 是一个命令行工具,用于创建一个临时文件或目录。

  • -d 选项告诉 mktemp 创建一个目录,而不是文件。

  • -t 选项用于指定临时文件或目录的模板字符串。

1
2
# 创建一个名为 example.XXXXXX 的临时目录,其中 XXXXXX 是自动生成的随机字符。
mktemp -d -t example

tmux

tmux 是一个终端复用工具,它允许在一个终端窗口中同时运行多个终端会话。以下是 tmux 的一些常用命令和用法:

1
2
3
4
apt-get install tmux
yum install -y tmux
# 启动tmux会话
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
2
3
4
5
6
7
8
# 检查
docker run --rm -v $PWD:/src -w /src \
peterdavehello/shfmt \
sh -c "find . -type f \( -name \"*.sh\" -o -exec grep -lE \"^#\!/usr/bin/env (bash|sh)$\" {} \; \) | xargs shfmt -d -i 4"
# 更正
docker run --rm -v $PWD:/src -w /src \
peterdavehello/shfmt \
sh -c "find . -type f \( -name \"*.sh\" -o -exec grep -lE \"^#\!/usr/bin/env (bash|sh)$\" {} \; \) | xargs shfmt -d -i 4 -w"

getent

getent 是一个用于获取系统数据库中的条目的命令。它可以用于获取用户、组、主机等信息。通过指定不同的数据库类型,可以获取不同类型的条目。

要获取系统中所有用户的列表,可以使用以下命令:getent passwd

要获取系统中所有组的列表,可以使用以下命令:getent groupgetent group <group_name> | cut -d: -f4 | tr ',' '\n'

tail

  • +<num>: 从 num 行开始显示,如 docker ps | tail +2 代表跳过第一行表头数据显示

  • -<num>: 从头显示 num 行,如 ps -ef | grep dockerd | head -1 代表从第一行显示一行

tr

将字符进行替换压缩和删除

1
2
3
4
5
6
7
8
input="[clash,devcontainer]"
# 将字符串转换为数组
IFS=' ' read -ra array <<< "$(echo $input | tr -d '[]' | tr ',' ' ')"

# 遍历输出数组元素
for element in "${array[@]}"; do
echo $element
done

find

1
2
3
4
# 查找子文件夹下jobs和templates下yml后缀并用sed操作每个文件

# +: 一次性传给exec处理
find jobs templates -type f -name "*.yml" -exec sed -i "s@$_prefix.*@$_image_name@g" {} +

ping

1
ping -c 3 google.com

update-alternatives

1
2
3
4
5
6
7
8
9
10
# 列出所有可用的java
update-alternatives --list java
# 设置java为默认版本
update-alternatives --config java

update-alternatives --get-selections | grep java

# 设置llvm-cov为默认版本
update-alternatives --install /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-12 100