所以我试图在某个任意文件上调用Windows命令类型。不幸的是,每当我将我的cmd从shell命令转换为非shell命令时,它都会失败。因此,我不能使用推荐的方法来确保我的python脚本无法被利用。这是一个例子。
import subprocess
cmd = "type" + '"' + "some_file_with_no_spaces_or_other_things_wrong" + '"'
p = subprocess.pOpen(cmd, shell = True)
但是当我尝试时:
#Assume cmd split is done properly. Even when I manually put in the
#array with properly escaped quotes it does not work
subprocess.pOpen(cmd.split(), shell = False)
它失败了,我不知道如何解决这个问题。我希望能够通过假将shell安全地调用此命令,但每当我这样做时,我都会收到以下错误。
Traceback (most recent call last):
File "C:\Users\Skylion\git\LVDOWin\Bin\Osiris.py", line 72, in openFileDialog
stderr = STDOUT, shell = False, bufsize = 0, universal_newlines=True)
File "C:\Python34\lib\subprocess.py", line 859, in __init__
restore_signals, start_new_session)
File "C:\Python34\lib\subprocess.py", line 1112, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
请注意,即使运行:
subprocess.Popen(['type'])
会抛出错误。我的问题是如何清理文件名,以便我可以使用shell = True运行文件名,或者正确地运行shell = False。
如何以这种方式正确打开文件的任何帮助将不胜感激。
答案 0 :(得分:1)
shell=True
是一个内部命令,因此您需要subprocess.list2cmdline()
,例如,隐式地通过CreateProcess()
运行。
如果您在Windows上将命令作为列表传递,则调用cmd.exe
将列表转换为字符串以传递给shell=True
Windows API。它的语法与from subprocess import check_call
check_call(r'type "C:\path\with spaces & special symbols.txt"', shell=True)
语法不同。有关详细信息,请read the links in this answer。
将shell命令作为字符串传递并添加r''
:
cmd
注意:^
前缀用于避免在文字字符串中转义后退。
如果该命令从命令行按 运行,那么它也可以在Python中运行。
如果文件名是在变量中给出的,那么您可以使用escaped_filename = filename_with_possible_shell_meta_chars.replace("", "^")[:-1]
check_call('type ' + escaped_filename, shell=True)
为shell type
转义它:
open()
注意:没有明确的引号。
显然,您可以在纯Python中模拟with open(r'C:\path\with spaces & special symbols.txt',
encoding=character_encoding) as file:
text = file.read()
命令:
TYPE复制到控制台设备(或其他地方) 如果重定向)。不检查该文件是否为可读文本。
如果您只需要阅读文件;使用open()
函数:
'cp1252'
如果您未指定显式编码,则locale.getpreferredencoding(False)
使用ANSI代码页(例如utf-8
(notepad.exe
)将文件内容解码为Unicode文本。
注意:您必须在此处考虑4个字符编码:
cp1252
cp1251
,例如cp437
或cp866
type
或utf-16
。它们可以在重定向时用于WriteConsoleW()
命令的输出cmd /U
,例如%
,例如,当使用100%
开关时。注意:Windows控制台显示UCS-2,即仅支持BMP Unicode字符,但复制粘贴甚至可用于? (U+1F60A)等星体字符。请参阅Keep your eye on the code page。
要将Unicode打印到Windows控制台,请参阅What's the deal with Python 3.4, Unicode, different languages and Windows?