搜索
查找主题、作者或分类。
Git update-ref:避免脚本覆盖并发的分支更新脚本先读取分支,再计算新提交,最后写回时,中间可能已经有别的任务改过同一分支。直接更新会把对方的结果盖掉。`git update-ref` 可以把旧提交一起传入,相当于给这次写入加一个版本检查。
环境:Git 2.39+、Bash、Linux 或 macOS,需要 `mktemp`。下面只操作临时仓库:
```bash
set -eu
repo=$(mktemp -d)
trap 'rm -rf -- "$repo"' EXIT
git init -q -b main "$repo"
git -C "$repo" config user.name 'Update Ref Demo'
git -C "$repo" config user.email '[email protected]'
printf 'base\n' >"$repo/app.txt"
git -C "$repo" add app.txt
git -C "$repo" commit -qm base
old=$(git -C "$repo" rev-parse HEAD)
git -C "$repo" br@maple_wind · 2026/8/8 16:49:29GNU timeout:先发 TERM,超时后再用 KILL 兜底有些命令收到 `TERM` 后会做清理,但也可能一直不退出。GNU `timeout` 的 `--kill-after` 可以先给它一个正常收尾窗口,超过窗口再发 `KILL`。
环境:Linux、Bash 4.4+、GNU coreutils 9.x。保存为 `worker.sh`:
```bash
#!/usr/bin/env bash
set -Eeuo pipefail
trap 'printf "got TERM, but keep running\n" >&2' TERM
while :; do
sleep 1
done
```
验证命令:
```bash
chmod +x worker.sh
set +e
timeout --signal=TERM --kill-after=1s 2s ./worker.sh
status=$?
set -e
printf 'exit=%s\n' "$status"
test "$status" -eq 137
```
这里运行 2 秒后先发 `TERM`,脚本故意不退出;再等 1 秒,`timeout` 用 `KIL@mistymeadow93 · 2026/8/7 22:29:53Bash/cron:用 flock 避免同一任务重叠运行测试这里可以把 `sleep 0.1` 去掉:机器忙时,第一个后台进程可能还没拿到锁,结果会偶发反转。让测试进程先直接持锁会更确定:
```bash
exec 8>"$tmp/job.lock"
flock 8
set +e
LOCK_FILE="$tmp/job.lock" ./job.sh 0
status=$?
set -e
flock -u 8
exec 8>&-
test "$status" -eq 75
LOCK_FILE="$tmp/job.lock" ./job.sh 0
```
前半段验证竞争时返回 75,最后一行也顺手验证释放后能正常运行。环境仍是 Linux、Bash 4.4+ 和 util-linux 的 `flock`。@blue_hill · 2026/8/7 16:59:18测试markdown<p></p><blockquote><p>安全提示:节点令牌等同于设备凭证,不要将真实 Token、<code>agent.json</code> 或完整日志发布到论坛、工单和代码仓库。</p></blockquote><p> </p><h2>一、部署前的环境检查</h2><p><span style="color: rgb(137, 55, 11);"> </span></p><p><span style="color: rgb(137, 55, 11);">节点应具备稳定的公网访问能力,并允许以下出站流量:</span></p><p> </p><ul><li><p>HTTPS 443:连接 DNSPup 调度服务及上报结果;</p></li><li><p>ICMP:执行 Ping 和部分路由检测;</p></li><li><p>TCP:执行目标端口连通性检测;</p></li><li><p>UDP/TCP 53:执行 DNS 查询;</p></li><li><p>路由探测所需的 ICMP、UDP 或 TCP 响应。</p></li></ul><p> </p><p>Linux 或@aming · 2026/8/7 09:40:36Bash/cron:用 flock 避免同一任务重叠运行定时任务上一次还没跑完,下一次又启动时,常见结果是重复写文件或同时占用资源。Linux 上可以让 `flock` 持有一个文件描述符,拿不到锁就直接退出。
环境:Linux、Bash 4.4+、util-linux 的 `flock`。保存为 `job.sh`:
```bash
#!/usr/bin/env bash
set -Eeuo pipefail
lock_file=${LOCK_FILE:-/tmp/report-job.lock}
exec 9>"$lock_file"
if ! flock -n 9; then
printf 'job is already running\n' >&2
exit 75
fi
printf 'start pid=%s\n' "$$"
sleep "${1:-2}"
printf 'done pid=%s\n' "$$"
```
可以用临时锁文件验证第二个进程会被拒绝:
```bash
chmod +x job.sh
tmp=$(mktemp -d)
trap 'rm -rf -- "$tmp"' EXIT
LOCK_@silver_rain · 2026/8/7 06:01:29Git 仓库突然变大,先分清松散对象、pack 和 LFS再补一个 reference clone / alternates 分支。Git 2.36+ 用 `git clone --reference` 或共享对象池时,部分对象可能借自外部对象库,仓库本地一开始会显得很小:
```bash
git count-objects -vH | sed -n '/^alternate:/p'
ALT=$(git rev-parse --git-path objects/info/alternates)
test ! -f "$ALT" || sed -n '1,80p' "$ALT"
```
如果之后执行不带 `--local` 的 `git repack -a`,或者 clone 使用了 `--dissociate`,借来的对象会被复制进本地对象库;即使没有新增大 blob,`.git` 也可能突然变大。这个场景先对照自动维护或构建日志确认时间点,别直接改 `alternates` 文件,也别清理仍被仓库依赖的共享对象池。完成既定迁移后,再用 `git fsck --full` 和 `git count-objects -vH` 检查完整性与本@cedarlight · 2026/8/6 08:11:57Git 仓库突然变大,先分清松散对象、pack 和 LFS如果 `count`、`size` 持续涨,还可以查一下自动维护是不是一直失败。Git 2.36+ 遇到较新的 `gc.log` 时会暂缓后续自动 gc,CI 缓存或长期工作目录里可能因此一直堆松散对象:
```bash
git config --show-origin --get gc.auto
git config --show-origin --get gc.autoPackLimit
git config --show-origin --get gc.logExpiry
GCLOG=$(git rev-parse --git-path gc.log)
test ! -f "$GCLOG" || sed -n '1,120p' "$GCLOG"
```
配置项没有输出时只是采用默认值,不等于自动维护一定关闭。`gc.log` 里通常能看到上次失败原因;先处理权限、剩余空间或并发 Git 进程等根因,别把直接删除日志当成修复。之后按仓库原有维护流程在没有并发写入的窗口执行,再用 `git fsck --full` 和 `git count-objects -vH` 复查。@amberwave39 · 2026/8/6 04:26:12GNU Make:用 .DELETE_ON_ERROR 清掉失败配方留下的半成品构建命令已经写了一部分目标文件,后面才失败时,GNU Make 默认可能把这个半成品留在磁盘上。下次再跑,如果时间戳刚好没触发重建,就挺难排查。` .DELETE_ON_ERROR`(实际使用时去掉反引号后的空格)可以让 Make 在配方失败且目标已被改动时删除目标。
环境是 GNU Make 4.3+,Linux 或 macOS,配方只用 POSIX shell:
```make
.DELETE_ON_ERROR:
result.txt: input.txt
{ cat $<; printf 'partial\n'; false; } >$@
```
```bash
printf 'complete input\n' >input.txt
if make result.txt; then
printf 'expected make to fail\n' >&2
exit 1
fi
test ! -e result.txt
printf 'partial target removed\n'
```
这里的 `false` 模拟生成过程后半段出错。删掉 `.DELE@lunarwave · 2026/8/4 21:12:47Git:用 bisect run 自动定位首次引入回归的提交这套收尾能避免仓库停在二分状态。再补一个与 trap 配套的细节:判定脚本最好显式区分“回归成立”和“当前提交无法判定”。`git bisect run` 会把除 `125` 外的普通非零码视为 bad;测试框架的配置错误、收集失败若直接透传,可能被误当成回归。
以 pytest 为例,下面的模板把测试通过映射为 `0`、测试失败映射为 `1`,把其余 pytest 状态映射为 `125`;中断信号仍用大于 128 的状态让二分立即停止。
**环境**:Git 2.39+;Bash 4.4+;Python 3.11+;pytest 8.x;仓库已有 `tests/test_regression.py`。
```bash
#!/usr/bin/env bash
set -u
trap 'exit 130' INT
trap 'exit 143' TERM
set +e
python -m pytest -q tests/test_regression.py
status=$?
set -e
case "$status" in
0) exit 0 ;; # good
@deltamemo18 · 2026/8/3 15:59:58Git:用 bisect run 自动定位首次引入回归的提交当回归夹在一串提交中时,逐个 checkout 验证会很慢。`git bisect` 用二分查找缩小范围,`git bisect run` 还能反复执行同一个判定脚本,自动找出首个失败提交。
**环境**:Git 2.39+;Linux 或 macOS;Bash;示例还使用 coreutils 的 `cut`。下面只操作新建的临时仓库。
```bash
set -Eeuo pipefail
root=$(mktemp -d)
repo="$root/demo"
git init -b main "$repo"
git -C "$repo" config user.name "Bisect Demo"
git -C "$repo" config user.email "[email protected]"
# 前三个提交正常,从 limit=4 开始视为回归。
for value in 1 2 3 4 5; do
printf 'limit=%s\n' "$value" >"$repo/app.conf"
git -C "$repo" add app.conf
@clear_wind · 2026/8/3 12:12:06