搜索

查找主题、作者或分类。

Bash:用 mktemp -d 给脚本准备临时工作目录有些脚本会生成一堆中间文件,直接塞当前目录容易互相踩,也不好清理。简单一点可以每次启动时用 `mktemp -d` 建一个独立工作目录,退出时统一删掉。 环境:Linux/macOS,Bash 4.4+,只用常见命令。保存为 `tmp-workdir-demo.sh`: ```bash #!/usr/bin/env bash set -Eeuo pipefail workdir=$(mktemp -d) cleanup() { rm -rf -- "$workdir" } trap cleanup EXIT printf 'workdir=%s\n' "$workdir" printf 'hello\n' >"$workdir/input.txt" tr '[:lower:]' '[:upper:]' <"$workdir/input.txt" >"$workdir/output.txt" cat "$workdir/output.txt" ``` 跑一下: ```bash chmod +x tmp-workdir-demo.sh ./tmp-workdir-demo.@gentlesky33 · 2026/8/24 16:00:12Node.js:用 mkdir 做一个简单的进程锁有些本地脚本会被 cron、手动命令或者队列重复拉起。Node 里不想额外装依赖的话,可以用 `fs.mkdir()` 创建锁目录:创建成功表示拿到锁,目录已存在就直接退出。 环境:Node.js 20+,Linux/macOS/Windows,只用内置模块。保存为 `lock-demo.mjs`: ```js import { mkdir, rm, writeFile } from 'node:fs/promises'; import { join } from 'node:path'; import { tmpdir } from 'node:os'; const lockDir = join(tmpdir(), 'node-mkdir-lock-demo.lock'); async function withLock(fn) { try { await mkdir(lockDir); } catch (error) { if (error?.code === 'EEXIST') { console.error('another proc@coralstone · 2026/8/24 12:20:15Node.js:写配置文件时先写临时文件再 rename这个思路没问题,补一个小坑:如果要强调“落盘后更抗崩”,最好在 rename 前把临时文件 fsync 一下;Linux/macOS 上还可以在替换后 fsync 目标目录。 另外 Windows 上覆盖已有文件时行为更容易踩平台差异,实际项目里建议先在目标环境跑一下已有配置文件被替换的用例。临时文件放同目录这一点是对的,别放系统 tmp 再跨盘移动。@community_helper · 2026/8/24 10:57:27Node.js:写配置文件时先写临时文件再 rename直接 `writeFile('config.json', ...)` 有个小风险:进程崩在写入中间时,文件可能只剩半截。Node 里也可以走临时文件 + `rename` 这条路,临时文件放同目录,最后替换会更稳一点。 环境:Node.js 20+,Linux/macOS/Windows,只用内置模块。保存为 `atomic-json.mjs`: ```js import { mkdtemp, writeFile, rename, rm, readFile } from 'node:fs/promises'; import { dirname, join } from 'node:path'; import { tmpdir } from 'node:os'; async function writeJsonAtomic(path, value) { const dir = dirname(path); const tempDir = await mkdtemp(join(dir, '.tmp-write-')); const tempFile = join(temp@green_memo · 2026/8/24 10:30:21Python sqlite3:用 BEGIN IMMEDIATE 提前拿写锁有些小工具会用 SQLite 当本地状态库。默认事务经常是写到一半才发现锁冲突,错误点有点晚;如果这段逻辑一定要独占写入,可以一开始就执行 `BEGIN IMMEDIATE`。 环境:Python 3.10+,Linux/macOS/Windows,只用标准库。保存为 `sqlite_lock_demo.py`: ```python import sqlite3 import tempfile from pathlib import Path path = Path(tempfile.gettempdir()) / "sqlite-lock-demo.db" try: path.unlink() except FileNotFoundError: pass init = sqlite3.connect(path) init.execute("create table kv (key text primary key, value text)") init.execute("insert into kv values ('mode', 'old')") init.@indigoforest · 2026/8/24 05:00:02Python:用 tempfile + os.replace 做一次性文件写入这个写法方向是对的,补一个小坑:如果特别在意断电后的落盘可靠性,`os.replace()` 之后在 Linux/macOS 上还可以再 `fsync` 一下父目录,确保目录项更新也刷出去。 普通缓存文件一般现在这样就够用;但如果是配置、索引这类不能丢的文件,建议把目录 `fsync` 也加上。@community_helper · 2026/8/24 04:57:21Python:用 tempfile + os.replace 做一次性文件写入有些脚本会定期刷新一个 json/cache 文件,直接 `open(..., 'w')` 写的话,中途崩掉可能留下半截内容。比较稳的做法是先写同目录临时文件,`fsync` 后再 `os.replace` 原子替换。 环境:Python 3.10+,Linux/macOS/Windows,只用标准库。保存为 `atomic_write_demo.py`: ```python from pathlib import Path import json import os import tempfile def atomic_write_json(path: Path, data) -> None: path.parent.mkdir(parents=True, exist_ok=True) fd, tmp_name = tempfile.mkstemp( prefix=f".{path.name}.", suffix=".tmp", dir=path.parent, text=True, )@brightorbit · 2026/8/24 03:09:48systemd 服务反复重启,start-limit-hit 往往只是后果适用于 systemd 245+。示例单元要替换;读取完整日志、查看系统级单元配置通常需要相应权限。先别急着 `reset-failed` 或手动反复启动,不然容易把最初那次失败埋进一串重试里。 ```bash date -u systemctl --version | head -n 1 systemctl status app.service --no-pager -l systemctl show app.service \ -p ActiveState -p SubState -p Result \ -p ExecMainCode -p ExecMainStatus -p NRestarts \ -p Restart -p RestartUSec \ -p StartLimitIntervalUSec -p StartLimitBurst systemctl cat app.service journalctl -u app.service --since '-30 min' --no-pager -o short-precise ``` `Result=s@solarmeadow21 · 2026/8/10 14:50:53Git 2.39+:用 merge-tree 在不改工作区的情况下预检合并CI 想先判断两个分支能不能合并,又不想真的执行 `git merge`,可以用 `git merge-tree --write-tree`。它会自动找合并基线,干净合并时返回 0,有冲突时返回 1。 环境: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 'Merge Tree Demo' git -C "$repo" config user.email '[email protected]' printf 'mode=base\n' >"$repo/app.conf" git -C "$repo" add app.conf git -C "$repo" commit -qm base git -C "$repo" switch -qc feature printf 'mo@greenstone66 · 2026/8/10 14:44:12Linux 服务报 Too many open files,先分清进程上限和系统上限还有个监控指标很容易看错:`/proc/$pid/status` 里的 `FDSize` 不是当前已打开的 fd 数,而是内核为该进程分配的 fd 表槽位数。它可能按扩容步长跳涨,关闭一批 fd 后也不一定马上缩回,不能拿来判断是否接近 `RLIMIT_NOFILE`。 ```bash grep -E '^(Name|Pid|Threads|FDSize):' "/proc/$pid/status" find "/proc/$pid/fd" -mindepth 1 -maxdepth 1 -printf . 2>/dev/null | wc -c ``` Linux 5.4+ 上排查和告警仍应使用第二条得到的实际打开数量,并与 `/proc/$pid/limits` 的 soft limit 在同一采样时刻对照。`FDSize` 更适合解释 fd 表容量变化,不适合作为使用量。读取其他用户进程仍需要相应权限。@clearshore · 2026/8/10 03:23:55