From 850f8fac9b5cd700ae45f1e25c6678d24728244c Mon Sep 17 00:00:00 2001 From: ypshidifu Date: Sat, 19 Sep 2026 12:13:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20CLI=20>=20=E9=87=8D=E5=AE=9A=E5=90=91?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=90=AB=E7=A9=BA=E6=A0=BC=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复 _split_line 在遇到 > 重定向时,因空格导致输出路径被分割的问题。 现在 > 后的内容(含空格)作为一个整体 token,配合 _parse_gt_output 的分隔符空格规范化,使如 '../ MMook JJi BBa.mp3' 的输出路径正确解析。 --- vipsong.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/vipsong.py b/vipsong.py index 2659135..39c83ea 100644 --- a/vipsong.py +++ b/vipsong.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import os, sys, glob, struct, base64, json, io +import os, sys, glob, struct, base64, json, io, re from pathlib import Path from typing import Optional from Crypto.Cipher import AES @@ -86,6 +86,9 @@ def _parse_gt_output(input_path, output_spec): """解析 'input>output' 重定向语法,返回 (output_path, output_fmt)。""" p = Path(input_path) spec = output_spec.strip() + # 规范化路径分隔符后的空格(如 '../ file.mp3' -> '../file.mp3'), + # 保留文件名内部的空格 + spec = re.sub(r'([/\\])\s+', r'\1', spec) if not spec: # 空输出规格(如 'song.ncm>'),使用默认 mp3 格式 out_path = p.with_suffix(".mp3") @@ -466,20 +469,32 @@ def print_stats(): print() def _split_line(line): - """按空白分割命令行,处理引号但不处理反斜杠转义(适配 Windows 路径)。""" + """按空白分割命令行,处理引号。支持 '>' 重定向语法:> 后的输出路径可含空格。 + + 注意:'>' 后的内容(含空格)作为输出路径整体;参数请写在重定向前。 + """ args = [] current = [] in_single = False in_double = False + after_redirect = False # 是否进入 > 重定向输出模式 for ch in line: if ch == '"' and not in_single: in_double = not in_double elif ch == "'" and not in_double: in_single = not in_single + elif ch == '>' and not in_single and not in_double: + # 遇到 > 重定向:附加到当前 token,进入输出模式(保留空格) + after_redirect = True + current.append(ch) elif ch in (' ', '\t') and not in_single and not in_double: - if current: - args.append(''.join(current)) - current = [] + if after_redirect: + # 输出路径模式:保留空格(用于含空格的文件名) + current.append(ch) + else: + if current: + args.append(''.join(current)) + current = [] else: current.append(ch) if current: