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

- Executing DOS/Windows Command-Line Commands: Using Python to run commands as if you were in the Windows Command Prompt (
cmd.exe). - 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.

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 aCompletedProcessobject.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. Usingshell=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 tellssubprocessto execute the command through the system's shell (cmd.exe). This allows you to use shell features likedir /worping google.com. Warning: Usingshell=Truecan be a security hazard if the command string comes from untrusted input (e.g., a web form).
Example 2: Running a command with arguments

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()withoutshell=Trueis much safer. - Control:
subprocessgives you fine-grained control over input, output, and error streams. - Functionality:
subprocesscan get the return code and capture output, whichos.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:
- Start the DOSBox process from Python using
subprocess.Popen(). - Use
pywinautoto connect to the DOSBox application window. - Send DOS commands as keystrokes to that window.
- 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. |
