Read & Write Files
TL;DR
Read and write files on remote machines using the CMDOP Python SDK. Supports text and binary reads, partial reads with offset and limit, line-based reading with tail, writing with custom permissions, atomic writes to prevent corruption, file copy/move/delete, permission changes, and working with JSON, YAML, and INI config files β all without shell commands.
Direct file access on remote machines without shell commands.
How do I read a file from a remote server?
from cmdop import AsyncCMDOPClient
async with AsyncCMDOPClient.remote(api_key="cmd_xxx") as client:
# Read the entire file as a string
content = await client.files.read("my-server", "/etc/hostname")
print(content)
# Read a file with explicit encoding
text = await client.files.read(
"my-server",
"/app/config.json",
encoding="utf-8"
)How do I read a binary file?
# Read raw bytes from a remote file (images, executables, etc.)
data = await client.files.read_bytes("my-server", "/path/to/image.png")
# Save the downloaded bytes to a local file
with open("image.png", "wb") as f:
f.write(data)How do I read only part of a file?
# Read just the first 1000 bytes of a large file
content = await client.files.read(
"my-server",
"/var/log/large.log",
limit=1000
)
# Read 1000 bytes starting from byte offset 5000
content = await client.files.read(
"my-server",
"/var/log/large.log",
offset=5000,
limit=1000
)How do I read a file line by line or tail the last N lines?
# Read the entire file and return each line as a list element
lines = await client.files.read_lines("my-server", "/etc/hosts")
for line in lines:
print(line)
# Read only the last 100 lines (equivalent to tail -n 100)
last_lines = await client.files.read_lines(
"my-server",
"/var/log/app.log",
tail=100
)How do I write a file to a remote server?
# Write a plain text string to a remote file (creates or overwrites)
await client.files.write(
"my-server",
"/app/config.yaml",
"key: value\nother: data\n"
)
# Write a file and set restrictive permissions (owner-read only)
await client.files.write(
"my-server",
"/app/secret.key",
"secret-content",
mode=0o600 # Only owner can read
)How do I write binary data to a remote file?
# Read a local binary file into memory
with open("local_image.png", "rb") as f:
data = f.read()
# Write the binary data to a remote path
await client.files.write_bytes(
"my-server",
"/app/image.png",
data
)How do I append content to an existing file?
# Add text to the end of a file without overwriting existing content
await client.files.append(
"my-server",
"/var/log/app.log",
"New log entry\n"
)How do I perform an atomic write to prevent corruption?
# Write to a temp file first, then rename β prevents partial writes on failure
await client.files.write(
"my-server",
"/app/config.yaml",
new_config,
atomic=True # Prevents partial writes
)How do I get file metadata and info?
# Retrieve detailed metadata for a single file
info = await client.files.info("my-server", "/app/data.json")
print(f"Size: {info.size} bytes")
print(f"Modified: {info.modified_at}")
print(f"Mode: {oct(info.mode)}")
print(f"Owner: {info.owner}")
print(f"Is directory: {info.is_dir}")How do I check if a file exists before writing?
# Returns True/False without reading the file content
exists = await client.files.exists("my-server", "/app/config.yaml")
# Only create the config file if it does not already exist
if not exists:
await client.files.write("my-server", "/app/config.yaml", default_config)How do I copy a file on a remote server?
# Duplicate a file to a new path on the same remote server
await client.files.copy(
"my-server",
"/app/config.yaml",
"/app/config.yaml.backup"
)How do I move or rename a remote file?
# Move or rename a file (atomic operation on most filesystems)
await client.files.move(
"my-server",
"/app/old_name.txt",
"/app/new_name.txt"
)How do I delete files or directories?
# Delete a single file
await client.files.delete("my-server", "/tmp/temp_file.txt")
# Delete a directory and all its contents recursively
await client.files.delete(
"my-server",
"/tmp/temp_dir",
recursive=True
)How do I change file permissions and ownership?
# Set file permissions (e.g., make a script executable)
await client.files.chmod("my-server", "/app/script.sh", 0o755)
# Change file owner and group (requires root privileges)
await client.files.chown("my-server", "/app/data", "deploy", "deploy")How do I create directories on a remote server?
# Create a single directory
await client.files.mkdir("my-server", "/app/logs")
# Create nested directories in one call (equivalent to mkdir -p)
await client.files.mkdir(
"my-server",
"/app/data/cache/images",
parents=True
)Error Handling
from cmdop.exceptions import (
FileNotFoundError,
PermissionError,
IsADirectoryError
)
try:
content = await client.files.read("my-server", "/etc/shadow")
except PermissionError:
# Raised when the user lacks read access to the file
print("Access denied")
except FileNotFoundError:
# Raised when the specified path does not exist
print("File not found")How do I read and write JSON, YAML, and INI config files?
JSON
import json
# Read a JSON config file and parse it into a Python dict
content = await client.files.read("my-server", "/app/config.json")
config = json.loads(content)
# Modify a value in the parsed config
config["debug"] = True
# Serialize back to JSON and write to the remote server
await client.files.write(
"my-server",
"/app/config.json",
json.dumps(config, indent=2)
)YAML
import yaml
# Read a YAML config file and parse it into a Python dict
content = await client.files.read("my-server", "/app/config.yaml")
config = yaml.safe_load(content)
# Update a nested config value
config["logging"]["level"] = "debug"
# Serialize back to YAML and write to the remote server
await client.files.write(
"my-server",
"/app/config.yaml",
yaml.dump(config)
)INI
import configparser
import io
# Read an INI config file and parse it with ConfigParser
content = await client.files.read("my-server", "/app/settings.ini")
config = configparser.ConfigParser()
config.read_string(content)
# Update a value in the [database] section
config["database"]["host"] = "new-host"
# Serialize back to INI format and write to the remote server
output = io.StringIO()
config.write(output)
await client.files.write(
"my-server",
"/app/settings.ini",
output.getvalue()
)What are the best practices for remote file operations?
1. Use Atomic Writes for Config
# Atomic write prevents corruption if the connection drops mid-write
await client.files.write(
"my-server",
"/app/config.yaml",
new_config,
atomic=True
)2. Create Backups
# Always back up a file before modifying it in place
await client.files.copy(
"my-server",
"/app/config.yaml",
f"/app/config.yaml.{datetime.now().isoformat()}"
)3. Handle Large Files with Streaming
# For files too large to hold in memory, use download instead of read
await client.files.download(
"my-server",
"/data/large.db",
"./large.db"
)Next
- File Transfer β Upload/download large files
- Directory Browsing β List and navigate
Last updated on