如何在Python中的随机文件上安全地调用类型?

时间:2015-08-05 20:13:26

标签: python shell python-3.x subprocess popen

所以我试图在某个任意文件上调用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。

如何以这种方式正确打开文件的任何帮助将不胜感激。

1 个答案:

答案 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-8notepad.exe)将文件内容解码为Unicode文本。

注意:您必须在此处考虑4个字符编码:

  1. 文本文件本身的字符编码。它可以是任何内容,例如cp1252
  2. GUI应用程序使用的ANSI代码页,例如cp1251,例如cp437cp866
  3. cmd.exe使用的OEM代码页,例如typeutf-16。它们可以在重定向时用于WriteConsoleW()命令的输出
  4. Unicode API使用的
  5. cmd /U,例如%,例如,当使用100%开关时。注意:Windows控制台显示UCS-2,即仅支持BMP Unicode字符,但复制粘贴甚至可用于? (U+1F60A)等星体字符。
  6. 请参阅Keep your eye on the code page

    要将Unicode打印到Windows控制台,请参阅What's the deal with Python 3.4, Unicode, different languages and Windows?