pathlib.PurePosixPath - Pure POSIX Path Operations
Class:
pathlib.PurePosixPath
Inheritance:PurePath→PurePosixPath
Category: File System Operations
Python Version: 3.4+
Overview
pathlib.PurePosixPath is a subclass of PurePath that represents POSIX-style paths (Unix, Linux, macOS) without performing any filesystem I/O operations. It always uses forward slashes (/) as path separators, regardless of the current operating system. Use this class when you need to manipulate POSIX paths on any platform.
📚 Basic Usage
Simple Example
from pathlib import PurePosixPath
# Create POSIX paths (forward slashes on all platforms)
path = PurePosixPath("/home/user/documents/file.txt")
config = PurePosixPath("config") / "app.yaml"
relative = PurePosixPath("../data/input.csv")
print(f"Path: {path}") # /home/user/documents/file.txt
print(f"Config: {config}") # config/app.yaml
print(f"Relative: {relative}") # ../data/input.csv
# POSIX-specific properties
print(f"Parts: {path.parts}") # ('/', 'home', 'user', 'documents', 'file.txt')
print(f"Anchor: {path.anchor}") # /
print(f"Root: {path.root}") # /
Core Methods/Functions
from pathlib import PurePosixPath
# Path creation and manipulation
base = PurePosixPath("/usr/local")
bin_dir = base / "bin"
app_path = bin_dir / "myapp"
print(f"Application path: {app_path}") # /usr/local/bin/myapp
# Path parsing
log_file = PurePosixPath("/var/log/app.log.2024-01-15")
print(f"Directory: {log_file.parent}") # /var/log
print(f"Filename: {log_file.name}") # app.log.2024-01-15
print(f"Stem: {log_file.stem}") # app.log.2024-01-15
# Pattern matching (POSIX shell-style)
pattern_match = PurePosixPath("/home/user/docs/readme.txt").match("*/docs/*")
print(f"Matches pattern: {pattern_match}") # True
Common Patterns
from pathlib import PurePosixPath
# Pattern 1: Unix-style configuration paths
def get_unix_config_path(app_name: str, config_type: str) -> PurePosixPath:
"""Generate Unix-style configuration file path."""
return PurePosixPath("/etc") / app_name / f"{config_type}.conf"
# Pattern 2: Log file rotation paths
def get_log_rotation_path(base_log: PurePosixPath, timestamp: str) -> PurePosixPath:
"""Generate rotated log file path."""
return base_log.with_suffix(f".{timestamp}")
# Pattern 3: Unix directory structure validation
def validate_unix_path(path_str: str) -> bool:
"""Validate if string represents valid Unix path."""
try:
path = PurePosixPath(path_str)
# Check for valid POSIX path characteristics
return (
not any(part.startswith(" ") or part.endswith(" ") for part in path.parts) and
not any("\0" in part for part in path.parts) and
all(len(part) <= 255 for part in path.parts if part != "/")
)
except (TypeError, ValueError):
return False
# Usage examples
config_path = get_unix_config_path("nginx", "server") # /etc/nginx/server.conf
rotated_log = get_log_rotation_path(
PurePosixPath("/var/log/app.log"), "2024-01-15"
) # /var/log/app.log.2024-01-15
print(f"Valid Unix path: {validate_unix_path('/home/user/file.txt')}") # True
print(f"Invalid Unix path: {validate_unix_path('C:\\Windows\\file.txt')}") # False
🔧 PurePosixPath API Reference
Constructor
| Method | Description | Parameters | Return Type | Example |
|---|---|---|---|---|
PurePosixPath(*args) | Create POSIX path | *args: str | PurePath | PurePosixPath | PurePosixPath("/home", "user") |
Inherited Methods (from PurePath)
All methods from PurePath are available with POSIX-specific behavior:
| Method | POSIX-Specific Behavior | Example |
|---|---|---|
joinpath() | Uses / separator | path.joinpath("dir", "file") |
with_name() | Preserves POSIX format | path.with_name("new.txt") |
with_suffix() | Preserves POSIX format | path.with_suffix(".log") |
relative_to() | POSIX path comparison | path.relative_to("/home") |
is_absolute() | Checks for leading / | path.is_absolute() |
match() | Unix shell-style patterns | path.match("*.txt") |
POSIX-Specific Properties
| Property | Description | Type | Example |
|---|---|---|---|
root | Root directory | str | "/" |
anchor | Root directory (same as root) | str | "/" |
parts | Path components with POSIX separators | tuple[str, ...] | ('/', 'home', 'user') |
Special Methods
| Method | POSIX-Specific Behavior | Example |
|---|---|---|
__str__() | Returns POSIX path string | "/home/user/file.txt" |
__truediv__() | Joins with / | path / "subdir" |
🐛 Common Errors and Troubleshooting
Typical Error Messages
from pathlib import PurePosixPath
# Error 1: Windows-style paths on POSIX
try:
# This works but creates unexpected structure
path = PurePosixPath("C:\\Users\\user\\file.txt")
print(path) # C:\Users\user\file.txt (treated as single filename)
print(path.parts) # ('C:\\Users\\user\\file.txt',)
except Exception as e:
print(f"Error: {e}")
# Error 2: Invalid POSIX characters
try:
# Null character is invalid in POSIX paths
path = PurePosixPath("/home/user/file\0.txt")
print(path) # This might work in PurePath but invalid in real filesystem
except ValueError as e:
print(f"Invalid character: {e}")
# Error 3: Relative path operations
try:
absolute = PurePosixPath("/home/user")
relative = PurePosixPath("../../../root/file.txt")
# This can create paths outside intended directory
result = absolute / relative
print(result) # /home/user/../../../root/file.txt
# Use resolve() equivalent logic for safety
except Exception as e:
print(f"Path operation error: {e}")
Debugging Tips
from pathlib import PurePosixPath
def debug_posix_path(path_str: str):
"""Debug POSIX path parsing and properties."""
try:
path = PurePosixPath(path_str)
print(f"Input: '{path_str}'")
print(f"Parsed path: {path}")
print(f"Parts: {path.parts}")
print(f"Is absolute: {path.is_absolute()}")
print(f"Root: '{path.root}'")
print(f"Anchor: '{path.anchor}'")
print(f"Parent: {path.parent}")
print(f"Name: '{path.name}'")
print(f"Stem: '{path.stem}'")
print(f"Suffix: '{path.suffix}'")
# Check for potential issues
if any("\\" in part for part in path.parts):
print("⚠️ WARNING: Backslashes detected - may not be intended POSIX path")
if path.is_absolute() and len(str(path)) > 4096:
print("⚠️ WARNING: Path may exceed typical filesystem limits")
if any(len(part) > 255 for part in path.parts if part != "/"):
print("⚠️ WARNING: Path component exceeds 255 characters")
except Exception as e:
print(f"❌ Error parsing path: {e}")
# Usage
debug_posix_path("/home/user/documents/file.txt")
debug_posix_path("C:\\Windows\\System32") # Shows Windows path issues
debug_posix_path("../../../etc/passwd") # Shows relative path behavior
Error Handling Patterns
from pathlib import PurePosixPath
def safe_posix_path_join(base: str, *components: str) -> PurePosixPath:
"""Safely join POSIX path components with validation."""
try:
base_path = PurePosixPath(base)
# Validate base path
if not base_path.is_absolute():
raise ValueError(f"Base path must be absolute: {base}")
# Validate and join components
result_path = base_path
for component in components:
# Remove leading/trailing slashes from components
clean_component = str(component).strip("/")
# Check for directory traversal attempts
if ".." in clean_component.split("/"):
raise ValueError(f"Directory traversal detected in: {component}")
# Check for invalid characters
if any(char in clean_component for char in ["\0", "\\"]):
raise ValueError(f"Invalid characters in component: {component}")
result_path = result_path / clean_component
return result_path
except Exception as e:
print(f"Path join error: {e}")
return PurePosixPath(base) # Return base path as fallback
def normalize_posix_path(path_str: str) -> PurePosixPath:
"""Normalize path string to valid POSIX path."""
try:
# Convert Windows-style separators
normalized_str = path_str.replace("\\", "/")
# Remove duplicate slashes
while "//" in normalized_str:
normalized_str = normalized_str.replace("//", "/")
# Create path
path = PurePosixPath(normalized_str)
return path
except Exception as e:
print(f"Normalization error: {e}")
return PurePosixPath("/") # Return root as fallback
# Usage
safe_path = safe_posix_path_join("/home/user", "documents", "project")
normalized = normalize_posix_path("C:\\Users\\user\\documents//file.txt")
print(f"Safe path: {safe_path}")
print(f"Normalized: {normalized}")
🎯 Primary Use Cases
1. Unix Configuration Management
Use Case: Manage Unix/Linux configuration file paths across different systems Why PurePosixPath: Consistent POSIX path format regardless of development platform
from pathlib import PurePosixPath
from typing import Dict, List
from dataclasses import dataclass
@dataclass
class UnixService:
name: str
config_dir: str
log_dir: str
data_dir: str
class UnixConfigManager:
"""Manage Unix system configuration paths."""
def __init__(self):
# Standard Unix directory structure
self.system_dirs = {
"config": PurePosixPath("/etc"),
"logs": PurePosixPath("/var/log"),
"data": PurePosixPath("/var/lib"),
"runtime": PurePosixPath("/var/run"),
"temp": PurePosixPath("/tmp"),
"user_config": PurePosixPath("/home"),
"system_bin": PurePosixPath("/usr/bin"),
"local_bin": PurePosixPath("/usr/local/bin")
}
self.services = {
"nginx": UnixService("nginx", "/etc/nginx", "/var/log/nginx", "/var/lib/nginx"),
"postgresql": UnixService("postgresql", "/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"),
"apache": UnixService("apache2", "/etc/apache2", "/var/log/apache2", "/var/lib/apache2"),
"redis": UnixService("redis", "/etc/redis", "/var/log/redis", "/var/lib/redis")
}
def get_service_paths(self, service_name: str) -> Dict[str, PurePosixPath]:
"""Get all standard paths for a Unix service."""
if service_name not in self.services:
raise ValueError(f"Unknown service: {service_name}")
service = self.services[service_name]
return {
"main_config": PurePosixPath(service.config_dir) / f"{service.name}.conf",
"config_dir": PurePosixPath(service.config_dir),
"log_file": PurePosixPath(service.log_dir) / f"{service.name}.log",
"error_log": PurePosixPath(service.log_dir) / f"{service.name}_error.log",
"access_log": PurePosixPath(service.log_dir) / f"{service.name}_access.log",
"pid_file": self.system_dirs["runtime"] / f"{service.name}.pid",
"data_dir": PurePosixPath(service.data_dir),
"socket": self.system_dirs["runtime"] / f"{service.name}.sock"
}
def get_user_service_paths(self, username: str, service_name: str) -> Dict[str, PurePosixPath]:
"""Get user-specific service paths."""
user_home = self.system_dirs["user_config"] / username
return {
"config": user_home / ".config" / service_name / "config.yaml",
"data": user_home / ".local" / "share" / service_name,
"cache": user_home / ".cache" / service_name,
"logs": user_home / ".local" / "share" / service_name / "logs"
}
def generate_systemd_paths(self, service_name: str) -> Dict[str, PurePosixPath]:
"""Generate systemd service file paths."""
return {
"system_service": PurePosixPath("/etc/systemd/system") / f"{service_name}.service",
"user_service": PurePosixPath("/etc/systemd/user") / f"{service_name}.service",
"override_dir": PurePosixPath("/etc/systemd/system") / f"{service_name}.service.d",
"drop_in": PurePosixPath("/etc/systemd/system") / f"{service_name}.service.d" / "override.conf"
}
def get_backup_paths(self, service_name: str, timestamp: str) -> Dict[str, PurePosixPath]:
"""Generate backup paths for service configuration."""
service_paths = self.get_service_paths(service_name)
backup_base = PurePosixPath("/var/backups") / service_name / timestamp
backup_paths = {}
for path_type, original_path in service_paths.items():
if path_type in ["main_config", "config_dir"]:
backup_paths[f"{path_type}_backup"] = backup_base / original_path.name
return backup_paths
# Usage
config_mgr = UnixConfigManager()
# Get nginx service paths
nginx_paths = config_mgr.get_service_paths("nginx")
print("Nginx Service Paths:")
for path_type, path in nginx_paths.items():
print(f" {path_type}: {path}")
# Get user-specific paths
user_paths = config_mgr.get_user_service_paths("john", "myapp")
print("\nUser Service Paths:")
for path_type, path in user_paths.items():
print(f" {path_type}: {path}")
# Generate systemd paths
systemd_paths = config_mgr.generate_systemd_paths("myapp")
print("\nSystemd Paths:")
for path_type, path in systemd_paths.items():
print(f" {path_type}: {path}")
2. Docker and Container Path Management
Use Case: Generate container-internal paths for Docker images and volumes Why PurePosixPath: Containers use Linux filesystem structure regardless of host OS
from pathlib import PurePosixPath
from typing import Dict, List, Optional
from dataclasses import dataclass
@dataclass
class ContainerVolume:
host_path: str
container_path: PurePosixPath
mode: str = "rw"
class DockerPathManager:
"""Manage Docker container filesystem paths."""
def __init__(self, app_name: str):
self.app_name = app_name
# Standard container directory structure
self.container_dirs = {
"app": PurePosixPath("/app"),
"config": PurePosixPath("/etc") / app_name,
"data": PurePosixPath("/var/lib") / app_name,
"logs": PurePosixPath("/var/log") / app_name,
"tmp": PurePosixPath("/tmp"),
"scripts": PurePosixPath("/usr/local/bin"),
"certs": PurePosixPath("/etc/ssl/certs"),
"secrets": PurePosixPath("/run/secrets")
}
def get_application_paths(self) -> Dict[str, PurePosixPath]:
"""Get standard application paths inside container."""
return {
"app_root": self.container_dirs["app"],
"main_script": self.container_dirs["app"] / "main.py",
"requirements": self.container_dirs["app"] / "requirements.txt",
"config_file": self.container_dirs["config"] / "config.yaml",
"environment": self.container_dirs["config"] / ".env",
"data_dir": self.container_dirs["data"],
"log_file": self.container_dirs["logs"] / f"{self.app_name}.log",
"pid_file": self.container_dirs["tmp"] / f"{self.app_name}.pid"
}
def get_volume_mappings(self, host_base_dir: str) -> List[ContainerVolume]:
"""Generate Docker volume mappings."""
host_base = PurePosixPath(host_base_dir)
return [
ContainerVolume(
str(host_base / "config"),
self.container_dirs["config"],
"ro" # Read-only config
),
ContainerVolume(
str(host_base / "data"),
self.container_dirs["data"],
"rw" # Read-write data
),
ContainerVolume(
str(host_base / "logs"),
self.container_dirs["logs"],
"rw" # Read-write logs
),
ContainerVolume(
"/etc/ssl/certs",
self.container_dirs["certs"],
"ro" # Read-only certificates
)
]
def get_dockerfile_paths(self) -> Dict[str, PurePosixPath]:
"""Generate paths for Dockerfile instructions."""
return {
"workdir": self.container_dirs["app"],
"copy_source": PurePosixPath("."),
"copy_dest": self.container_dirs["app"],
"config_template": self.container_dirs["config"] / "config.template.yaml",
"entrypoint_script": self.container_dirs["scripts"] / "entrypoint.sh",
"health_check_script": self.container_dirs["scripts"] / "healthcheck.sh"
}
def get_kubernetes_paths(self) -> Dict[str, PurePosixPath]:
"""Generate paths for Kubernetes pod specifications."""
return {
"config_map_mount": self.container_dirs["config"],
"secret_mount": self.container_dirs["secrets"],
"persistent_volume": self.container_dirs["data"],
"log_volume": self.container_dirs["logs"],
"init_script": self.container_dirs["scripts"] / "init.sh",
"readiness_probe": self.container_dirs["app"] / "health",
"liveness_probe": self.container_dirs["app"] / "health"
}
def generate_dockerfile_content(self) -> str:
"""Generate Dockerfile content with proper paths."""
paths = self.get_dockerfile_paths()
dockerfile_content = f"""
FROM python:3.11-slim
# Create application user and directories
RUN groupadd -r {self.app_name} && useradd -r -g {self.app_name} {self.app_name}
RUN mkdir -p {paths['workdir']} {self.container_dirs['config']} {self.container_dirs['data']} {self.container_dirs['logs']}
# Set working directory
WORKDIR {paths['workdir']}
# Copy application files
COPY {paths['copy_source']} {paths['copy_dest']}
# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy configuration and scripts
COPY scripts/entrypoint.sh {paths['entrypoint_script']}
COPY scripts/healthcheck.sh {paths['health_check_script']}
RUN chmod +x {paths['entrypoint_script']} {paths['health_check_script']}
# Set ownership
RUN chown -R {self.app_name}:{self.app_name} {paths['workdir']} {self.container_dirs['data']} {self.container_dirs['logs']}
# Switch to application user
USER {self.app_name}
# Define volumes
VOLUME ["{self.container_dirs['data']}", "{self.container_dirs['logs']}"]
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
CMD {paths['health_check_script']}
# Entry point
ENTRYPOINT ["{paths['entrypoint_script']}"]
CMD ["python", "main.py"]
""".strip()
return dockerfile_content
def generate_docker_compose_volumes(self, host_base_dir: str) -> Dict[str, str]:
"""Generate docker-compose volume configuration."""
volumes = {}
for volume in self.get_volume_mappings(host_base_dir):
volume_key = f"{volume.host_path}:{volume.container_path}:{volume.mode}"
volumes[f"{self.app_name}_{volume.container_path.name}"] = volume_key
return volumes
# Usage
docker_mgr = DockerPathManager("web-api")
# Get application paths
app_paths = docker_mgr.get_application_paths()
print("Container Application Paths:")
for path_type, path in app_paths.items():
print(f" {path_type}: {path}")
# Get volume mappings
volumes = docker_mgr.get_volume_mappings("/opt/web-api")
print("\nDocker Volume Mappings:")
for volume in volumes:
print(f" {volume.host_path} -> {volume.container_path} ({volume.mode})")
# Generate Dockerfile
dockerfile_content = docker_mgr.generate_dockerfile_content()
print(f"\nGenerated Dockerfile:\n{dockerfile_content}")
# Get Kubernetes paths
k8s_paths = docker_mgr.get_kubernetes_paths()
print("\nKubernetes Paths:")
for path_type, path in k8s_paths.items():
print(f" {path_type}: {path}")
3. Unix Shell Script Path Generation
Use Case: Generate shell script paths and commands for Unix automation Why PurePosixPath: Consistent Unix path format for shell scripts
from pathlib import PurePosixPath
from typing import Dict, List, Optional
class UnixScriptPathGenerator:
"""Generate Unix shell script paths and commands."""
def __init__(self, project_name: str):
self.project_name = project_name
# Standard Unix paths for scripts
self.script_dirs = {
"user_bin": PurePosixPath.home() / ".local" / "bin",
"system_bin": PurePosixPath("/usr/local/bin"),
"project_scripts": PurePosixPath("/opt") / project_name / "scripts",
"cron_scripts": PurePosixPath("/etc/cron.d"),
"init_scripts": PurePosixPath("/etc/init.d"),
"systemd_scripts": PurePosixPath("/etc/systemd/system")
}
# Common Unix utilities paths
self.unix_tools = {
"bash": PurePosixPath("/bin/bash"),
"sh": PurePosixPath("/bin/sh"),
"python": PurePosixPath("/usr/bin/python3"),
"awk": PurePosixPath("/usr/bin/awk"),
"sed": PurePosixPath("/usr/bin/sed"),
"grep": PurePosixPath("/usr/bin/grep"),
"find": PurePosixPath("/usr/bin/find"),
"xargs": PurePosixPath("/usr/bin/xargs")
}
def get_deployment_script_paths(self) -> Dict[str, PurePosixPath]:
"""Generate deployment script paths."""
scripts_dir = self.script_dirs["project_scripts"]
return {
"deploy": scripts_dir / "deploy.sh",
"backup": scripts_dir / "backup.sh",
"restore": scripts_dir / "restore.sh",
"update": scripts_dir / "update.sh",
"rollback": scripts_dir / "rollback.sh",
"health_check": scripts_dir / "health_check.sh",
"cleanup": scripts_dir / "cleanup.sh"
}
def get_maintenance_script_paths(self) -> Dict[str, PurePosixPath]:
"""Generate maintenance script paths."""
scripts_dir = self.script_dirs["project_scripts"]
return {
"log_rotate": scripts_dir / "log_rotate.sh",
"db_backup": scripts_dir / "db_backup.sh",
"disk_cleanup": scripts_dir / "disk_cleanup.sh",
"security_scan": scripts_dir / "security_scan.sh",
"performance_check": scripts_dir / "performance_check.sh",
"dependency_update": scripts_dir / "dependency_update.sh"
}
def generate_backup_script(self, backup_sources: List[str],
backup_destination: str) -> str:
"""Generate backup shell script content."""
script_content = f"""#!/bin/bash
# Backup script for {self.project_name}
# Generated automatically
set -euo pipefail
# Configuration
BACKUP_DEST="{backup_destination}"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_DIR="$BACKUP_DEST/{self.project_name}_$TIMESTAMP"
LOG_FILE="/var/log/{self.project_name}_backup.log"
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Logging function
log_message() {{
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}}
log_message "Starting backup for {self.project_name}"
# Backup sources
"""
for source in backup_sources:
source_path = PurePosixPath(source)
dest_name = source_path.name or "root"
script_content += f"""
# Backup {source}
log_message "Backing up {source}"
if [ -d "{source}" ]; then
tar -czf "$BACKUP_DIR/{dest_name}.tar.gz" -C "{source_path.parent}" "{source_path.name}"
elif [ -f "{source}" ]; then
cp "{source}" "$BACKUP_DIR/"
fi
"""
script_content += f"""
# Create backup manifest
cat > "$BACKUP_DIR/manifest.txt" << EOF
Backup created: $(date)
Project: {self.project_name}
Sources: {', '.join(backup_sources)}
EOF
# Compress backup
cd "$BACKUP_DEST"
tar -czf "{self.project_name}_$TIMESTAMP.tar.gz" "{self.project_name}_$TIMESTAMP"
rm -rf "$BACKUP_DIR"
log_message "Backup completed: {self.project_name}_$TIMESTAMP.tar.gz"
# Cleanup old backups (keep last 7)
find "$BACKUP_DEST" -name "{self.project_name}_*.tar.gz" -mtime +7 -delete
log_message "Backup cleanup completed"
"""
return script_content
def generate_systemd_service_script(self, service_description: str,
exec_command: str,
working_directory: Optional[str] = None) -> str:
"""Generate systemd service file content."""
working_dir = working_directory or f"/opt/{self.project_name}"
service_content = f"""[Unit]
Description={service_description}
After=network.target
Wants=network.target
[Service]
Type=simple
User={self.project_name}
Group={self.project_name}
WorkingDirectory={working_dir}
ExecStart={exec_command}
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths={working_dir} /var/log/{self.project_name}
[Install]
WantedBy=multi-user.target
"""
return service_content
def generate_cron_script(self, schedule: str, command: str,
user: str = "root") -> str:
"""Generate cron job configuration."""
return f"""# Cron job for {self.project_name}
# Schedule: {schedule}
# User: {user}
{schedule} {user} {command}
"""
def get_log_processing_paths(self) -> Dict[str, PurePosixPath]:
"""Generate log processing script paths."""
log_dir = PurePosixPath("/var/log") / self.project_name
return {
"access_log": log_dir / "access.log",
"error_log": log_dir / "error.log",
"debug_log": log_dir / "debug.log",
"audit_log": log_dir / "audit.log",
"archive_dir": log_dir / "archive",
"processed_dir": log_dir / "processed",
"failed_dir": log_dir / "failed"
}
def generate_log_rotation_script(self) -> str:
"""Generate log rotation script."""
log_paths = self.get_log_processing_paths()
script_content = f"""#!/bin/bash
# Log rotation script for {self.project_name}
set -euo pipefail
LOG_DIR="{log_paths['access_log'].parent}"
ARCHIVE_DIR="{log_paths['archive_dir']}"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
# Create archive directory
mkdir -p "$ARCHIVE_DIR"
# Rotate logs
for log_file in "$LOG_DIR"/*.log; do
if [ -f "$log_file" ]; then
log_name=$(basename "$log_file" .log)
# Compress and move to archive
gzip -c "$log_file" > "$ARCHIVE_DIR/${{log_name}}_$TIMESTAMP.log.gz"
# Truncate original log
> "$log_file"
echo "Rotated: $log_file -> $ARCHIVE_DIR/${{log_name}}_$TIMESTAMP.log.gz"
fi
done
# Clean up old archives (keep 30 days)
find "$ARCHIVE_DIR" -name "*.log.gz" -mtime +30 -delete
echo "Log rotation completed for {self.project_name}"
"""
return script_content
# Usage
script_gen = UnixScriptPathGenerator("web-service")
# Get deployment script paths
deploy_paths = script_gen.get_deployment_script_paths()
print("Deployment Script Paths:")
for script_type, path in deploy_paths.items():
print(f" {script_type}: {path}")
# Generate backup script
backup_script = script_gen.generate_backup_script(
["/opt/web-service", "/etc/web-service", "/var/lib/web-service"],
"/var/backups"
)
print(f"\nGenerated Backup Script:\n{backup_script[:500]}...")
# Generate systemd service
systemd_service = script_gen.generate_systemd_service_script(
"Web Service Application",
"/opt/web-service/bin/web-service",
"/opt/web-service"
)
print(f"\nGenerated Systemd Service:\n{systemd_service}")
# Generate cron job
cron_job = script_gen.generate_cron_script(
"0 2 * * *", # Daily at 2 AM
"/opt/web-service/scripts/backup.sh"
)
print(f"\nGenerated Cron Job:\n{cron_job}")
🎯 When to Use pathlib.PurePosixPath
✅ Ideal Use Cases
- Unix/Linux configuration management on any development platform
- Docker and container path generation (containers use Linux filesystem)
- Shell script generation that will run on Unix systems
- CI/CD pipeline paths (most CI systems use Linux containers)
- Cross-platform development targeting Unix deployment
- URL path manipulation (URLs use forward slashes like POSIX)
- Git repository paths (Git uses POSIX-style paths internally)
- Package management systems that follow Unix conventions
❌ When NOT to Use pathlib.PurePosixPath
- Windows-specific applications (use
PureWindowsPathinstead) - Need actual filesystem I/O (use
PosixPathinstead) - Working with native Windows paths (backslashes, drive letters)
- Legacy systems requiring specific path formats
Alternative Solutions
- pathlib.PureWindowsPath: For Windows-specific path manipulation
- pathlib.Path: For filesystem I/O operations (auto-selects platform)
- pathlib.PosixPath: For POSIX paths with filesystem operations
- os.path.posix: Legacy POSIX path operations
- urllib.parse: For URL path manipulation
Additional Learning Resources
Official Python Resources
Unix/Linux Path Standards
Related Topics
- Docker filesystem documentation
- Kubernetes volume mounting
- Unix shell scripting best practices
- Linux system administration guides