Interacting With The Operating System Using Python

List all files under the directory

import os
import stat
import pwd
import grp
import time

def list_files(path='.'):
    try:
        # 获取目录中的所有文件和子目录
        files = os.listdir(path)
    except OSError as e:
        print(f"Error accessing directory: {e}")
        return

    # 打印类似于 ls -al 的输出
    for file in files:
        file_path = os.path.abspath(os.path.join(path, file))
        try:
            file_stat = os.stat(file_path)
        except OSError as e:
            print(f"Error accessing file: {e}")
            continue

        # 获取文件类型和权限
        mode = file_stat.st_mode
        file_type = '-' if stat.S_ISREG(mode) else 'd' if stat.S_ISDIR(mode) else 'l' if stat.S_ISLNK(mode) else '?'
        permissions = ''.join([
            'r' if mode & stat.S_IRUSR else '-',
            'w' if mode & stat.S_IWUSR else '-',
            'x' if mode & stat.S_IXUSR else '-',
            'r' if mode & stat.S_IRGRP else '-',
            'w' if mode & stat.S_IWGRP else '-',
            'x' if mode & stat.S_IXGRP else '-',
            'r' if mode & stat.S_IROTH else '-',
            'w' if mode & stat.S_IWOTH else '-',
            'x' if mode & stat.S_IXOTH else '-'
        ])

        # 获取硬链接数
        n_links = file_stat.st_nlink

        # 获取所有者和组
        owner = pwd.getpwuid(file_stat.st_uid).pw_name
        group = grp.getgrgid(file_stat.st_gid).gr_name

        # 获取文件大小
        size = file_stat.st_size

        # 获取最后修改时间
        mtime = time.strftime('%Y-%m-%d %H:%M', time.localtime(file_stat.st_mtime))

        # 打印文件信息
        print(f"{file_type}{permissions} {n_links} {owner} {group} {size} {mtime} {file}")

# 调用函数列出当前目录的文件
list_files('/tmp')

Check whether the file exists

  • os.path.exists(filename): 检查路径是否存在。
  • os.path.isfile(filename): 检查路径是否为文件。
  • os.path.isdir(filename): 检查路径是否为目录。
  • 日志记录: 使用 logging 模块记录信息、警告和错误。
  • 异常处理 (try/except 块): 捕获并处理可能的异常,确保程序的鲁棒性。
  • os.access(filename, os.R_OK): 检查文件是否可读。
  • os.access(filename, os.W_OK): 检查文件是否可写。
  • os.access(filename, os.X_OK): 检查文件是否可执行。
  • argparse 模块: 用于处理命令行参数。
import os
import logging
import argparse

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', filename='file_check.log')

def check_file(filename):
    try:
        if os.path.exists(filename):
            if os.path.isfile(filename):
                logging.info(f"'{filename}' exists and is a file.")
                info = {
                    'exists': True,
                    'is_file': True,
                    'is_directory': False,
                    'readable': os.access(filename, os.R_OK),
                    'writable': os.access(filename, os.W_OK),
                    'executable': os.access(filename, os.X_OK),
                    'size': os.path.getsize(filename),
                    'last_modified': os.path.getmtime(filename)
                }
                return info
            elif os.path.isdir(filename):
                logging.info(f"'{filename}' exists but is a directory.")
                return {'exists': True, 'is_file': False, 'is_directory': True}
            else:
                logging.warning(f"'{filename}' exists but is neither a file nor a directory.")
                return {'exists': False}
        else:
            logging.info(f"'{filename}' does not exist.")
            return {'exists': False}
    except Exception as e:
        logging.error(f"Error checking file '{filename}': {e}")
        return {'exists': False, 'error': str(e)}

def format_file_info(info):
    if info['exists']:
        if info.get('is_file'):
            return (
                f"File exists\n"
                f"Readable: {info['readable']}\n"
                f"Writable: {info['writable']}\n"
                f"Executable: {info['executable']}\n"
                f"Size: {info['size']} bytes\n"
                f"Last modified: {time.ctime(info['last_modified'])}\n"
            )
        elif info.get('is_directory'):
            return "Exists and is a directory"
    else:
        return "File does not exist"

def main():
    parser = argparse.ArgumentParser(description="Check if a file exists and get its properties.")
    parser.add_argument("filename", type=str, help="The path to the file to check.")
    args = parser.parse_args()

    info = check_file(args.filename)
    print(format_file_info(info))

if __name__ == "__main__":
    main()

Create a new directory

import os
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', filename='directory_creation.log')

def create_directory(directory):
    try:
        os.makedirs(directory, exist_ok=True)
        logging.info(f"Directory '{directory}' created successfully or already exists.")
    except OSError as e:
        logging.error(f"Error creating directory '{directory}': {e}")

create_directory('/path/to/your/multi/level/directory')

Bin Management

import os
import shutil
import uuid
from pathlib import Path

class TrashBin:
    def __init__(self, bin_path='/tmp/my_bin'):
        self.bin_path = Path(os.path.abspath(bin_path))
        self.bin_path.mkdir(parents=True, exist_ok=True)
        self.index_file = self.bin_path / 'index.txt'
        self._load_index()

    def _load_index(self):
        self.index = {}
        if self.index_file.exists():
            with open(self.index_file, 'r') as f:
                for line in f:
                    original_path, trash_id = line.strip().split(',')
                    self.index[trash_id] = original_path

    def _save_index(self):
        with open(self.index_file, 'w') as f:
            for trash_id, original_path in self.index.items():
                f.write(f"{original_path},{trash_id}\n")

    def delete(self, path):
        path = Path(path)
        if not path.exists():
            print("File/Directory does not exist")
            return

        trash_id = str(uuid.uuid4())
        trash_path = self.bin_path / trash_id

        shutil.move(str(path), trash_path)
        self.index[trash_id] = str(path)
        self._save_index()
        print(f"Moved to trash bin: {path} -> {trash_path}")

    def restore(self, trash_id):
        trash_path = self.bin_path / trash_id
        if trash_id not in self.index or not trash_path.exists():
            print("No such ID in the trash bin")
            return

        original_path = Path(self.index[trash_id])
        if original_path.exists():
            print("Original location already has a file/directory with the same name")
            return

        shutil.move(trash_path, original_path)
        del self.index[trash_id]
        self._save_index()
        print(f"Restored: {trash_path} -> {original_path}")

    def permanently_delete(self, trash_id):
        trash_path = self.bin_path / trash_id
        if trash_id not in self.index or not trash_path.exists():
            print("No such ID in the trash bin")
            return

        if trash_path.is_dir():
            shutil.rmtree(trash_path)
        else:
            trash_path.unlink()
        
        del self.index[trash_id]
        self._save_index()
        print(f"Permanently deleted: {trash_path}")

    def list_contents(self):
        if not self.index:
            print("Trash bin is empty")
        else:
            for trash_id, original_path in self.index.items():
                print(f"ID: {trash_id}, Original Path: {original_path}")

    def empty(self):
        for trash_id in list(self.index.keys()):
            self.permanently_delete(trash_id)
        print("Trash bin emptied")

# Example usage:
# trash_bin = TrashBin()
# trash_bin.delete('test_file.txt')  # Move file to trash bin
# trash_bin.list_contents()  # List contents of the trash bin
# trash_bin.restore('some-uuid')  # Restore file
# trash_bin.permanently_delete('some-uuid')  # Permanently delete file
# trash_bin.empty()  # Empty the trash bin
  1. 删除文件/文件夹
    • delete(path): 将指定文件/文件夹移送到垃圾箱,并赋予唯一 ID。
  2. 恢复文件/文件夹
    • restore(trash_id): 将指定 ID 的文件/文件夹从垃圾箱恢复到原始位置。
  3. 彻底删除文件/文件夹
    • permanently_delete(trash_id): 将指定 ID 的文件/文件夹从垃圾箱彻底删除。
  4. 查询垃圾箱内容
    • list_contents(): 列出垃圾箱中的所有文件/文件夹及其对应的原始路径。
  5. 清空垃圾箱
    • empty(): 清空垃圾箱中的所有文件/文件夹。

Rename or Move File

  • Method 1: Using shutil.move

    import shutil
    
    shutil.move('source_file.txt', 'destination_file.txt')
    
  • Method 2: Using os.rename

    import os
    
    os.rename('source_file.txt', 'destination_file.txt')
    
  • Method 3: Using pathlib.Path.rename

    from pathlib import Path
    
    Path('source_file.txt').rename('destination_file.txt')
    
  • Method 4: Using os.replace

    import os
    
    os.replace('source_file.txt', 'destination_file.txt')
    
  • Method 5: Using pathlib.Path.replace

    from pathlib import Path
    
    Path('source_file.txt').replace('destination_file.txt')
    

Execute Cmd

  • Method 1: Using subprocess.run

    import subprocess
    
    result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
    result = subprocess.run('ls -l', capture_output=True, text=True, shell=True)
    print(result.stdout)
    
  • Method 2: Using subprocess.call

    import subprocess
    
    return_code = subprocess.call(['ls', '-l'])
    print(f"Return code: {return_code}")
    
  • Method 3: Using os.system

    import os
    
    return_code = os.system('ls -l')
    print(f"Return code: {return_code}")
    
  • Method 4: Using subprocess.Popen

    import subprocess
    
    process = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = process.communicate()
    print(stdout.decode())
    
  • Method 5: Using os.popen

    import os
    
    with os.popen('ls -l') as stream:
        output = stream.read()
    print(output)
    
  • Method 6: Using subprocess.check_output

    import subprocess
    
    output = subprocess.check_output(['ls', '-l'], text=True)
    print(output)