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):