♻️ 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:
@@ -17,13 +17,15 @@ AV1 视频批量转码脚本
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import ctypes
|
||||||
|
import ctypes.util
|
||||||
import queue
|
import queue
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import setproctitle
|
|
||||||
from tqdm import tqdm
|
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"
|
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/comm(top 默认显示的短名)
|
||||||
|
2. 直接覆盖 argv 内存 — 改 /proc/self/cmdline(ps 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):
|
def get_duration(input_path):
|
||||||
"""用 ffprobe 获取视频时长(秒),失败返回 None"""
|
"""用 ffprobe 获取视频时长(秒),失败返回 None"""
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
@@ -203,7 +241,7 @@ def main():
|
|||||||
|
|
||||||
print(f"共发现 {len(tasks)} 个文件,准备使用 {max_workers} 个并行任务进行转码...")
|
print(f"共发现 {len(tasks)} 个文件,准备使用 {max_workers} 个并行任务进行转码...")
|
||||||
if process_name:
|
if process_name:
|
||||||
setproctitle.setproctitle(process_name)
|
_set_proc_title(process_name)
|
||||||
print(f"进程别名: {process_name}")
|
print(f"进程别名: {process_name}")
|
||||||
|
|
||||||
# 初始化进度条
|
# 初始化进度条
|
||||||
|
|||||||
Reference in New Issue
Block a user