跳到主要内容

Git 常用命令

· 阅读需 1 分钟

git log

--since 语法

  1. 绝对日期格式
    • YYYY-MM-DD
    • Month Day, Year
    • YYYY-MM-DD HH:mm:ss
  2. 相对时间格式
    • N year/months/weeks/days/hours/minutes/seconds ago
    • yesterday/today
  3. --until --before 结合
    • --since>=
    • --until, 即 <

从今天开始,过去 1 个月的提交

git log --since="1 month ago"

一行显示

git log --since="2025-06-01" --until="2025-07-01" --oneline

自定义输出

# %h commit hash 的缩写
# %an 作者
# %ar 提交的相对时间
# %s 提交信息
git log --since="1 month ago" --pretty=format:"%h - %an, %ar : %s"

图形化显示

git log --since="1 month ago" --graph --oneline

问题记录

· 阅读需 1 分钟

2025.6.27

  1. 序列化与反序列
    • 兼容多种日志格式
    • jackson、gson、fastjson 的写法
  2. Dockerfile 构建优化技巧

Docker Image

· 阅读需 1 分钟

watchtower

自动检测并更新 docker image

version: "3"
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 3600 # 每小时检查一次更新

自解释代码

· 阅读需 2 分钟

summary

  1. 使用命名常量而非晦涩的错误代码 | Using named constants instead of cryptic error codes
  2. 将复杂逻辑抽离成独立函数 | Extracting complex logic and putting it in its own function
  3. 运用短路求值使代码流程线性化 | Using short-circuit evaluation to make the code flow linear
  4. 引入类型注解辅助静态检查与实时编码反馈 | Introducing type annotations to help with static type checking and real-time coding feedback

original code

async function createUser(user) {
if (!validateUserInput(user)) {
throw new Error('u105');
}

const rules = [/[a-z]{1,}/, /[A-Z]{1,}/, /[0-9]{1,}/, /\W{1,}/];
if (user.password.length >= 8 && rules.every((rule) => rule.test(user.password))) {
if (await userService.getUserByEmail(user.email)) {
throw new Error('u212');
}
} else {
throw new Error('u201');
}

user.password = await hashPassword(user.password);
return userService.create(user);
}

命名常量与单一职责原则

const err = {
userValidationFailed: 'u105',
userExists: 'u212',
invalidPassword: 'u201',
};

function isPasswordValid(password) {
const rules = [/[a-z]{1,}/, /[A-Z]{1,}/, /[0-9]{1,}/, /\W{1,}/];
return password.length >= 8 && rules.every((rule) => rule.test(password));
}

async function createUser(user) {
if (!validateUserInput(user)) {
throw new Error(err.userValidationFailed);
}

if (isPasswordValid(user.password)) {
if (await userService.getUserByEmail(user.email)) {
throw new Error(err.userExists);
}
} else {
throw new Error(err.invalidPassword);
}

user.password = await hashPassword(user.password);
return userService.create(user);
}

短路求值

function throwError(error) {
throw new Error(error);
}

async function createUser(user) {
validateUserInput(user) || throwError(err.userValidationFailed);
isPasswordValid(user.password) || throwError(err.invalidPassword);
!(await userService.getUserByEmail(user.email)) || throwError(err.userExists);

user.password = await hashPassword(user.password);
return userService.create(user);
}

Keeping a Mistake Journal

· 阅读需 1 分钟

Entry Format

Name:名称,简明扼要的标题。
Tags:标签,分类
Context:背景,错误发生的具体环境或情境。
Problem:问题,对错误本身的描述。
Impacts:影响,可能导致的后果。
Lessons learned:经验总结,从这次错误中学到了什么。
Correction plan: 改进方案,今后如何避免重蹈覆辙。
Latest occurrence:最近发送,上次犯这个错误的时间。
Repetition: 重复次数,这个错误发送的概率。

awk 命令基本使用

· 阅读需 4 分钟

awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

默认分隔符是:空白键或者 tab 建,以 \n 为一行

$0:所有域
$n:第 n 个域

1、显示出最近登录成功的用户

使用默认分隔符

last -n 5 | awk '{print $1}'

2、查看用户

通过 -F ':' 指定分隔符

# 下面两个命令等效
cat /etc/passwd | awk -F ':' '{print $1}'
cat /etc/passwd | awk -F: '{print $1}'

3、查看用户的时候显示出 bash

通过双引号对 \t 转义

cat /etc/passwd | awk -F ':' '{print $1"\t"$7}'

4、BEGIN、END 使用

cat /etc/passwd | awk -F ':' 'BEGIN {"name,bash"} {print $1","$7} END {print "blue,/bin/nosh"}'

5、匹配含有关键字的行

'/pattern/action' 指定正则表达式和 action

awk -F ':' '/root/' /etc/passwd
awk -F ':' '/root/{print $7}' /etc/passwd

6、awk 内置变量

ARGC               命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
awk -F ':' '{print $1 "\tfilename:" FILENAME "\t\tARGC:" ARGC "\tFNR:" FNR}' aa.txt 

7、print、printf

print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。

printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。

8、自定义变量

awk -F ':' 'BEGIN {count=0; print "[start] user count is "count}{ count++; print $1"\t" count} END {print "user count is " count}' /etc/passwd

统计某个文件夹下的文件占用的字节数

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'

如果以M为单位显示:

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'

9、显示账户

awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd

查看拒绝访问的 IP

awk -F ':' '{print $2}' /etc/hosts.deny| sort | uniq -c | awk '{print $1"\t"$2}' | grep  '^[0-9]' 

MongoDB 常用查询语句/技巧

· 阅读需 1 分钟

转换为 UTC 时间字符串

// 转换为 UTC 时间字符串
db.collection.find({
timestamp: { $gte: new Date( new Date("2025-03-22T00:00:00+08:00").toISOString()) }
});

创建视图

标准视图使用底层集合的索引。

// ==============  AI800 A相进线温度  ==========
db.AI800.drop();
db.createView(
"AI800", // 视图名称
"equipment-1123", // 源集合
[
{ $match: { "code": "AI424" } }, // 过滤条件
]
)

db.AI800.find();

scoop

· 阅读需 2 分钟

ref

https://linux.do/t/topic/566873

Install

1. 调整执行策略

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

2. 安装

irm get.scoop.sh | iex

3. 检验是否安装成功

Initializing...
Downloading...
Creating shim...
Adding ~\scoop\shims to your path.
Scoop was installed successfully!
Type 'scoop help' for instructions.
scoop help

Usage

Bucket

buckets 是存储应用程序清单的仓库,每个 bucket 包含了一系列 JSON 文件,每个文件对应一个软件包,描述如何下载、安装以及依赖等信息。

需要有 git 环境

scoop install git
scoop bucket add extras
scoop bucket add java
scoop bucket add nerd-fonts
scoop bucket add versions
scoop bucket add nonportable

更新 scoop 和 buckets

scoop update

更新安装的软件

scoop update *

安装软件

scoop install 7zip
scoop install geekuninstaller
scoop install everything
scoop install fastcopy
scoop install apifox
scoop install localsend
scoop install screentogif
scoop install sumatrapdf