我试图用7z.exe
解压缩文件,密码中包含特殊字符
EX。 &)kra932(lk0¤23
执行以下命令:
subprocess.call(['7z.exe', 'x', '-y', '-ps^&)kratsaslkd932(lkasdf930¤23', 'file.zip'])
7z.exe
启动正常,但它说密码错误。
这是我创建的文件,它让我疯狂。
如果我在Windows命令行上运行该命令,则运行正常
7z.exe x -y -ps^&)kratsaslkd932(lkasdf930¤23 file.zip
如何让python转义为&
字符?
@Wim问题发生了&在密码上,因为我执行时
7z.exe x -y -ps^&)kratsaslkd932(lkasdf930¤23 file.zip
它表示无效的命令')kratsaslkd932(lkasdf930¤23'
即时通讯使用python 2.76,由于只运行在2.76
答案 0 :(得分:0)
我建议使用原始字符串和shlex模块(特别是在Windows上),不支持ASCII以外的任何编码。
import shlex
import subprocess
cmd = r'7z.exe x -y -p^&moreASCIIpasswordchars file.zip'
subprocess.call(shlex.split(cmd))
回到非ASCII字符问题......
我非常确定Python版本< 3你根本不能使用非ASCII字符。我不是C专家,但请注意2.7和3.3之间的区别。前者使用“标准”字符,而后者使用宽字符。
答案 1 :(得分:0)
请尝试在密码之间加上双引号,否则cmd解析器将按原样解析特殊字符,而不是将其作为密码的一部分。
例如,
/**
* Responds to any HTTP request.
*
* @param {!express:Request} req HTTP request context.
* @param {!express:Response} res HTTP response context.
*/
exports.helloWorld = (req, res) => {
let message = req.query.message || req.body.message || 'Hello World!';
console.log('Headers from request: ' + JSON.stringify(req.headers));
let parsedBody;
if(req.header('content-type') === 'application/json') {
console.log('request header content-type is application/json and auto parsing the req body as json');
parsedBody = req.body;
} else {
console.log('request header content-type is NOT application/json and MANUALLY parsing the req body as json');
parsedBody = JSON.parse(req.body);
}
console.log('Message from parsed json body is:' + parsedBody.message);
res.status(200).send(message);
};
不起作用。
但是7z.exe x -y -ps^&)kratsaslkd932(lkasdf930¤23 file.zip
肯定可以。
答案 2 :(得分:0)
在命令行上传递密码存在很大的安全风险。具有管理权限,可以检索该信息(启动信息对象)并提取密码。更好的解决方案是将7zip作为一个进程打开,并将密码输入其标准输入中。
这是一个命令行示例,它将“ source.txt”压缩为“ dest.7z”:
CMD = ['c:\\Program Files\\7-Zip\\7z.exe', 'a', '-t7z', '-p', 'c:\\source.txt', 'd:\\dest.7z']
PASSWORD = "Nj@8G86Tuj#a"
首先,您需要将密码转换为输入字符串。请注意,7-zip要求在终端输入密码。您可以使用特殊字符,只要它们可以在终端中显示即可。终端的编码很重要!例如,在匈牙利语Windows上,您可能要使用“ cp1250”编码。在所有情况下,标准输入都是二进制文件,并且期望二进制字符串(Python 3中为“字节”)。为了安全起见,可以将密码限制为纯ascii并按以下方式创建输入:
input = (PASSWORD + "\r\n").encode("ascii")
如果您知道终端的编码,则可以将密码转换为该编码。您还将能够检测密码是否不能与系统的编码一起使用。 (顺便说一句,这也意味着它也不能交互使用。)
(上次我检查过,Windows上不同区域设置的终端编码是不同的。也许有技巧将其更改为UTF-8,但我不确定如何。)
这是执行命令的方式:
import subprocess
import typing
def execute(cmd : typing.List[str], input: typing.Optional[bytes] = None, verbose=False, debug=False, normal_priority=False):
if verbose:
print(cmd)
creationflags = subprocess.CREATE_NO_WINDOW
if normal_priority:
creationflags |= subprocess.NORMAL_PRIORITY_CLASS
else:
creationflags |= subprocess.BELOW_NORMAL_PRIORITY_CLASS
if debug:
process = subprocess.Popen(cmd, shell=False, stdout=sys.stdout, stderr=sys.stderr, stdin=subprocess.PIPE,
creationflags=creationflags)
else:
process = subprocess.Popen(cmd, shell=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
stdin=subprocess.PIPE, creationflags=creationflags)
if input:
process.stdin.write(input)
process.stdin.flush()
returncode = process.wait()
if returncode:
raise OSError(returncode)
CMD = ['c:\\Program Files\\7-Zip\\7z.exe', 'a', '-t7z', '-p', 'c:\\source.txt', 'd:\\dest.7z']
PASSWORD = "Nj@8G86Tuj#a"
input = (PASSWORD + "\r\n").encode("ascii")
execute(CMD, input)
这还显示了如何降低进程优先级(压缩大量数据时通常是个好主意),并且还显示了如何将标准输出和标准错误转发到控制台。
绝对正确的解决方案是加载7-zip DLL并使用其API。 (我没有检查,但是可能可以使用8位二进制字符串作为密码。)
注意:此示例适用于Python 3,但使用Python 2也可以做到这一点。