【问题标题】:How do I write a command from Command Prompt to a file using Python?如何使用 Python 将命令提示符中的命令写入文件?
【发布时间】:2016-05-17 21:55:17
【问题描述】:

本质上,我想创建一个具有多种选择的脚本来检查主机名上的某些数据。例如,这里的代码可以选择在给定的主机名上 ping 或运行tracert

import os

print("""What did you want to run? (pick a number)
        (1) Ping
        (2) Traceroute""")

runit = raw_input("> ")

print ("Enter a hostname to check")
host = raw_input("> ") #accept input for hostname

if runit == "1":
    os.system("cmd /c ping " + host) 
elif runit == "2":
    os.system("cmd /c tracert " + host)

上面的代码有效,我可以得到结果并手动复制它们,但我希望这能自动完成。我知道我可以使用类似

的方式打开文件
p = open("ping1.txt", "w")

但我不确定如何从命令提示符复制跟踪或 ping 的结果?任何帮助将不胜感激。

【问题讨论】:

标签: python windows subprocess


【解决方案1】:

您可以使用subprocess.Popen 查看输出并写入文件:

from subprocess import Popen, PIPE
print("""What did you want to run? (pick a number)
        (1) Ping
        (2) Traceroute""")

runit = raw_input("> ")

print ("Enter a hostname to check")
host = raw_input("> ") #accept input for hostname

if runit == "1":
    p  = Popen("cmd /c ping " + host, shell=True, stdout=PIPE)
    with open("ping.txt","w") as f:
        for line in iter(p.stdout.readline,""):
            print(line)
            f.write(line)

elif runit == "2":
     p = Popen("cmd /c tracert " + host, shell=True, stdout=PIPE)
     with open("trace.txt", "w") as f:
         for line in iter(p.stdout.readline, ""):
             print(line)
             f.write(line)

为了保持代码干爽并允许用户在选择错误的选项时再次选择,您可以使用带有 str.format 的 while 循环和 dict 来保留选项:

from subprocess import Popen, PIPE

opts = {"1": "ping", "2": "tracert"}

while True:
    print("""What did you want to run? (pick a number)
            (1) Ping
            (2) Traceroute""")
    runit = raw_input("> ")
    if runit in opts:
        host = raw_input("Enter a hostname to check\n> ")  # accept input for hostname
        p = Popen("cmd /c {} {}".format(opts[runit], host), shell=True, stdout=PIPE)
        with open("ping.txt", "w") as f:
            for line in iter(p.stdout.readline, ""):
                print(line)
                f.write(line)
        break
    print("Invalid option")

【讨论】:

  • 是的,这完全符合我的期望。非常感谢!对 shell=1、stdout=PIPE 等子进程参数仍然有点不熟悉,但我找到了该页面并将阅读更多内容。其余的我理解并感激!
  • 不用担心,您通常可以在不设置 shell=True 的情况下传递单个参数列表而侥幸,但我从不使用 Windows,所以我不太确定它是否会如我所知某些命令在使用窗口时需要 shell=True
  • 1- 您可以使用stdout=file 代替 2- 无需重复代码。与this比较
  • @J.F.Sebastian,1. 我知道如何将输出重定向到文件,OP 想要输出到 shell 并保存到它提供的文件中。 2. 编辑会解决这个问题,我建议您在将用户输入转换为 int 时在代码中使用 try/except,您也可以根据我的回答考虑使用 dict,如果数字 > 2,您的代码也会出错已输入,因此这也是您可能想要捕获的内容。
  • @PadraicCunningham:1-您能否指出问题/评论中的一个特定句子,其中 OP 说输出应该同时到文件和标准输出? 2-如果您对我的回答有意见;将它们留在我的答案下(不过,我认为我不需要污染与用户输入的问题错误处理无关的 [subprocess] 问题的答案。顺便说一句,我看不出您在哪里遵循自己的建议(在这种情况下你不应该这样做)。
【解决方案2】:

os.system(command) 在子 shell 中执行命令并在大多数系统上返回其退出状态(至少对于 cmd.exe)。

subprocess 模块非常适合做更多的事情。

您可能想要使用subprocess.check_output,它使用参数运行命令并将其输出作为字节字符串返回。

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)`

【讨论】:

  • 一旦您将输出作为字节字符串,其余的应该是微不足道的。尽管如果您不指定-c count,则如果不能保证命令像ping 一样终止,则“subprocess.check_output()”可能不合适。那么Padraic Cunningham提出的方案就更好了!
【解决方案3】:

要将命令的输出重定向到文件,您可以将stdout 参数传递给subprocess.check_call()

#!/usr/bin/env python2
import subprocess

one_or_two = raw_input("""What did you want to run? (pick a number)
        (1) Ping
        (2) Traceroute
> """)
command = ["", "ping", "tracert"][int(one_or_two)]
host = raw_input("Enter a hostname to check\n> ") 

with open('output.txt', 'wb', 0) as file:
    subprocess.check_call([command, host], stdout=file)

如果除了将输出复制到文件之外,还想在控制台中显示输出,请参阅Displaying subprocess output to stdout and redirecting it

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    相关资源
    最近更新 更多