五一小长假快乐!
Go flag库
在 Go 语言中,flag
是一个用于解析命令行参数的标准库。通过这个库,你可以很方便地从命令行中获取用户传入的参数,比如字符串、整数、布尔值等。
主要用途:
处理命令行参数,例如:
go run main.go -name=Tom -age=25 -debug=true
基本使用示例:
package main
import (
"flag"
"fmt"
)
func main() {
// 定义命令行参数
name := flag.String("name", "default", "请输入用户名")
age := flag.Int("age", 18, "请输入年龄")
debug := flag.Bool("debug", false, "是否开启调试模式")
// 解析命令行参数
flag.Parse()
fmt.Println("name:", *name)
fmt.Println("age:", *age)
fmt.Println("debug:", *debug)
}
常用函数:
函数 | 用途 |
---|---|
flag.String(name, default, usage) | 定义字符串参数 |
flag.Int(name, default, usage) | 定义整数参数 |
flag.Bool(name, default, usage) | 定义布尔参数 |
flag.Parse() | 开始解析命令行参数 |
flag.Args() | 获取非 flag 的参数 |
flag.NArg() | 获取非 flag 参数个数 |
需要注意,flag
默认只支持 -key=value
或 -key value
的形式,不支持 --key
的双横线写法(这在某些 CLI 工具中是常见的)。
使用上面的写法获取到的变量是一个指针,所以在访问的时候如果要访问对应的值需要在变量之前加一个*号
如果想要直接得到变量也可以是用下面这种写法
var name string
flag.StringVar(&name, "name", "default", "请输入用户名")
这种写法是自己定义一个变量,然后将它的地址传进去
flag
后面的提示文字(也叫 usage 或说明文本)会在以下几种情况下自动显示:
1. 用户执行程序时传入了 h
或 -help
这是最常见的触发方式,flag
包会自动帮你注册 -h
和 --help
参数,触发时会显示所有参数的说明信息。例如:
go run main.go -h
输出会像这样:
Usage of /tmp/go-build.../main:
-age int
请输入年龄 (default 18)
-debug
是否开启调试模式 (default false)
-name string
请输入用户名 (default "default")
2. 程序中手动调用 flag.Usage()
你可以在代码里手动触发帮助信息显示,例如参数验证失败时:
if *name == "" {
fmt.Println("name 参数不能为空")
flag.Usage()
os.Exit(1)
}
3. 覆盖默认的帮助输出内容(可选)
你也可以自定义 flag.Usage
的行为,比如美化输出:
flag.Usage = func() {
fmt.Println("用法说明:")
fmt.Println(" -name string 请输入用户名 (默认值:default)")
fmt.Println(" -age int 请输入年龄 (默认值:18)")
fmt.Println(" -debug 是否开启调试模式 (默认值:false)")
}
总结一下:
方式 | 是否自动显示帮助信息 |
---|---|
运行时使用 -h 或 --help | ✅ 自动显示 |
手动调用 flag.Usage() | ✅ 手动触发 |
用户没有传必要参数 | ❌ 不会自动显示(需要你手动判断并触发) |
Bash 脚本中的if...then...fi
在 Bash 脚本中,if...then...fi
是最基础也是最常用的条件语句结构,类似于其他语言中的 if...else
结构。
🧱 基本语法格式
if 条件
then
命令1
命令2
fi
✅ 示例:
if [ -f /etc/passwd ]
then
echo "文件存在"
fi
这个例子判断 /etc/passwd 是否存在并且是个普通文件。
✨ 加上 else 的格式:
if 条件
then
命令1
else
命令2
fi
示例:
if [ "$USER" = "root" ]
then
echo "你是超级用户"
else
echo "你不是 root 用户"
fi
🌈 多条件:if...elif...else...fi
if 条件1
then
命令1
elif 条件2
then
命令2
else
命令3
fi
示例:
if [ "$1" = "start" ]
then
echo "开始服务"
elif [ "$1" = "stop" ]
then
echo "停止服务"
else
echo "未知命令"
fi
🧠 条件表达式说明(最常用):
表达式 | 含义 |
---|---|
[ -f FILE ] | 文件存在且是普通文件 |
[ -d DIR ] | 目录存在 |
[ -z STRING ] | 字符串长度为 0 |
[ STRING1 = STRING2 ] | 两个字符串相等 |
[ NUM1 -eq NUM2 ] | 两个整数相等 |
[ NUM1 -lt NUM2 ] | NUM1 小于 NUM2 |
[ 条件 ] && [ 条件 ] | 多个条件 "并且" |
❗注意事项:
- 方括号两边一定要留空格,如
[ "$USER" = "root" ]
(否则报错) fi
是if
的结束标志(fi
是if
反过来)
🔧 小脚本示例:
#!/bin/bash
read -p "请输入一个数字: " num
if [ "$num" -gt 100 ]; then
echo "大于 100"
elif [ "$num" -eq 100 ]; then
echo "等于 100"
else
echo "小于 100"
fi
grep介绍
grep
是 Linux 系统中非常强大且常用的命令行工具,用于在文件中搜索指定的字符串或正则表达式。其名称来自 "global regular expression print",意思是全局正则表达式打印。
基本语法:
grep [选项] '模式' 文件名
常用选项:
选项 | 说明 |
---|---|
-i | 忽略大小写 |
-v | 反向匹配,显示不包含匹配内容的行 |
-r 或 -R | 递归搜索目录中的所有文件 |
-n | 显示匹配行的行号 |
-l | 只列出包含匹配内容的文件名 |
-c | 统计匹配的行数 |
--color=auto | 高亮显示匹配的部分(大多数 Linux 发行版默认启用) |
使用示例:
在文件中查找字符串
grep "hello" file.txt
查找
file.txt
文件中包含 "hello" 的行。忽略大小写
grep -i "hello" file.txt
查找不包含某字符串的行
grep -v "error" log.txt
递归查找目录中匹配内容
grep -r "main" ./src
查找支持正则表达式
grep "^start" file.txt
匹配以 "start" 开头的行。
小技巧:
可以与
pipe
(|
) 命令结合使用,从其他命令的输出中筛选信息:dmesg | grep usb
- 与正则表达式配合,处理文本非常灵活。
grep -q
grep -q
是 grep
命令的一个非常实用的选项,意思是 安静模式(quiet / silent),它不会输出任何匹配结果,只通过返回码(退出状态码)来表示是否匹配成功。
✅ 功能说明:
- 当使用
q
选项时,grep
不会在终端显示任何匹配的文本。 - 它仅通过退出码来判断是否有匹配行。
🔢 退出状态码说明:
退出码 | 含义 |
---|---|
0 | 找到匹配项 |
1 | 未找到匹配项 |
2 | 出现错误(如文件不存在等) |
🧪 使用示例:
判断一个文件是否包含某个字符串:
if grep -q "error" log.txt; then echo "日志中包含错误" else echo "日志中未发现错误" fi
配合
&&
或||
使用:grep -q "success" result.txt && echo "任务成功" grep -q "fail" result.txt || echo "任务未失败"
Cookies存放token
使用 Cookies 存储和获取 Access Token 和 Refresh Token 是一种相对安全的做法,尤其是当你设置了 HttpOnly 标志时,这样可以防止 JavaScript 访问这些 Cookies,从而降低 XSS 攻击的风险。以下是如何在 React 中存储和获取 Cookies 的示例。
1. 安装 js-cookie
库
为了更方便地处理 Cookies,可以使用 js-cookie
库。首先,需要安装它:
npm install js-cookie
2. 示例代码
下面是如何使用 js-cookie
进行存储和获取 Cookies 的示例。
存储令牌
当你从登录 API 获取 Access Token 和 Refresh Token 后,可以使用 Cookies.set
来存储它们。
import Cookies from 'js-cookie';
// 假设你在登录成功时得到了这两个令牌
const accessToken = 'your_access_token';
const refreshToken = 'your_refresh_token';
// 存储 Cookies
Cookies.set('accessToken', accessToken, { expires: 7, secure: true, sameSite: 'Strict' }); // 7天过期
Cookies.set('refreshToken', refreshToken, { expires: 30, secure: true, sameSite: 'Strict' }); // 30天过期
在上面的代码中,expires
参数设置了 Cookies 的过期时间,secure
参数表示只有在 HTTPS 协议下才能发送 Cookies,sameSite
限制了 Cookies 在一定情况下的使用。
获取令牌
在需要访问令牌时,可以通过 Cookies.get
进行获取。
import Cookies from 'js-cookie';
// 获取令牌
const accessToken = Cookies.get('accessToken');
const refreshToken = Cookies.get('refreshToken');
// 使用令牌
if (accessToken) {
console.log('Access Token:', accessToken);
}
if (refreshToken) {
console.log('Refresh Token:', refreshToken);
}
3. 应用 Cookies 的情况
当你在发起API请求时,需要在请求头中附带 Access Token,可以通过上述方式获取它:
import axios from 'axios';
import Cookies from 'js-cookie';
// 创建一个 Axios 实例
const api = axios.create({
baseURL: '<http://your-api-endpoint.com>',
});
// 添加请求拦截器
api.interceptors.request.use(
config => {
const token = Cookies.get('accessToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => {
return Promise.reject(error);
}
);
// 示例 API 调用
const fetchData = async () => {
try {
const response = await api.get('/protected-resource');
console.log(response.data);
} catch (error) {
console.error(error);
}
};
// 调用 fetchData
fetchData();
4. 注意事项
- HttpOnly Cookies:如果你将 Cookies 设置为 HttpOnly,JavaScript 将无法访问这些 Cookies,因此你需要在服务器端设置 Cookies,并通过
set-cookie
响应头发送给客户端。 - Cross-Origin Resource Sharing (CORS):如果你的 API 在不同的域上,要确保 CORS 设置正确,以允许 cookies 传递。
- Secure Flag:在生产环境中部署时,请确保你的应用使用 HTTPS,并且在存储 Cookies 时设置
secure
标志,使 Cookies 只能通过安全的连接传输。
通过这种方式,可以安全地存储和获取 Access Token 和 Refresh Token, 提高应用的安全性。