杰瑞科技汇

Python如何用import smb操作SMB共享?

Of course. Here’s a comprehensive guide on how to import and use the smb library in Python, which is the most common way to interact with SMB (Server Message Block) protocol shares.

Python如何用import smb操作SMB共享?-图1
(图片来源网络,侵删)

What is the smb library?

The smb library is a pure Python implementation of the SMB/CIFS protocol. It allows you to programmatically access files and printers on remote servers, just as if they were on your local machine. It supports both SMBv1 and the more modern SMBv2/v3 protocols.

Step 1: Installation

First, you need to install the library. It's available on PyPI and can be installed using pip.

pip install smb

Step 2: Basic Import

Once installed, you can import the necessary modules into your Python script. The main module is smb.SMBConnection.

from smb.SMBConnection import SMBConnection
from smb.base import SharedFile

Step 3: Establishing a Connection

To interact with an SMB share, you first need to create a connection object. The primary class for this is SMBConnection.

Python如何用import smb操作SMB共享?-图2
(图片来源网络,侵删)

Key Parameters for SMBConnection:

  • session: The remote server's hostname or IP address.
  • my_name: Your client's NetBIOS name. This can often be a dummy name like 'my-pc'.
  • remote_name: The remote server's NetBIOS name. This can often be the same as the session name or 'server'.
  • username: Your username for the SMB share.
  • password: Your password for the SMB share.
  • domain: (Optional) The Windows domain or workgroup name.
  • use_ntlm_v2: (Optional) It's highly recommended to set this to True for modern security. It defaults to True.
  • sign_options: (Optional) For message signing. Defaults to 0 (disabled).

Example:

# Replace with your actual server details
server_ip = '192.168.1.100'
server_name = 'FILESERVER'
client_machine_name = 'MYLAPTOP'
username = 'user'
password = 'password'
domain = 'WORKGROUP' # Or your domain name like 'CORP'
try:
    # Create the connection object
    conn = SMBConnection(
        session=server_ip,
        my_name=client_machine_name,
        remote_name=server_name,
        username=username,
        password=password,
        domain=domain,
        use_ntlm_v2=True
    )
    # Connect to the remote server
    conn.connect(server_ip)
    print("Successfully connected to the server!")
    # ... perform operations here ...
except Exception as e:
    print(f"Failed to connect: {e}")
finally:
    # Always close the connection when done
    if conn:
        conn.close()
        print("Connection closed.")

Step 4: Common Operations

Once connected, you can perform various file operations.

List Available Shares

To see what shares are available on the server.

Python如何用import smb操作SMB共享?-图3
(图片来源网络,侵删)
if conn:
    shares = conn.listShares()
    print("\nAvailable shares:")
    for share in shares:
        print(f"- {share.name} ({share.comment})")

List Files in a Share

To list the contents of a specific share (e.g., public).

share_name = 'public'
if conn:
    print(f"\nFiles in share '{share_name}':")
    files = conn.listPath(share_name, '/')
    for item in files:
        # item is a SharedFile object
        # name, isDirectory, size, etc.
        print(f"{'[DIR]' if item.isDirectory else '[FILE]'} {item.name} - Size: {item.file_size} bytes")

Download a File

To download a file from the share to your local machine.

remote_file_path = '/document.txt'
local_file_path = 'C:/temp/document_downloaded.txt' # Or '/tmp/document_downloaded.txt'
if conn:
    with open(local_file_path, 'wb') as local_file:
        # The 'retrieveFile' method returns a generator
        # We can iterate over it to get chunks or just write it directly
        for chunk in conn.retrieveFile(share_name, remote_file_path, local_file):
            pass # The chunk is written to the file object by retrieveFile
    print(f"\nFile downloaded successfully to {local_file_path}")

Upload a File

To upload a local file to the share.

local_upload_path = 'C:/temp/my_report.pdf'
remote_upload_path = '/reports/my_report.pdf'
if conn:
    with open(local_upload_path, 'rb') as local_file:
        # The 'storeFile' method takes the file-like object and writes it to the share
        conn.storeFile(share_name, remote_upload_path, local_file)
    print(f"\nFile uploaded successfully to {remote_upload_path}")

Create a Directory

new_dir_path = '/new_folder'
if conn:
    try:
        conn.createDirectory(share_name, new_dir_path)
        print(f"\nDirectory created: {new_dir_path}")
    except Exception as e:
        print(f"Could not create directory: {e}")

Delete a File

file_to_delete = '/document.txt'
if conn:
    try:
        conn.delete(share_name, file_to_delete)
        print(f"\nFile deleted: {file_to_delete}")
    except Exception as e:
        print(f"Could not delete file: {e}")

Complete Example Script

Here is a full, runnable script that combines connection, listing, and a download operation.

import os
from smb.SMBConnection import SMBConnection
# --- Configuration ---
SERVER_IP = '192.168.1.100'
SERVER_NAME = 'FILESERVER'
CLIENT_NAME = 'PYTHON_CLIENT'
USERNAME = 'user'
PASSWORD = 'password'
DOMAIN = 'WORKGROUP'
SHARE_NAME = 'public'
def main():
    """
    Main function to demonstrate SMB operations.
    """
    conn = None
    try:
        # 1. Establish connection
        print(f"Connecting to {SERVER_IP}...")
        conn = SMBConnection(
            session=SERVER_IP,
            my_name=CLIENT_NAME,
            remote_name=SERVER_NAME,
            username=USERNAME,
            password=PASSWORD,
            domain=DOMAIN,
            use_ntlm_v2=True
        )
        conn.connect(SERVER_IP)
        print("Connection successful!")
        # 2. List files in the share
        print(f"\nListing files in share '{SHARE_NAME}':")
        files = conn.listPath(SHARE_NAME, '/')
        for item in files:
            if not item.name in ('.', '..'): # Skip special directory entries
                item_type = "Directory" if item.isDirectory else "File"
                print(f"- {item.name} ({item_type}, {item.file_size} bytes)")
        # 3. Download a specific file (e.g., 'readme.txt')
        remote_file = '/readme.txt'
        local_download_path = os.path.join(os.getcwd(), 'smb_readme.txt')
        if any(f.name == 'readme.txt' for f in files if not f.isDirectory):
            print(f"\nDownloading '{remote_file}' to '{local_download_path}'...")
            with open(local_download_path, 'wb') as local_file:
                # retrieveFile writes chunks to the file object
                for chunk in conn.retrieveFile(SHARE_NAME, remote_file, local_file):
                    pass
            print("Download complete!")
        else:
            print(f"\nFile '{remote_file}' not found in the share.")
    except Exception as e:
        print(f"\nAn error occurred: {e}")
        import traceback
        traceback.print_exc()
    finally:
        # 4. Close the connection
        if conn:
            conn.close()
            print("\nConnection closed.")
if __name__ == '__main__':
    main()

Important Considerations

  • Firewall: Ensure that the server's firewall allows incoming connections on the SMB ports. The default ports are TCP 445 (SMB over IP) and UDP 137, 138 (NetBIOS) and TCP 139 (NetBIOS Session Service).
  • Permissions: The user you are connecting with must have the necessary read/write permissions on the target share and files/directories.
  • Security: Using SMBv1 is highly discouraged due to security vulnerabilities (like EternalBlue). The smb library defaults to NTLMv2, which is much more secure. For the highest security, ensure your server supports and is configured for SMBv3 with encryption.
  • Error Handling: Always wrap your SMB operations in try...except blocks. Network connections and file operations can fail for many reasons (e.g., wrong credentials, file not found, network outage).
分享:
扫描分享到社交APP
上一篇
下一篇