You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda Python写入/tmp目录遇只读文件系统错误排查

搞定AWS Lambda里解压ZIP时的只读文件系统错误

问题出在哪?

你碰到的OSError: Errno 30 Read-only file system其实是个常见坑——zipfile.ZipFile.extractall()默认会把文件解压到当前工作目录,而Lambda的当前工作目录是/var/task,这个目录是只读的,根本没法写新东西。本地测试没问题是因为你本地的当前目录有写入权限,自然不会报错。

怎么解决?

核心就是给extractall()明确指定path参数,把解压路径指向Lambda唯一可写的临时目录/tmp,这样所有解压操作都在/tmp里完成,完全不会碰只读的/var/task。

修正后的完整代码示例

import zipfile
import boto3
import os
from io import BytesIO

def lambda_handler(event, context):
    # 1. 从API拉取ZIP二进制数据(这里是示例,换成你实际的API调用逻辑)
    api_response = get_zip_from_api()
    zip_binary = api_response.content
    
    # 2. 把ZIP存到/tmp目录
    zip_path = "/tmp/myZip.zip"
    with open(zip_path, "wb") as f:
        f.write(zip_binary)
    
    # 3. 解压到/tmp下的专属目录(避免和其他临时文件混在一起)
    extract_dir = "/tmp/extracted_files"
    os.makedirs(extract_dir, exist_ok=True)  # 先确保目录存在,不存在就创建
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        zip_ref.extractall(path=extract_dir)  # 重点:指定解压到/tmp下的目录
    
    # 4. 处理解压后的文件(这里写你实际的业务逻辑,比如修改内容、解析数据等)
    for root, dirs, files in os.walk(extract_dir):
        for file in files:
            file_path = os.path.join(root, file)
            print(f"正在处理文件: {file_path}")
            # 你的处理代码写在这里
    
    # 5. 把处理后的文件重新压缩
    rezip_path = "/tmp/processed_files.zip"
    with zipfile.ZipFile(rezip_path, 'w', zipfile.ZIP_DEFLATED) as zip_ref:
        for root, dirs, files in os.walk(extract_dir):
            for file in files:
                file_path = os.path.join(root, file)
                # 用相对路径作为压缩包内的路径,避免把/tmp的完整路径也打包进去
                arcname = os.path.relpath(file_path, extract_dir)
                zip_ref.write(file_path, arcname=arcname)
    
    # 6. 上传到目标S3桶
    s3 = boto3.client('s3')
    bucket_name = "你的S3桶名称"
    s3_key = "processed/processed_files.zip"  # S3里的存储路径
    with open(rezip_path, "rb") as f:
        s3.put_object(Bucket=bucket_name, Key=s3_key, Body=f)
    
    return {
        'statusCode': 200,
        'body': "文件处理完成并成功上传到S3"
    }

def get_zip_from_api():
    # 替换成你实际的API调用代码,返回包含ZIP二进制内容的响应
    import requests
    return requests.get("https://example.com/your-zip-source-api")

额外要注意的点

  • Lambda的/tmp目录有512MB的默认存储限制(部分新运行时支持更大空间,比如10GB,你可以在Lambda配置里调整),要确保解压和重新压缩后的文件总大小不超这个限制。
  • /tmp目录的内容会在Lambda执行结束后保留一段时间,但绝对不能用来存持久化数据——每次执行都应该重新生成需要的文件,避免依赖之前的残留数据。
  • 尽量在/tmp下创建专属子目录来处理你的文件,不要直接解压到/tmp根目录,避免和其他可能的临时文件冲突。

内容的提问来源于stack exchange,提问作者Codyj110

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:40:54