♻️ refactor(av1-transfer): replace setproctitle with ctypes to fully hide cmdline args

Drop the setproctitle dependency. Use prctl(PR_SET_NAME) to change
/proc/self/comm and directly overwrite argv memory via Py_GetArgcArgv
to clear /proc/self/cmdline, so ps aux shows no arguments.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
FlintyLemming
2026-02-28 11:03:57 +08:00
parent a036b400d2
commit bf98b6d002

View File

@@ -17,13 +17,15 @@ AV1 视频批量转码脚本
"""
import argparse
import ctypes
import ctypes.util
import queue
import shutil
import subprocess
import sys
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path
import setproctitle
from tqdm import tqdm
# ================= 配置区域 =================
@@ -35,6 +37,42 @@ VIDEO_EXTS = {".mp4", ".mkv", ".mov", ".avi", ".flv", ".ts", ".webm"}
SLOT_BAR_FORMAT = "{desc:<50} {percentage:3.0f}%|{bar}| {n:.0f}/{total:.0f}s"
def _set_proc_title(title: str) -> None:
"""
通过两种方式彻底隐藏进程命令行:
1. prctl(PR_SET_NAME) — 改 /proc/self/commtop 默认显示的短名)
2. 直接覆盖 argv 内存 — 改 /proc/self/cmdlineps aux COMMAND 列)
"""
# 1. 改短名(/proc/self/comm最多 15 字节)
try:
libc_name = ctypes.util.find_library("c")
if libc_name:
libc = ctypes.CDLL(libc_name, use_errno=True)
libc.prctl(15, title.encode()[:15], 0, 0, 0) # PR_SET_NAME = 15
except Exception:
pass
# 2. 覆盖 argv 内存,清除 /proc/self/cmdline 里的参数
try:
argc = ctypes.c_int(0)
argv = ctypes.POINTER(ctypes.c_char_p)()
ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(argc), ctypes.byref(argv))
if argc.value == 0:
return
# argv 字符串在内存中连续排列,计算总占用字节数
start = ctypes.cast(argv[0], ctypes.c_void_p).value
end = ctypes.cast(argv[argc.value - 1], ctypes.c_void_p).value
end += len(argv[argc.value - 1]) + 1
size = end - start
# 用 title 填充开头,其余全部清零
enc = title.encode()[:size - 1]
buf = (ctypes.c_char * size).from_address(start)
buf[:len(enc)] = enc
buf[len(enc):] = b"\x00" * (size - len(enc))
except Exception:
pass
def get_duration(input_path):
"""用 ffprobe 获取视频时长(秒),失败返回 None"""
result = subprocess.run(
@@ -203,7 +241,7 @@ def main():
print(f"共发现 {len(tasks)} 个文件,准备使用 {max_workers} 个并行任务进行转码...")
if process_name:
setproctitle.setproctitle(process_name)
_set_proc_title(process_name)
print(f"进程别名: {process_name}")
# 初始化进度条