strace:Linux 系统调用排查利器

strace 是一个用于跟踪程序执行过程中系统调用的工具。它可以捕获程序与内核之间的交互,包括文件操作、进程控制、网络通信等,为开发者提供了深入了解程序行为的途径。通过 strace,你可以追踪到程序的每一步,查看系统调用的参数、返回值以及执行时间等关键信息。

在大多数 Linux 发行版中,strace 可以通过包管理工具进行安装。例如,在 Ubuntu 中,可以使用以下命令安装:

1
sudo apt-get install strace

用法

最基本的使用方式是在命令行中直接运行 strace 并指定待跟踪的命令。

1
strace ls

通过 -o 参数,你可以将 strace 的输出保存到文件中,以便后续分析。

1
strace -o output.txt ls

C++: std::decay_t

std::decay_t是一个类型转换工具,它接受一个类型,并将其转换为对应的”衰减类型”。所谓”衰减类型”指的是将某个类型以如下方式处理得到的类型:

  • 对于数组或函数类型,将其转换为指针类型。
  • 对于const/volatile限定符和引用类型,去除这些修饰符,得到被修饰类型本身。
  • 对于非上述类型,保持其原样。

以下是一个使用std::decay_t的例子:

1
2
3
4
5
6
7
8
9
10
11
12
#include <type_traits>

int main() {
int arr[3] = {1, 2, 3};
using type1 = std::decay_t<decltype(arr)>; // type1会被推导为int*

const volatile double& ref = 42.0;
using type2 = std::decay_t<decltype(ref)>; // type2会被推导为double

struct S {};
using type3 = std::decay_t<S>; // type3会被推导为S
}

tar 带密码压缩

比如对 app 目录进行压缩备份,带上密码,可以使用以下操作

1
tar -czvf - /app | openssl enc -aes-256-cbc -e > backup.tar.enc

解释一下以上命令:

  • tar -czvf - /app 将/app目录压缩成一个tar包,并将其输出到stdout。
  • openssl enc -aes-256-cbc -e 将stdin中的数据用AES-256-CBC算法进行加密,并将加密后的数据输出到stdout。
  • > backup.tar.enc 将stdout中的数据输出到backup.tar.enc文件中。

Shell 使用技巧

修改全局变量

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

my_var="initial value"

my_function() {
# 声明 my_var 为全局变量
declare -g my_var
my_var="new value"
}

echo "Before function call: my_var=$my_var"
my_function
echo "After function call: my_var=$my_var"

获取脚本所在绝对路径

脚本中涉及到一些路径的时候可以用绝对路径,这样可以再任意地方执行脚本。而不用 cd 到固定的目录

1
2
3
## 获取脚本自身所在目录绝对路径
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
echo "SCRIPT_DIR: $SCRIPT_DIR"

文件路径相关操作

1
2
3
4
5
6
7
8
# 获取目录名
DIR=$(dirname /path/file.txt) # /path

# 获取文件名
FILE=$(basename /path/file.txt) # file.txt

# 获取文件名,不带文件类型后缀
FILE_NAME=${FILE.*} # file

获取环境变量的值

1
2
# 获取环境变量 VAR 的值,如果没有则是 default_value
VAR="${VAR:-default_value}"

多行字符串换行符处理

某些 CI/CD 流程中可能会涉及到一些多行字符串,需要对换行符进行特殊处理,比如转义

1
2
3
4
5
6
7
8
9
# 原始字符串
original_string=" 这是一个包含
换行符的
字符串 "

# 将换行符替换成 ###
escape_string=$(echo "$original_string" | sed ':a;N;$!ba; s/\n/###/g')
echo $escape_string
# 会输出 "这是一个包含 ### 换行符的 ### 字符串"

后台执行程序

1
$(COMMOND &)

nohup COMMOND &