code-abyss 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +197 -0
- package/bin/install.js +193 -0
- package/bin/uninstall.js +42 -0
- package/config/AGENTS.md +247 -0
- package/config/CLAUDE.md +207 -0
- package/config/settings.example.json +27 -0
- package/output-styles/abyss-cultivator.md +399 -0
- package/package.json +41 -0
- package/skills/SKILL.md +115 -0
- package/skills/ai/SKILL.md +29 -0
- package/skills/ai/agent-dev.md +242 -0
- package/skills/ai/llm-security.md +288 -0
- package/skills/architecture/SKILL.md +41 -0
- package/skills/architecture/api-design.md +225 -0
- package/skills/architecture/caching.md +299 -0
- package/skills/architecture/cloud-native.md +285 -0
- package/skills/architecture/compliance.md +299 -0
- package/skills/architecture/data-security.md +184 -0
- package/skills/architecture/message-queue.md +329 -0
- package/skills/architecture/security-arch.md +210 -0
- package/skills/development/SKILL.md +43 -0
- package/skills/development/cpp.md +246 -0
- package/skills/development/go.md +323 -0
- package/skills/development/java.md +277 -0
- package/skills/development/python.md +288 -0
- package/skills/development/rust.md +313 -0
- package/skills/development/shell.md +313 -0
- package/skills/development/typescript.md +277 -0
- package/skills/devops/SKILL.md +36 -0
- package/skills/devops/cost-optimization.md +272 -0
- package/skills/devops/database.md +217 -0
- package/skills/devops/devsecops.md +198 -0
- package/skills/devops/git-workflow.md +181 -0
- package/skills/devops/observability.md +280 -0
- package/skills/devops/performance.md +273 -0
- package/skills/devops/testing.md +186 -0
- package/skills/gen-docs/SKILL.md +114 -0
- package/skills/gen-docs/scripts/doc_generator.py +491 -0
- package/skills/multi-agent/SKILL.md +268 -0
- package/skills/run_skill.py +88 -0
- package/skills/security/SKILL.md +51 -0
- package/skills/security/blue-team.md +379 -0
- package/skills/security/code-audit.md +265 -0
- package/skills/security/pentest.md +226 -0
- package/skills/security/red-team.md +321 -0
- package/skills/security/threat-intel.md +322 -0
- package/skills/security/vuln-research.md +369 -0
- package/skills/tests/README.md +225 -0
- package/skills/tests/SUMMARY.md +362 -0
- package/skills/tests/__init__.py +3 -0
- package/skills/tests/test_change_analyzer.py +558 -0
- package/skills/tests/test_doc_generator.py +538 -0
- package/skills/tests/test_module_scanner.py +376 -0
- package/skills/tests/test_quality_checker.py +516 -0
- package/skills/tests/test_security_scanner.py +426 -0
- package/skills/verify-change/SKILL.md +138 -0
- package/skills/verify-change/scripts/change_analyzer.py +529 -0
- package/skills/verify-module/SKILL.md +125 -0
- package/skills/verify-module/scripts/module_scanner.py +321 -0
- package/skills/verify-quality/SKILL.md +158 -0
- package/skills/verify-quality/scripts/quality_checker.py +481 -0
- package/skills/verify-security/SKILL.md +141 -0
- package/skills/verify-security/scripts/security_scanner.py +368 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust
|
|
3
|
+
description: Rust 开发。系统编程、内存安全、高性能、WebAssembly。当用户提到 Rust、Cargo、tokio、内存安全时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 📜 符箓秘典 · Rust
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## 基础语法
|
|
10
|
+
|
|
11
|
+
### 所有权系统
|
|
12
|
+
```rust
|
|
13
|
+
fn main() {
|
|
14
|
+
// 所有权转移
|
|
15
|
+
let s1 = String::from("hello");
|
|
16
|
+
let s2 = s1; // s1 不再有效
|
|
17
|
+
// println!("{}", s1); // 编译错误
|
|
18
|
+
|
|
19
|
+
// 借用
|
|
20
|
+
let s3 = String::from("world");
|
|
21
|
+
let len = calculate_length(&s3); // 借用
|
|
22
|
+
println!("{} has length {}", s3, len); // s3 仍有效
|
|
23
|
+
|
|
24
|
+
// 可变借用
|
|
25
|
+
let mut s4 = String::from("hello");
|
|
26
|
+
change(&mut s4);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fn calculate_length(s: &String) -> usize {
|
|
30
|
+
s.len()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fn change(s: &mut String) {
|
|
34
|
+
s.push_str(", world");
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 结构体与枚举
|
|
39
|
+
```rust
|
|
40
|
+
// 结构体
|
|
41
|
+
struct User {
|
|
42
|
+
name: String,
|
|
43
|
+
email: String,
|
|
44
|
+
active: bool,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
impl User {
|
|
48
|
+
fn new(name: String, email: String) -> Self {
|
|
49
|
+
Self { name, email, active: true }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fn deactivate(&mut self) {
|
|
53
|
+
self.active = false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 枚举
|
|
58
|
+
enum Result<T, E> {
|
|
59
|
+
Ok(T),
|
|
60
|
+
Err(E),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
enum Message {
|
|
64
|
+
Quit,
|
|
65
|
+
Move { x: i32, y: i32 },
|
|
66
|
+
Write(String),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 模式匹配
|
|
70
|
+
fn handle_message(msg: Message) {
|
|
71
|
+
match msg {
|
|
72
|
+
Message::Quit => println!("Quit"),
|
|
73
|
+
Message::Move { x, y } => println!("Move to ({}, {})", x, y),
|
|
74
|
+
Message::Write(text) => println!("Write: {}", text),
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 错误处理
|
|
80
|
+
```rust
|
|
81
|
+
use std::fs::File;
|
|
82
|
+
use std::io::{self, Read};
|
|
83
|
+
|
|
84
|
+
// Result 处理
|
|
85
|
+
fn read_file(path: &str) -> Result<String, io::Error> {
|
|
86
|
+
let mut file = File::open(path)?; // ? 操作符
|
|
87
|
+
let mut contents = String::new();
|
|
88
|
+
file.read_to_string(&mut contents)?;
|
|
89
|
+
Ok(contents)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 自定义错误
|
|
93
|
+
#[derive(Debug)]
|
|
94
|
+
enum AppError {
|
|
95
|
+
IoError(io::Error),
|
|
96
|
+
ParseError(String),
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
impl From<io::Error> for AppError {
|
|
100
|
+
fn from(err: io::Error) -> Self {
|
|
101
|
+
AppError::IoError(err)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 异步编程
|
|
107
|
+
|
|
108
|
+
### Tokio
|
|
109
|
+
```rust
|
|
110
|
+
use tokio;
|
|
111
|
+
|
|
112
|
+
#[tokio::main]
|
|
113
|
+
async fn main() {
|
|
114
|
+
let result = fetch_data().await;
|
|
115
|
+
println!("{:?}", result);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async fn fetch_data() -> Result<String, reqwest::Error> {
|
|
119
|
+
let resp = reqwest::get("https://api.example.com/data")
|
|
120
|
+
.await?
|
|
121
|
+
.text()
|
|
122
|
+
.await?;
|
|
123
|
+
Ok(resp)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 并发执行
|
|
127
|
+
async fn fetch_all(urls: Vec<&str>) -> Vec<String> {
|
|
128
|
+
let futures: Vec<_> = urls.iter()
|
|
129
|
+
.map(|url| fetch_url(url))
|
|
130
|
+
.collect();
|
|
131
|
+
|
|
132
|
+
futures::future::join_all(futures).await
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Channel
|
|
136
|
+
use tokio::sync::mpsc;
|
|
137
|
+
|
|
138
|
+
async fn channel_example() {
|
|
139
|
+
let (tx, mut rx) = mpsc::channel(32);
|
|
140
|
+
|
|
141
|
+
tokio::spawn(async move {
|
|
142
|
+
tx.send("hello").await.unwrap();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
while let Some(msg) = rx.recv().await {
|
|
146
|
+
println!("Received: {}", msg);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Web 框架
|
|
152
|
+
|
|
153
|
+
### Axum
|
|
154
|
+
```rust
|
|
155
|
+
use axum::{
|
|
156
|
+
routing::{get, post},
|
|
157
|
+
Router, Json, extract::Path,
|
|
158
|
+
};
|
|
159
|
+
use serde::{Deserialize, Serialize};
|
|
160
|
+
|
|
161
|
+
#[derive(Serialize, Deserialize)]
|
|
162
|
+
struct User {
|
|
163
|
+
id: u64,
|
|
164
|
+
name: String,
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async fn get_user(Path(id): Path<u64>) -> Json<User> {
|
|
168
|
+
Json(User { id, name: "Alice".to_string() })
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async fn create_user(Json(user): Json<User>) -> Json<User> {
|
|
172
|
+
Json(user)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
#[tokio::main]
|
|
176
|
+
async fn main() {
|
|
177
|
+
let app = Router::new()
|
|
178
|
+
.route("/users/:id", get(get_user))
|
|
179
|
+
.route("/users", post(create_user));
|
|
180
|
+
|
|
181
|
+
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
|
182
|
+
.serve(app.into_make_service())
|
|
183
|
+
.await
|
|
184
|
+
.unwrap();
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Actix-web
|
|
189
|
+
```rust
|
|
190
|
+
use actix_web::{web, App, HttpServer, HttpResponse};
|
|
191
|
+
|
|
192
|
+
async fn get_user(path: web::Path<u64>) -> HttpResponse {
|
|
193
|
+
HttpResponse::Ok().json(User { id: *path, name: "Alice".to_string() })
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
#[actix_web::main]
|
|
197
|
+
async fn main() -> std::io::Result<()> {
|
|
198
|
+
HttpServer::new(|| {
|
|
199
|
+
App::new()
|
|
200
|
+
.route("/users/{id}", web::get().to(get_user))
|
|
201
|
+
})
|
|
202
|
+
.bind("127.0.0.1:8080")?
|
|
203
|
+
.run()
|
|
204
|
+
.await
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## CLI 工具
|
|
209
|
+
|
|
210
|
+
### Clap
|
|
211
|
+
```rust
|
|
212
|
+
use clap::{Parser, Subcommand};
|
|
213
|
+
|
|
214
|
+
#[derive(Parser)]
|
|
215
|
+
#[command(name = "myapp")]
|
|
216
|
+
#[command(about = "My CLI application")]
|
|
217
|
+
struct Cli {
|
|
218
|
+
#[command(subcommand)]
|
|
219
|
+
command: Commands,
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
#[derive(Subcommand)]
|
|
223
|
+
enum Commands {
|
|
224
|
+
/// Start the server
|
|
225
|
+
Serve {
|
|
226
|
+
#[arg(short, long, default_value = "8080")]
|
|
227
|
+
port: u16,
|
|
228
|
+
},
|
|
229
|
+
/// Run a task
|
|
230
|
+
Run {
|
|
231
|
+
#[arg(short, long)]
|
|
232
|
+
name: String,
|
|
233
|
+
},
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
fn main() {
|
|
237
|
+
let cli = Cli::parse();
|
|
238
|
+
|
|
239
|
+
match cli.command {
|
|
240
|
+
Commands::Serve { port } => {
|
|
241
|
+
println!("Starting server on port {}", port);
|
|
242
|
+
}
|
|
243
|
+
Commands::Run { name } => {
|
|
244
|
+
println!("Running task: {}", name);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## 测试
|
|
251
|
+
|
|
252
|
+
```rust
|
|
253
|
+
#[cfg(test)]
|
|
254
|
+
mod tests {
|
|
255
|
+
use super::*;
|
|
256
|
+
|
|
257
|
+
#[test]
|
|
258
|
+
fn test_add() {
|
|
259
|
+
assert_eq!(add(1, 2), 3);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
#[test]
|
|
263
|
+
#[should_panic(expected = "divide by zero")]
|
|
264
|
+
fn test_divide_by_zero() {
|
|
265
|
+
divide(1, 0);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
#[tokio::test]
|
|
269
|
+
async fn test_async_fetch() {
|
|
270
|
+
let result = fetch_data().await;
|
|
271
|
+
assert!(result.is_ok());
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
cargo test
|
|
278
|
+
cargo test --release
|
|
279
|
+
cargo test -- --nocapture # 显示输出
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## 项目结构
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
myproject/
|
|
286
|
+
├── Cargo.toml
|
|
287
|
+
├── src/
|
|
288
|
+
│ ├── main.rs
|
|
289
|
+
│ ├── lib.rs
|
|
290
|
+
│ ├── models/
|
|
291
|
+
│ │ └── mod.rs
|
|
292
|
+
│ └── utils/
|
|
293
|
+
│ └── mod.rs
|
|
294
|
+
├── tests/
|
|
295
|
+
│ └── integration_test.rs
|
|
296
|
+
└── benches/
|
|
297
|
+
└── benchmark.rs
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## 常用库
|
|
301
|
+
|
|
302
|
+
| 库 | 用途 |
|
|
303
|
+
|---|------|
|
|
304
|
+
| tokio | 异步运行时 |
|
|
305
|
+
| axum/actix-web | Web 框架 |
|
|
306
|
+
| serde | 序列化 |
|
|
307
|
+
| reqwest | HTTP 客户端 |
|
|
308
|
+
| sqlx | 数据库 |
|
|
309
|
+
| clap | CLI |
|
|
310
|
+
| tracing | 日志 |
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shell
|
|
3
|
+
description: Shell 脚本开发。Bash、自动化、系统管理。当用户提到 Shell、Bash、脚本、自动化、Linux命令时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 📜 符箓秘典 · Shell
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## Bash 基础
|
|
10
|
+
|
|
11
|
+
### 变量与字符串
|
|
12
|
+
```bash
|
|
13
|
+
#!/bin/bash
|
|
14
|
+
|
|
15
|
+
# 变量
|
|
16
|
+
name="Alice"
|
|
17
|
+
age=25
|
|
18
|
+
readonly PI=3.14
|
|
19
|
+
|
|
20
|
+
# 字符串操作
|
|
21
|
+
str="Hello World"
|
|
22
|
+
echo ${#str} # 长度: 11
|
|
23
|
+
echo ${str:0:5} # 截取: Hello
|
|
24
|
+
echo ${str/World/Bash} # 替换: Hello Bash
|
|
25
|
+
echo ${str,,} # 小写: hello world
|
|
26
|
+
echo ${str^^} # 大写: HELLO WORLD
|
|
27
|
+
|
|
28
|
+
# 默认值
|
|
29
|
+
echo ${var:-default} # 如果 var 未设置,返回 default
|
|
30
|
+
echo ${var:=default} # 如果 var 未设置,设置并返回 default
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 数组
|
|
34
|
+
```bash
|
|
35
|
+
# 索引数组
|
|
36
|
+
arr=("a" "b" "c")
|
|
37
|
+
echo ${arr[0]} # 第一个元素
|
|
38
|
+
echo ${arr[@]} # 所有元素
|
|
39
|
+
echo ${#arr[@]} # 数组长度
|
|
40
|
+
|
|
41
|
+
# 遍历
|
|
42
|
+
for item in "${arr[@]}"; do
|
|
43
|
+
echo "$item"
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
# 关联数组 (Bash 4+)
|
|
47
|
+
declare -A map
|
|
48
|
+
map[name]="Alice"
|
|
49
|
+
map[age]=25
|
|
50
|
+
echo ${map[name]}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 条件判断
|
|
54
|
+
```bash
|
|
55
|
+
# 字符串比较
|
|
56
|
+
if [[ "$str1" == "$str2" ]]; then
|
|
57
|
+
echo "Equal"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# 数值比较
|
|
61
|
+
if [[ $a -eq $b ]]; then echo "Equal"; fi
|
|
62
|
+
if [[ $a -lt $b ]]; then echo "Less"; fi
|
|
63
|
+
if [[ $a -gt $b ]]; then echo "Greater"; fi
|
|
64
|
+
|
|
65
|
+
# 文件测试
|
|
66
|
+
if [[ -f "$file" ]]; then echo "File exists"; fi
|
|
67
|
+
if [[ -d "$dir" ]]; then echo "Directory exists"; fi
|
|
68
|
+
if [[ -r "$file" ]]; then echo "Readable"; fi
|
|
69
|
+
if [[ -w "$file" ]]; then echo "Writable"; fi
|
|
70
|
+
if [[ -x "$file" ]]; then echo "Executable"; fi
|
|
71
|
+
|
|
72
|
+
# 逻辑运算
|
|
73
|
+
if [[ $a -gt 0 && $b -gt 0 ]]; then echo "Both positive"; fi
|
|
74
|
+
if [[ $a -gt 0 || $b -gt 0 ]]; then echo "At least one positive"; fi
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 循环
|
|
78
|
+
```bash
|
|
79
|
+
# for 循环
|
|
80
|
+
for i in {1..5}; do
|
|
81
|
+
echo $i
|
|
82
|
+
done
|
|
83
|
+
|
|
84
|
+
for file in *.txt; do
|
|
85
|
+
echo "Processing $file"
|
|
86
|
+
done
|
|
87
|
+
|
|
88
|
+
# while 循环
|
|
89
|
+
while read -r line; do
|
|
90
|
+
echo "$line"
|
|
91
|
+
done < file.txt
|
|
92
|
+
|
|
93
|
+
# until 循环
|
|
94
|
+
count=0
|
|
95
|
+
until [[ $count -ge 5 ]]; do
|
|
96
|
+
echo $count
|
|
97
|
+
((count++))
|
|
98
|
+
done
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 函数
|
|
102
|
+
```bash
|
|
103
|
+
# 定义函数
|
|
104
|
+
greet() {
|
|
105
|
+
local name="$1"
|
|
106
|
+
echo "Hello, $name!"
|
|
107
|
+
return 0
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# 调用
|
|
111
|
+
greet "Alice"
|
|
112
|
+
result=$? # 获取返回值
|
|
113
|
+
|
|
114
|
+
# 返回字符串
|
|
115
|
+
get_date() {
|
|
116
|
+
echo "$(date +%Y-%m-%d)"
|
|
117
|
+
}
|
|
118
|
+
today=$(get_date)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## 实用脚本模板
|
|
122
|
+
|
|
123
|
+
### 带参数的脚本
|
|
124
|
+
```bash
|
|
125
|
+
#!/bin/bash
|
|
126
|
+
set -euo pipefail
|
|
127
|
+
|
|
128
|
+
usage() {
|
|
129
|
+
cat <<EOF
|
|
130
|
+
Usage: $(basename "$0") [OPTIONS] <input>
|
|
131
|
+
|
|
132
|
+
Options:
|
|
133
|
+
-o, --output FILE Output file
|
|
134
|
+
-v, --verbose Verbose mode
|
|
135
|
+
-h, --help Show this help
|
|
136
|
+
EOF
|
|
137
|
+
exit 1
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
# 默认值
|
|
141
|
+
OUTPUT=""
|
|
142
|
+
VERBOSE=false
|
|
143
|
+
|
|
144
|
+
# 解析参数
|
|
145
|
+
while [[ $# -gt 0 ]]; do
|
|
146
|
+
case "$1" in
|
|
147
|
+
-o|--output)
|
|
148
|
+
OUTPUT="$2"
|
|
149
|
+
shift 2
|
|
150
|
+
;;
|
|
151
|
+
-v|--verbose)
|
|
152
|
+
VERBOSE=true
|
|
153
|
+
shift
|
|
154
|
+
;;
|
|
155
|
+
-h|--help)
|
|
156
|
+
usage
|
|
157
|
+
;;
|
|
158
|
+
-*)
|
|
159
|
+
echo "Unknown option: $1"
|
|
160
|
+
usage
|
|
161
|
+
;;
|
|
162
|
+
*)
|
|
163
|
+
INPUT="$1"
|
|
164
|
+
shift
|
|
165
|
+
;;
|
|
166
|
+
esac
|
|
167
|
+
done
|
|
168
|
+
|
|
169
|
+
# 检查必需参数
|
|
170
|
+
if [[ -z "${INPUT:-}" ]]; then
|
|
171
|
+
echo "Error: Input is required"
|
|
172
|
+
usage
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# 主逻辑
|
|
176
|
+
main() {
|
|
177
|
+
if $VERBOSE; then
|
|
178
|
+
echo "Processing $INPUT..."
|
|
179
|
+
fi
|
|
180
|
+
# 处理逻辑
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
main
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 日志函数
|
|
187
|
+
```bash
|
|
188
|
+
#!/bin/bash
|
|
189
|
+
|
|
190
|
+
# 颜色定义
|
|
191
|
+
RED='\033[0;31m'
|
|
192
|
+
GREEN='\033[0;32m'
|
|
193
|
+
YELLOW='\033[1;33m'
|
|
194
|
+
NC='\033[0m'
|
|
195
|
+
|
|
196
|
+
log_info() {
|
|
197
|
+
echo -e "${GREEN}[INFO]${NC} $1"
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
log_warn() {
|
|
201
|
+
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
log_error() {
|
|
205
|
+
echo -e "${RED}[ERROR]${NC} $1" >&2
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
die() {
|
|
209
|
+
log_error "$1"
|
|
210
|
+
exit 1
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### 错误处理
|
|
215
|
+
```bash
|
|
216
|
+
#!/bin/bash
|
|
217
|
+
set -euo pipefail
|
|
218
|
+
|
|
219
|
+
# 错误处理
|
|
220
|
+
trap 'echo "Error on line $LINENO"; exit 1' ERR
|
|
221
|
+
|
|
222
|
+
# 清理函数
|
|
223
|
+
cleanup() {
|
|
224
|
+
rm -f "$TEMP_FILE"
|
|
225
|
+
}
|
|
226
|
+
trap cleanup EXIT
|
|
227
|
+
|
|
228
|
+
TEMP_FILE=$(mktemp)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## 常用命令组合
|
|
232
|
+
|
|
233
|
+
### 文本处理
|
|
234
|
+
```bash
|
|
235
|
+
# grep - 搜索
|
|
236
|
+
grep -r "pattern" .
|
|
237
|
+
grep -v "exclude" # 排除
|
|
238
|
+
grep -i "case insensitive" # 忽略大小写
|
|
239
|
+
grep -E "regex" # 正则
|
|
240
|
+
|
|
241
|
+
# sed - 替换
|
|
242
|
+
sed 's/old/new/g' file
|
|
243
|
+
sed -i 's/old/new/g' file # 原地修改
|
|
244
|
+
sed -n '10,20p' file # 打印行
|
|
245
|
+
|
|
246
|
+
# awk - 处理
|
|
247
|
+
awk '{print $1}' file # 第一列
|
|
248
|
+
awk -F: '{print $1}' /etc/passwd
|
|
249
|
+
awk 'NR>1 {sum+=$1} END {print sum}' file
|
|
250
|
+
|
|
251
|
+
# 组合
|
|
252
|
+
cat file | grep "pattern" | awk '{print $2}' | sort | uniq -c
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### 文件操作
|
|
256
|
+
```bash
|
|
257
|
+
# 查找
|
|
258
|
+
find . -name "*.txt"
|
|
259
|
+
find . -type f -mtime -7 # 7天内修改
|
|
260
|
+
find . -size +100M # 大于100M
|
|
261
|
+
find . -name "*.log" -exec rm {} \;
|
|
262
|
+
|
|
263
|
+
# 批量重命名
|
|
264
|
+
for f in *.txt; do
|
|
265
|
+
mv "$f" "${f%.txt}.md"
|
|
266
|
+
done
|
|
267
|
+
|
|
268
|
+
# 批量处理
|
|
269
|
+
find . -name "*.py" | xargs grep "TODO"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### 网络
|
|
273
|
+
```bash
|
|
274
|
+
# curl
|
|
275
|
+
curl -s https://api.example.com/data
|
|
276
|
+
curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' URL
|
|
277
|
+
curl -o output.file URL
|
|
278
|
+
|
|
279
|
+
# 端口检查
|
|
280
|
+
nc -zv host 80
|
|
281
|
+
ss -tulpn | grep :80
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## 最佳实践
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
#!/bin/bash
|
|
288
|
+
# 1. 使用 set 选项
|
|
289
|
+
set -euo pipefail
|
|
290
|
+
|
|
291
|
+
# 2. 引用变量
|
|
292
|
+
echo "$variable"
|
|
293
|
+
|
|
294
|
+
# 3. 使用 [[ ]] 而非 [ ]
|
|
295
|
+
if [[ -f "$file" ]]; then
|
|
296
|
+
|
|
297
|
+
# 4. 使用 $() 而非反引号
|
|
298
|
+
result=$(command)
|
|
299
|
+
|
|
300
|
+
# 5. 使用 local 声明局部变量
|
|
301
|
+
func() {
|
|
302
|
+
local var="value"
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
# 6. 检查命令是否存在
|
|
306
|
+
command -v git &>/dev/null || die "git not found"
|
|
307
|
+
|
|
308
|
+
# 7. 使用 shellcheck 检查
|
|
309
|
+
# shellcheck script.sh
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|