From 8f3c6dbc852aa9148817b34f813bd1a2d993438b Mon Sep 17 00:00:00 2001 From: xiatianxuan Date: Sat, 6 Jun 2026 20:33:06 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=AE=80=E5=8C=96=20hooks=20=E8=B7=A8?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E5=91=BD=E4=BB=A4=E8=A7=A3=E6=9E=90=EF=BC=8C?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=B5=8B=E8=AF=95=E5=85=BC=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sbackup/hooks.py | 14 ++++++++------ tests/sbackup/test_hooks.py | 16 ++++++++++++---- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/sbackup/hooks.py b/sbackup/hooks.py index d18ea40..b826851 100644 --- a/sbackup/hooks.py +++ b/sbackup/hooks.py @@ -69,13 +69,15 @@ class HookRunner: start = time.monotonic() try: # 跨平台命令解析 - if sys.platform == "win32": - try: - args_list = shlex.split(command, posix=False) - except ValueError: - args_list = [command] - else: + # posix=True(默认):剥离引号,各平台行为一致 + # Windows 上 shlex.split 可能对某些命令格式报 ValueError,回退到 [command] + try: args_list = shlex.split(command) + except ValueError: + if sys.platform == "win32": + args_list = [command] + else: + raise result = subprocess.run( args_list, diff --git a/tests/sbackup/test_hooks.py b/tests/sbackup/test_hooks.py index 67b5b2f..0dc3194 100644 --- a/tests/sbackup/test_hooks.py +++ b/tests/sbackup/test_hooks.py @@ -10,13 +10,21 @@ from sbackup.hooks import HookResult, HookRunner def _make_python_cmd(script: str) -> str: - """创建跨平台的 Python 命令,避免引号转义问题""" - return f"{sys.executable} -c {script}" + """创建跨平台的 Python 命令 + + 将可执行文件路径用双引号包裹,确保 shlex.split 在 posix 模式下 + 不会将 Windows 路径中的反斜杠解释为转义字符。 + """ + return f'"{sys.executable}" -c {script}' +# 命令中不包含空格或分号,确保 shlex.split 正确解析 _echo_cmd = _make_python_cmd("print(42)") -_fail_cmd = _make_python_cmd("raise SystemExit(1)") -_sleep_cmd = _make_python_cmd("__import__('time').sleep(10)") +_fail_cmd = _make_python_cmd("exit(1)") +# 超时命令使用 ping(无引号/分号问题): +# Windows: ping -n 11 127.0.0.1 (~10s) +# Unix: ping -c 11 127.0.0.1 (~10s) +_sleep_cmd = "ping -n 11 127.0.0.1" if sys.platform == "win32" else "sleep 10" class TestHookResult(unittest.TestCase):