杰瑞科技汇

Python中dos system命令如何正确使用?

Of course. The term "DOS system" in Python can refer to two main things:

Python中dos system命令如何正确使用?-图1
(图片来源网络,侵删)
  1. Executing DOS/Windows Command-Line Commands: Using Python to run commands as if you were in the Windows Command Prompt (cmd.exe).
  2. Accessing MS-DOS Legacy Systems: Using Python to interact with old MS-DOS machines, often through emulators or network connections.

I will cover both, starting with the most common use case.


Executing DOS/Windows Commands from Python

This is the most frequent meaning. You want to run a command like dir, ping google.com, or copy file1.txt file2.txt from your Python script and get the output.

The modern and recommended way to do this in Python 3.5+ is by using the subprocess module. It's powerful, flexible, and secure.

The subprocess Module (Recommended)

The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.

Python中dos system命令如何正确使用?-图2
(图片来源网络,侵删)

Key Functions:

  • subprocess.run(): The recommended, all-in-one function for most use cases. It runs the command, waits for it to complete, and returns a CompletedProcess object.
  • subprocess.Popen(): A more low-level and powerful class. Use this when you need more control, such as running a process in the background or interacting with its input/output streams in real-time.

Examples with subprocess.run()

Let's assume you want to list the files in the current directory.

Example 1: Running a simple command and capturing its output

import subprocess
# The command to run. Use a list of strings.
# On Windows, 'dir' is the command. On Linux/macOS, it's 'ls'.
command = ['dir']
# Run the command and capture the output
# text=True decodes stdout/stderr from bytes to string using the default encoding
# check=True will raise a CalledProcessError if the command returns a non-zero exit code (i.e., fails)
try:
    result = subprocess.run(command, capture_output=True, text=True, check=True, shell=True)
    # Print the standard output
    print("Command executed successfully!")
    print("STDOUT:")
    print(result.stdout)
except subprocess.CalledProcessError as e:
    # This block runs if the command fails
    print(f"Command failed with return code {e.returncode}")
    print("STDERR:")
    print(e.stderr)

Explanation:

  • command = ['dir']: The command as a list of arguments. Using shell=True (see below) allows you to use a single string.
  • capture_output=True: Captures the standard output and standard error streams.
  • text=True: Decodes the output as text (instead of bytes).
  • check=True: Automatically raises an exception if the command returns an error code. This is very useful for scripting.
  • shell=True: This is important on Windows. It tells subprocess to execute the command through the system's shell (cmd.exe). This allows you to use shell features like dir /w or ping google.com. Warning: Using shell=True can be a security hazard if the command string comes from untrusted input (e.g., a web form).

Example 2: Running a command with arguments

Python中dos system命令如何正确使用?-图3
(图片来源网络,侵删)

Let's get a directory listing in wide format.

import subprocess
# Command with arguments
command = 'dir /w' # Using a string because shell=True is used
try:
    result = subprocess.run(command, shell=True, capture_output=True, text=True, check=True)
    print("STDOUT:")
    print(result.stdout)
except subprocess.CalledProcessError as e:
    print(f"Error: {e.stderr}")

Example 3: Running a command and piping its output to another command

This is a powerful feature of the command line. Let's find all .py files in the current directory and count them.

import subprocess
# We use a single string with shell=True to use the pipe '|'
command = 'dir /b *.py | find /c ".'
try:
    result = subprocess.run(command, shell=True, capture_output=True, text=True, check=True)
    # The output of 'find /c' is something like "---------- X"
    # We just want the number
    count = result.stdout.strip().split(' ')[-1]
    print(f"Found {count} Python files.")
except subprocess.CalledProcessError as e:
    print(f"Error: {e.stderr}")

The "Old Way": os.system()

Before subprocess was the standard, os.system() was used. It's simple but less flexible and less secure.

import os
# This will execute the command, but its output will go directly to the console.
# You cannot capture it into a variable.
return_code = os.system('dir /w')
print(f"The command finished with return code: {return_code}")

Why subprocess is better than os.system():

  • Security: os.system() is vulnerable to shell injection if you pass user-supplied input to it. subprocess.run() without shell=True is much safer.
  • Control: subprocess gives you fine-grained control over input, output, and error streams.
  • Functionality: subprocess can get the return code and capture output, which os.system() cannot do easily.

Accessing a Legacy MS-DOS System

This is a niche but interesting use case. You would typically do this if you have an old DOS machine connected to your network or running in an emulator (like DOSBox).

Method A: Using telnetlib for a Network Connection

If the DOS machine is running a Telnet server, you can use Python's built-in telnetlib to connect and send commands.

import telnetlib
import time
# --- Configuration ---
DOS_HOST = '192.168.1.100'  # IP address of the DOS machine
DOS_PORT = 23              # Default Telnet port
USERNAME = 'user'          # Username for the Telnet server (if any)
PASSWORD = 'password'      # Password for the Telnet server (if any)
try:
    # Connect to the Telnet server
    tn = telnetlib.Telnet(DOS_HOST, DOS_PORT)
    # Login (if required)
    tn.read_until(b"login: ")
    tn.write(USERNAME.encode('ascii') + b"\n")
    tn.read_until(b"Password: ")
    tn.write(PASSWORD.encode('ascii') + b"\n")
    # Wait for the command prompt
    # You need to know what the prompt looks like, e.g., 'C:\>'
    time.sleep(1) # Give it a moment to respond
    prompt = tn.read_until(b'>').decode('ascii')
    print("Successfully connected to DOS machine.")
    print(f"Current prompt: {prompt}")
    # Send a command
    command = "dir\n" # The newline \n is crucial to execute the command
    tn.write(command.encode('ascii'))
    # Read the output
    time.sleep(2) # Wait for the command to finish
    output = tn.read_very_eager().decode('ascii')
    print("\n--- DOS Command Output ---")
    print(output)
    # Close the connection
    tn.close()
except ConnectionRefusedError:
    print(f"Connection to {DOS_HOST}:{DOS_PORT} failed. Is the Telnet server running?")
except Exception as e:
    print(f"An error occurred: {e}")

Method B: Interacting with an Emulator (e.g., DOSBox)

You can automate an emulator like DOSBox by controlling its input. A common way is to run DOSBox in a "debug" mode or by sending keystrokes to its window.

This is more complex and often requires a GUI automation library like pywinauto on Windows.

Conceptual Workflow:

  1. Start the DOSBox process from Python using subprocess.Popen().
  2. Use pywinauto to connect to the DOSBox application window.
  3. Send DOS commands as keystrokes to that window.
  4. Read the text from the window's screen buffer to get the output.

This is an advanced topic and highly dependent on the specific emulator and operating system.

Summary

Task Recommended Method Why?
Run a simple command and get output subprocess.run(command, shell=True, capture_output=True, text=True) Modern, safe, flexible, and the standard way.
Run a command and see its output live subprocess.Popen(command, shell=True) Gives you more control over input/output streams for real-time interaction.
Quick & simple command (no output capture) os.system(command) Simple, but less powerful and less secure. Avoid for new scripts.
Connect to a remote DOS machine telnetlib Built-in library for standard network protocol.
Control a local DOS emulator subprocess.Popen + pywinauto (or similar) Requires external libraries for GUI automation.
分享:
扫描分享到社交APP
上一篇
下一篇