Python Shell处理json文件

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
{
"status": "success",
"timestamp": "2025-07-21T10:00:00Z",
"data": [
{
"host": "server-01",
"metrics": {
"cpu": {
"usage": 35.6,
"cores": 4
},
"memory": {
"total": 32768,
"used": 16384,
"unit": "MB"
},
"disk": [
{
"mount": "/",
"total": 512000,
"used": 400000,
"unit": "MB"
}
],
"network": {
"eth0": {
"rx_bytes": 123456789,
"tx_bytes": 987654321
}
}
}
}
]
}

shell

1
2
cat /tmp/data.json | jq '.data[0].metrics.memory.total'
# 32768
1
2
cat /tmp/data.json | jq -r '.data[] | "\(.host): total memory = \(.metrics.memory.total) MB"'
# server-01: total memory = 32768 MB

Python

1
2
3
4
5
6
7
8
9
10
import json

# 读取 JSON 文件
with open('/tmp/data.json', 'r') as f:
data = json.load(f)

# 获取 memory total 的值
total_memory = data['data'][0]['metrics']['memory']['total']
print(total_memory)
# 32768

遍历所有主机

1
2
3
4
5
for host_data in data['data']:
host = host_data.get('host')
total_mem = host_data['metrics']['memory']['total']
print(f"{host}: total memory = {total_mem} MB")
# server-01: total memory = 32768 MB

psutil 模块

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
import psutil

# ---------- 内存信息 ----------
mem = psutil.virtual_memory()
print("🔹 内存信息")
print(f"总内存: {round(mem.total / (1024**3), 2)} GB")
print(f"已使用: {round(mem.used / (1024**3), 2)} GB")
print(f"可用: {round(mem.available / (1024**3), 2)} GB")
print(f"使用率: {mem.percent}%")
print()

# ---------- 磁盘信息 ----------
disk = psutil.disk_usage('/')
print("🔹 磁盘信息 (/ 分区)")
print(f"总容量: {round(disk.total / (1024**3), 2)} GB")
print(f"已使用: {round(disk.used / (1024**3), 2)} GB")
print(f"可用: {round(disk.free / (1024**3), 2)} GB")
print(f"使用率: {disk.percent}%")
print()

# ---------- CPU 信息 ----------
print("🔹 CPU 信息")
print(f"CPU 总核数(逻辑核): {psutil.cpu_count(logical=True)}")
print(f"CPU 总核数(物理核): {psutil.cpu_count(logical=False)}")

# CPU 总使用率(1秒平均)
cpu_percent_total = psutil.cpu_percent(interval=1)
print(f"CPU 当前总使用率: {cpu_percent_total:2f}%")

# 每个核心的使用率
import psutil

cpu_per_core = psutil.cpu_percent(interval=1, percpu=True)
print(type(cpu_per_core)) # <class 'list'>
print(cpu_per_core) # [5.1, 4.0]
for i, percent in enumerate(cpu_per_core): # enumerate 枚举,返回索引和值
print(f"CPU 核心 {i}: {percent}%")

🧠 模块作用
psutil(process and system utilities)用于获取系统运行的进程信息、CPU、内存、磁盘、网络等资源的使用情况,广泛用于监控脚本和性能分析。

功能 代码示例 说明
查看 CPU 信息 psutil.cpu_percent() 获取 CPU 使用率(默认是瞬时值)
多核 CPU psutil.cpu_percent(percpu=True) 获取每个 CPU 的使用率
CPU 核心数 psutil.cpu_count(logical=False) 获取物理核心数
内存信息 psutil.virtual_memory() 返回内存总量、已用、剩余等
交换内存 psutil.swap_memory() 获取交换分区使用情况
磁盘使用 psutil.disk_usage(‘/‘) 获取某个挂载点的磁盘使用情况
磁盘 IO psutil.disk_io_counters() 读取/写入字节数与次数
网络 IO psutil.net_io_counters() 网络传输字节和包数
网络接口 psutil.net_if_addrs() 获取每个网络接口的 IP 等信息
当前进程 psutil.Process() 获取当前进程的 CPU/内存等信息
所有进程 psutil.pids() / psutil.process_iter() 遍历所有 PID 并查看进程状态

shell 一些脚本片段

用户交互性例子

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
45

#!/bin/bash
# shellcheck disable=SC2162

echo "请输入一些选项(用空格分隔):" # echo "请输入一些选项(用空格分隔):"
read -r options # options是一个数组
PS3="请选择一个选项: " # PS3是一个变量,用于提示用户输入
select choice in $options "Exit"
do
if [ "$choice" = "Exit" ]; then
echo "退出程序"
break
elif [ -n "$choice" ]; then
echo "你选择了:$choice"
else
echo "无效选择,请输入有效编号!"
fi
done


# =======================

#!/bin/bash
PS3="请选择一个水果(输入编号): " # 自定义提示符
select fruit in 苹果 香蕉 橙子 退出
do
case $fruit in
苹果)
echo "你选择了苹果,价格:5元/斤"
;;
香蕉)
echo "你选择了香蕉,价格:3元/斤"
;;
橙子)
echo "你选择了橙子,价格:4元/斤"
;;
退出)
echo "退出程序"
break # 退出 select 循环
;;
*)
echo "无效选择,请输入 1 到 4 之间的编号!"
;;
esac
done

判断机器的系统类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
__main() {
read id1 id2 < <(grep '^ID' /etc/os-release | head -n 2 | awk -F= '{gsub(/"/,""); print $2}' | tr '[:upper:]' '[:lower:]' | tr '\n' ' ')

if [[ "$id1" == "$id2" ]]; then
echo "两者相等"
else
echo "错误:不相等. id1=$id1, id2=$id2"
exit 1
fi

}

bash<<<"$(declare -f __main | sed '$a __main')"

颜色输出

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
#!/bin/bash
out_success() {
echo -e "[\033[32mSuccess\033[0m] $1"
}
out_warning() {
echo -e "[\033[33mWarning\033[0m] $1"
}
out_error() {
echo -e "[ \033[35mError\033[0m ] $1"
}
out_info() {
echo -e "[ \033[36mInfo\033[0m ] $1"
}


__main() {

out_info "这是蓝色的"
out_success "这是绿色的"
out_warning "这是黄色的"
out_error "这是紫色的"
}

__main

Go 语言基础语法

Go 语言基础语法

1.GO 语言注释

1
2
3
4
5
// 单行注释
/*
多行
注释
*/

2.GO 语言变量

2.1 变量就是变化的量

定义变量:

1
2
3
4
5
6
7
8
package main
import "fmt"

func main() {

var name string = "zhangsan"
fmt.Println(name)
}

短变量声明: num := 100

1
2
3
4
5
6
fun main() {
num := 100
name := "zhangsan"
fmt.Println(num, name)
fmt.Printf("%T,%T", num, name) // %T 打印变量类型
}

变量的内存地址:

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main() {
var num int
num = 100
fmt.Printf("num:%d,内存地址:%p", num, &num) // &取地址符
num = 200
fmt.Printf("num:%d,内存地址:%p", num, &num) // 地址会刷新,但会保持一致
}

变量交换

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "fmt"

func main() {
var a,b int
a = 100
b = 200
a, b = b, a
fmt.Println(b, a)

}

变量的作用域

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import "fmt"

func test()(int, int){
return 100 200 // 调用test 就返回值 100 200
}
func main() {
// a, b = test()
a, _ = test() // 赋给_的值 都将被抛弃
fmt.Println(a)

}

2.2 常量

常量中的数据类型只能是: 布尔型、数字型(整数型,浮点数型和复数)和字符串类型。

不可改变的量

1
2
3
4
5
6
7
8
9
10
const identifier [type] = value

package main
func main(){
const URL string = "www.baidu.com" // const是常量的标识符 : 显示定义
const URL = "WWW.taobao.com" // 隐示定义、
const a,b,c = 3.14, "song", false // 多个定义
URL = "www.jd.com" // URL是不会被改变的,
}

iota (常量计数器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
"fmt"
)

func main() {
const (
// 一组常量里面,如果没有默认初始值,默认和上一行一致
a = iota // iota 默认等于0
b = iota
c = iota // 就算不给b,c赋值也是默认的 自动加1
d = "haha" // iota = 3
e
f = 100
g
h = iota
i
j
k
)
fmt.Println(a, b, c, d, e, f, g, h, i, j, k)
}
// 0 1 2 haha haha 100 100 7 8 9 10

sys模块

功能 作用 举例
sys.argv 获取命令行参数 sys.argv[1]
sys.exit() 退出程序 sys.exit(“错误退出”)
sys.stdout 标准输出流(可重定向) sys.stdout.write(“text\n”)
sys.stderr 标准错误输出流(用于报错) sys.stderr.write(“错误\n”)
sys.stdin 标准输入(代替 input()) sys.stdin.readline()
sys.platform 当前操作系统平台 ‘linux’, ‘win32’ 等
sys.path 模块搜索路径 sys.path.append(…)
sys.version Python 版本字符串 ‘3.11.4 (…)’
sys.getsizeof() 获取对象占用内存大小 sys.getsizeof([1,2,3])

shellcheck

shellcheck

静态分析工具

shellcheck disable=SC2317,SC2162

是用于禁用 ShellCheck 静态分析工具对特定规则(SC2317 和 SC2162)的警告的注释指令。

  • ShellCheck 是一个用于检查 Shell 脚本语法错误、潜在问题和代码风格的工具。
  • 它会根据预设的规则(如 SC2001、SC2162 等)提示代码中的风险或改进建议。
1
2
# shellcheck disable=SC2162
read -p "Enter name: " name # 忽略 SC2162 的警告

disable=SC2086

SC2086:双引号引用变量

1
2
3
4
5
# 错误写法(会触发 SC2086):
echo $var

# 正确写法:
echo "$var"

SC2155

SC2155:不要在声明和赋值中同时使用命令替换

1
2
3
4
5
6
# 错误写法(会触发 SC2155):
local file=$(ls -l)

# 正确写法:
local file
file=$(ls -l)

disable=SC1009

SC1009:if 等语句语法错误

1
2
3
4
5
6
7
8
# 错误写法(会触发 SC1009):
if [ "$x" = "1" ]
echo "x is 1"

# 正确写法:
if [ "$x" = "1" ]; then
echo "x is 1"
fi

容器逃逸,用宿主机环境

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

my_func() {
echo "当前运行环境:$(uname -a)"
echo "当前路径:$(pwd)"
echo "列出宿主机根目录:"
ls /
}

run_on_host() {
nsenter --mount=/host/proc/1/ns/mnt bash <<<"$(declare -f my_func | sed "\$a my_func")" # declare -f my_func —— 打印 my_func 函数定义。sed '$a my_func' —— 在函数定义最后一行追加一行 my_func,用于自动执行
}

run_on_host

nsenter 是 Linux 下的一个命令,可以进入其他进程的命名空间(namespace),比如:

  • –mount 表示进入挂载命名空间(即文件系统环境)

  • –pid 表示进入进程空间

  • –net 表示进入网络空间

等等……

这意味着你可以“变成另一个进程看到的世界”。

  • /host/proc/1/ns/mnt 是宿主机中 1 号进程的挂载命名空间文件

  • 容器内的 /proc/1/ns/mnt 是容器的命名空间

  • 通常容器里会把宿主机的 /proc 挂载到 /host/proc 下

  • 1 号进程 在宿主机上就是 init 进程,也就是整个系统的根命名空间

bash <<<”…” 是什么意思?

1
2
3
bash <<<"..."
==
echo "..." | bash

declare -f

表示把函数定义输出出来:

1
declare -f func1 func2 ...
1
2
3
4
my_func() {
echo "hello"
}
declare -f my_func

输出:

1
2
3
my_func() {
echo "hello"
}

sed “$a __main”

1
2
3
sed "\$a __main"
==
sed '$a __main'

在最后加上一行 **main,表示自动调用 **main 函数

Golang 项目工程结构

Golang 项目工程结构

配置好工作目录后,就可以编码开发了,在这之前,我们看下 go 的通用项目结构,这里的结构主要是源代码相应地资源文件存放目录结构。

1.1 gopath 目录

gopath 目录就是我们存储我们所编写源代码的目录。该目录下往往要有 3 个子目录:src,bin,pkg。

src —- 里面每一个子目录,就是一个包。包内是 Go 的源码文件

pkg —- 编译后生成的,包的目标文件

bin —- 生成的可执行文件。

1.2 第一个程序

.在 HOME/go 的目录下,(就是 GOPATH 目录里),创建一个目录叫 src,然后再该目录下创建一个文件夹叫 hello,在该目录下创建一个文件叫 helloworld.go,并双击打开,输入以下内容:

1
2
3
4
5
6
7
packge main

import "fmt"

func main() {
fmt.Println("Hello World")
}

2 . 执行 go 程序
方式一:

1
go run helloworld.go

方式二:

1
2
3
4
5
step1:打开终端:在任意文件路径下,运行:
go install hello

​也可以进入项目(应用包)的路径,然后运行:
go install

注意,在编译生成 go 程序的时,go 实际上会去两个地方找程序包:
GOROOT 下的 src 文件夹下,以及 GOPATH 下的 src 文件夹下。

在程序包里,自动找 main 包的 main 函数作为程序入口,然后进行编译。

step2:运行 go 程序
​ 在/home/go/bin/下(如果之前没有 bin 目录则会自动创建),会发现出现了一个 hello 的可执行文件,用如下命令运行:
​ ./hello

1.3 第一个程序的解释说明

3.2.1 package

  • 在同一个包下面的文件属于同一个工程文件,不用 import 包, 可以直接使用
  • 在同一个包下面的所有文件的 package 名,都是一样的
  • 在同一个包下面的文件 package 名都建议设为是该名目名,但也可以不是

3.2.2 import

  • import "fmt" 告诉 go 编译器这个程序需要使用fmt包的函数,fmt 包实现了格式化 IO(输入/输出)的函数
  • 可以是相对路径也可以是绝对路径,推荐使用绝对路径(起始于工程根目录)
  1. 点操作
    我们有时候会看到如下的方式导入包
1
2
3
import (
. "fmt"
)

点操作的含义就是这个包导入之后在你调用这个包的函数时,你可以省略前缀的包名,也就是前面你调用的 fmt.Println(“hello world”)可以省略的写成 Println(“hello world”)。

  1. 别名操作
    别名操作顾名思义我们可以把包命名成另一个我们用起来容易记忆的名字
1
2
3
import (
f "fmt"
)

别名操作的话调用包函数时前缀变成了我们的前缀,即 f.Println(“hello world”) 3. _操作
这个操作经常是让很多人费解的一个操作码,

1
2
3
4
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)

_ 操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的 init 函数。

3.2.3 main 包

main() , 是程勋运行的入口

Golang语言的下载安装

macOS 下载安装 Golang

下载安装包

1
2
3
4
5
6
7
8
9
10
打开官网:https://go.dev/dl/
找到适合 macOS 的安装包,比如:

Apple Silicon (M1/M2/M3):go1.xx.x.darwin-arm64.pkg

Intel 处理器(老款 Mac):go1.xx.x.darwin-amd64.pkg

uname -m # 查看架构

安装完成后,Go 会默认被安装到 /usr/local/go

配置变量环境

1
2
3
4
5
6
7
8
9
10
11
vim ~/.zshrc

export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
export GOPROXY=https://goproxy.cn,direct

source ~/.zshrc

go install golang.org/x/tools/gopls@latest
# gopls 是给编辑器(如 VS Code)用的,提供语法高亮、自动补全、跳转定义、智能提示等功能,让你写 Go 代码更高效。

Windows 下载安装 Golang

下载安装包

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
https://studygolang.com/dl
下载对应的系统安装包


放在D盘下的songshai目录下的env目录

创建一个GoWorks目录
创建三个工作的目录:bin,src,pkg

在环境变量设置工作路径
(系统变量)中新建:GOPATH和GOROOT
GOPATH:./GoWorks
GOROOT:./go
(如果GOPATH没有到D盘中):在用户变量中新建一个GOPATH地址一样

配置代理
go env -w GOPROXY=https://goproxy.cn,direct


vscode : ctrl +
在下面设置里找到setting 搜索 Go Path
点击“在settings.json中编辑”,然后在settings.json文件中设置"go.gopath": "D:\\songshai/environment/GoWorks",将路径替换为你的Go工作区的绝对路径

创建一个工作空间:save workspace
导入必要模块:go mod init test(自定义名字)
(在对应工作区下执行)

vscode:改语言
ctrl+shift+p
输入选择:Configure Display Language

go install golang.org/x/tools/gopls@latest
# gopls 是给编辑器(如 VS Code)用的,提供语法高亮、自动补全、跳转定义、智能提示等功能,让你写 Go 代码更高效。

Ubuntu&CentOS 下载安装 Golang

1
2
3
4
5
6
7
8
9
10
11
12
# 安装go 环境
wget https://go.dev/dl/go1.23.4.linux-amd64.tar.gz
tar -xzf go1.23.4.linux-amd64.tar.gz -C /usr/local/
vim ~/.profile
# 添加到最后一行
GOROOT=/usr/local/go
GOPATH=$HOME/go
GOPROXY=https://goproxy.cn,direct
PATH=$PATH:$GOROOT/bin:$GOPATH/bin
source ~/.profile
# 验证
go version
1
2
3

# 你可以一条命令拉全部依赖:
go mod tidy

C的IEEE754浮点数格式

float

IEEE754 浮点数格式
f = (-1)^s _ M _ 2^E

s 代表符号位,M 代表尾数,E 代表指数

第一步

1
2
3
4
5
6
7
8
// 浮点数举例
float f = 9.625; // 在内存的存储
整数:9 = 1001 // 对应二进制的存储
小数: 0.625 * 2 = 1.25 //一直乘2取整,一直到小数部分为0
0.25 * 2 = 0.5
0.5 * 2 = 1.0
// 看的是整数上的数字,所以是0.625=.101
1001.101

第二步

1
2
3
4
5
6
1001.101 = (-1)^0 * 1.001101 * 2^3
// 小数点向左移了3位 → 指数 = 3
s: 0 , M: 去掉整数1, 001101 , E :加上偏移127, 130
130 的二进制是:10000010
尾数部分(23 位)
0011010000000000000000 // 去掉整数1
符号位 指数位(8 位) 尾数位(23 位)
0 10000010 0011010000000000000000

double

IEEE 754 双精度(double)浮点数格式

名称 位数
符号位 1
指数位 11
尾数位 52
合计 64

第一步:

正数: 符号位=0

第二步:
转换二进制

1
9.625 = 1001.101 = 1.001101 * 2^3

第三步:
指数(带偏移)

  • 实际指数:3
  • double 的偏移是: 1023
1
2
存储指数 = 1023 + 3 = 1026
1026 的二进制是:10000000010

第四步:
尾数
标准化后的是 1.001101
->尾数位只要去掉 1. , 补齐 52 位,

1
0011010000000000000000000000000000000000000000000000

第五步:拼接完整的 64 位

1
2
3
符号位:0
指数位:10000000010
尾数位:0011010000000000000000000000000000000000000000000000

分为八组

1
01000000 00100011 01000000 00000000 00000000 00000000 00000000 00000000

C语言字符串乱码

UTF-8 万国码 中文占 3 个字节
GBK 中国区的编码 中文占 2 个字节
如果想要所有文字 需要都是 utf-8 的编码

1
2
3
4
5
6
7
8
#include <stdio.h>

int main() {
char* p = "我要努力学会C语言문자열\n";

printf("%s", p);
return 0;
}

C语言变量数据类型和输入输出

  1. 理解变量和常量的概念

  2. 掌握常见数据类型:int、float、char、double

  3. 学会使用 scanf 读取输入,printf 输出内容

  4. 编写一个简单的计算器程序(加法)进行练习

变量 和 常量

  • 变量: 用来存储程序中临时使用的数据,值可以变化
  • 常量: 用来存储程序中不可变的数据,值不可以变化,例如:3.14、100、’A’
1
2
3
4
int age = 25; //声明int类型变量age,值为25
const int age = 25; // 声明int类型常量age,值为25
float pi = 3.14; // 声明float类型变量pi,值为3.14
char grade = 'A'; // 声明char类型变量grade,值为'A'

| 类型 | 占内存(字节) | 说明 | 示例值 |
| —— | ————– | ————– | ———- | ——— |
| int | 4 | 整数类型 | 123, -45 |
| float | 4 | 小数(精度低) | 3.14, -0.1 |
| double | 8 | 小数 | (精度高) | 3.1415926 |
| char | 1 | 单个字符 | ‘A’, ‘z’ |

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

int main() {
// 变量 : 在内存重占用一行八个格子的位置:内存地址
char a; // 4个字节
int c; // 1个字节 8位
// 补码表示负数,符号位置不变 其他的0变1,1变0 ,结果加1
short c; // 可以存放两个字节的,16位
long long // 占8个字节
unsigned char a; // 表示第一位不再是表示符号了,他的表示范围也就变了
return 0;
}

浮点数

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

int main() {
// 浮点数
// float 类型的数据在内存中占4个字节,32位 有误差
float a ,b ;
a = 0.1;
b = 0.2;
printf("%f", a + b);

// double 不要误差就用double,但是需要大内存
}
1
2
3
4
5
6
7
8
int main() {
// 赋值运算符

float a;
a = 1.0;

}