惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
爱范儿
爱范儿
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Tailwind CSS Blog
J
Java Code Geeks
宝玉的分享
宝玉的分享
Jina AI
Jina AI
B
Blog
N
Netflix TechBlog - Medium
Recent Announcements
Recent Announcements
aimingoo的专栏
aimingoo的专栏
腾讯CDC
C
Check Point Blog
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - Franky
罗磊的独立博客
B
Blog RSS Feed
WordPress大学
WordPress大学
小众软件
小众软件
博客园 - 叶小钗
M
MIT News - Artificial intelligence
GbyAI
GbyAI

LINUX DO - 最新话题

谷歌云盘下载700g数据集,求方法 OpenAI推出了100美元的Pro订阅后,plus的Codex 5小时限额大幅缩水 之前买的super grok居然还没掉 关于CPA认证文件周限 佬们,默认CDK的要求是什么等级啊? 最新版本的微信群聊机器人方案 有没有人知道如何free号没有封,那么是否可以循环使用,因为我看主要是周限 L站改版了?吓我一跳,我以为我浏览器崩了 淘宝这种宽带可信吗,500兆移动宽带月费8元到2099年 docker内部应用访问宿主机mysql和redis时被拒绝connection refuse Erp全栈想转行做Ai有什么推荐的吗 boost有bug 佬们,有没有靠谱点的 Plus 购买渠道 大妈,狗妈用的 lg 服务有源头开源项目吗? 有人有能过验证码打码的嘛 上次帖里好像发过通过大模型来打码的 gpt plus 封号似乎也太快了点,一天就给封号了 按流量/token收费的国产官方AI推荐 我算是知道了为什么Oracle总是ABC了 佬友们帮我分析一下 ChatGPT Team账号只有一个人使用和4个席位邀请满了使用的总额度是一样的吗? gpt-free 10个带rt CPA反代claude是默认1m吗? 我终于敢说我做出来windows上tmux的替代了,目标windows/全平台最强的终端Ai编程工具 claude pro升级max,除了原来的$20,好像还能再领一次$100 关于AI agent的知识框架 独乐乐不如众乐乐,分享一下我的的AI对话程序 佬们自建网站支付问题是怎么解决的 怎么能让gpt模仿claude风格输出 codex free已经死了,下一个会是plus或者team吗 请问chatgpt pro里的fast模式,速度快了,降智吗
【Macbook玩游戏】我想分享一下Macbook使用4090D玩3A单机游戏...
Alvin.Zhang (王权富贵) · 2026-06-13 · via LINUX DO - 最新话题

首先这个帖子不是商业性质,我也没有任何好处,纯粹是我用了很长时间觉得好用,作为一个自来水怕它因为用的人太少,没经费了以后倒闭我没得玩,还有就是站里Mac的用户越来越多,我真的想分享一下。
我看了《社区准则》应该是没问题了,如果有任何违规的恳请批评。

首先我是一个Macbook用户,其次是单机游戏爱好者,我没有台式机,也不想一次性花两三万去配个台式机。自从四五年前买了Macbook之后,我就在研究市场上各种云游戏云电脑云主机,目前各平台还活下来的并且稳定使用的基本就只有这个海马云。可能大家有在网上看到过宣传,但都是从免费使用时长,签到领时长这种偏向羊毛的角度去讲,我这次从付费用户角度出发,大致分享几个应用场景:

1.我开最高级的传奇会员,冲150块(一个月有效,有时候只要125)在4090D/120Hz区正价时段可以玩至少88个小时左右,除了放长假基本用不完,就算一个月只玩40个小时,那也就是3块多,还不提低价时段,相当便宜;
2.我经常出差,用这个只要有网,晚上在酒店的时候也可以玩;
3.由于是云电脑,我玩起来本身电脑风扇都不会转的,机身不会发烫,没有噪音,也不影响别人,因此上班摸鱼的时候也可以玩;
4.不用考虑硬件折旧维修等问题,也不需要考虑电脑散热;
5.我用了将近一年,没有遇到过排队,偶尔遇到过几次网络不稳定导致掉线存档没了,后来我自己用Python写了个存档同步脚本,15分钟把存档同步到会员盘里一次,基本解决了这个问题;
6.充会员会给一个5GB的会员盘,数据持久化保留,另外可以单独买到最大500GB数据硬盘,存游戏本体是够了,大部分游戏都能从3DM下到协调版;
7.支持手柄接入,支持高刷分辨率,4090D画质全开,配上Macbook的显示器,游玩体验好。
8.客服响应及时,不知道是不是我开了史诗会员,白天随时都有人工客服在线,节假日周末也不例外。

一些需要注意的事项:
1.有时候遇到网络不好掉线,或者窗口化的时候不小心按到command+Q关了是不能重连的,存档问题可以使用我上传的Python脚本;
2.充钱开会员赠送的金币一个月内有效,自充钱之日起计算,建议大家绝对别买包季,就一个月一个月充,包季的金币是分成三个月发放,不仅麻烦而且风险高;
3.没有的游戏或者需要更新,可以让客服发工单更新,或者自己在自己云盘建个Steam库下载安装;
4.云电脑下载带宽只有5MB/s,非常慢,可以在低价时段(0点到9点)挂机下载;
5.关注云盘到期时间,及时续费或下载数据,不然到期了数据就没了;
6.可以开全屏模式独占,或者开最大化窗口边玩边vibe coding,但是要注意使用同TUN的,可以在开启TUN模式的时候把进程关键字加到直连规则中;

【这个是用来同步存档数据的Python脚本,海马云客户端自行搜索官网下载】:

#!/usr/bin/env python3
"""
定期复制目录脚本 - 202606100125
每N分钟把目录A复制进目录B中,新建一个本机时间+A目录名的文件夹保存
仅使用Python标准库实现,支持跨平台(Windows, macOS, Linux)
复制代码保存为.py脚本文件,直接双击运行即可,启动时可以配置路径和时间
"""

import argparse
import os
import shutil
import sys
import time
from datetime import datetime


def normalize_path(path_str):
    """
    规范化路径,支持跨平台

    Args:
        path_str: 路径字符串

    Returns:
        规范化后的绝对路径
    """
    # 展开用户主目录符号 (~)
    expanded_path = os.path.expanduser(path_str)
    # 转换为绝对路径
    absolute_path = os.path.abspath(expanded_path)
    # 规范化路径分隔符
    normalized_path = os.path.normpath(absolute_path)
    return normalized_path


def copy_directory(source_dir, target_dir):
    """
    复制source_dir到target_dir中,使用时间戳+源目录名作为新文件夹名称

    Args:
        source_dir: 源目录的绝对路径
        target_dir: 目标目录的绝对路径

    Returns:
        bool: 复制是否成功
    """
    # 验证源目录存在
    if not os.path.isdir(source_dir):
        print(f"[错误] 源目录不存在: {source_dir}")
        return False

    # 创建目标目录(如果不存在)
    if not os.path.exists(target_dir):
        try:
            os.makedirs(target_dir, exist_ok=True)
            print(f"[信息] 创建目标目录: {target_dir}")
        except Exception as e:
            print(f"[错误] 无法创建目标目录: {e}")
            return False

    # 验证目标是目录
    if not os.path.isdir(target_dir):
        print(f"[错误] 目标路径不是目录: {target_dir}")
        return False

    # 获取源目录名
    source_name = os.path.basename(source_dir.rstrip(os.sep))
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    new_folder_name = f"{timestamp}_{source_name}"

    # 使用os.path.join确保跨平台兼容
    new_folder_path = os.path.join(target_dir, new_folder_name)

    try:
        print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 开始复制...")
        print(f"  源: {source_dir}")
        print(f"  目标: {new_folder_path}")

        shutil.copytree(source_dir, new_folder_path)

        # 获取复制的文件大小用于日志
        total_size = sum(
            os.path.getsize(os.path.join(dirpath, filename))
            for dirpath, dirnames, filenames in os.walk(new_folder_path)
            for filename in filenames
        )
        size_mb = total_size / (1024 * 1024)

        print(
            f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 复制完成 (大小: {size_mb:.2f} MB)"
        )
        return True
    except Exception as e:
        print(f"[错误] 复制失败: {e}")
        return False


def schedule_task(source_dir, target_dir, interval_minutes=5):
    """
    定时执行复制任务

    Args:
        source_dir: 源目录路径
        target_dir: 目标目录路径
        interval_minutes: 间隔时间(分钟)
    """
    # 规范化输入路径(支持跨平台)
    source_dir = normalize_path(source_dir)
    target_dir = normalize_path(target_dir)

    print("=" * 60)
    print("目录同步脚本 - 配置信息")
    print("=" * 60)
    print(f"操作系统: {sys.platform}")
    print(f"源目录: {source_dir}")
    print(f"目标目录: {target_dir}")
    print(f"执行间隔: 每 {interval_minutes} 分钟")
    print(f"启动时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print("=" * 60)
    print()

    # 验证路径
    if not os.path.isdir(source_dir):
        print(f"[错误] 源目录不存在或不可访问: {source_dir}")
        sys.exit(1)

    # 首次立即执行
    print("[信息] 首次执行...")
    print()
    copy_directory(source_dir, target_dir)
    print()

    # 计算间隔秒数
    interval_seconds = interval_minutes * 60
    last_run_time = time.time()

    print(f"[信息] 脚本已启动,等待下一个执行周期...")
    print(f"[信息] 按 Ctrl+C 停止脚本")
    print()

    # 保持运行
    try:
        while True:
            current_time = time.time()
            # 检查是否到达执行时间
            if current_time - last_run_time >= interval_seconds:
                copy_directory(source_dir, target_dir)
                print()
                last_run_time = current_time
            # 每秒检查一次
            time.sleep(1)
    except KeyboardInterrupt:
        print()
        print("[信息] 收到停止信号,正在退出...")
        print("[信息] 脚本已停止")
        sys.exit(0)
    except Exception as e:
        print(f"[错误] 发生异常: {e}")
        sys.exit(1)


def validate_paths(source, target):
    """
    验证并规范化输入的路径参数

    Args:
        source: 源目录路径
        target: 目标目录路径

    Returns:
        tuple: (规范化的源路径, 规范化的目标路径)

    Raises:
        ValueError: 如果路径无效
    """
    try:
        normalized_source = normalize_path(source)
        normalized_target = normalize_path(target)

        # 检查源路径是否存在
        if not os.path.exists(normalized_source):
            raise ValueError(f"源路径不存在: {source}")

        # 检查源路径是否是目录
        if not os.path.isdir(normalized_source):
            raise ValueError(f"源路径不是目录: {source}")

        return normalized_source, normalized_target
    except Exception as e:
        raise ValueError(f"路径验证失败: {e}")


def prompt_path(label, default_value=None):
    """
    提示用户输入路径;如果有默认值,允许直接回车使用默认值。

    Args:
        label: 提示标签
        default_value: 默认路径

    Returns:
        str: 用户确认后的路径
    """
    default_value = default_value.strip() if isinstance(default_value, str) else None
    has_default = bool(default_value)

    while True:
        if has_default:
            prompt = f"请输入{label} [默认: {default_value}]: "
        else:
            prompt = f"请输入{label}: "

        value = input(prompt).strip()
        if value:
            return value
        if has_default:
            return default_value

        print(f"[错误] {label}不能为空,请重新输入")


def prompt_interval(default_value):
    """
    提示用户输入执行间隔;允许直接回车使用默认值。

    Args:
        default_value: 默认间隔(分钟)

    Returns:
        int: 执行间隔(分钟)
    """
    while True:
        value = input(f"请输入执行间隔(分钟)[默认: {default_value}]: ").strip()
        if not value:
            value = str(default_value)

        try:
            interval = int(value)
        except ValueError:
            print("[错误] 执行间隔必须是整数,请重新输入")
            continue

        if interval < 1:
            print("[错误] 执行间隔必须至少为1分钟,请重新输入")
            continue

        return interval


def prompt_config(args):
    """
    收集并确认启动配置。

    Args:
        args: argparse解析后的参数

    Returns:
        tuple: (源目录, 目标目录, 执行间隔)
    """
    print("=" * 60)
    print("目录同步脚本 - 启动配置")
    print("=" * 60)
    source = prompt_path("源目录", args.source)
    target = prompt_path("目标目录", args.target)
    interval = prompt_interval(args.interval)
    print("=" * 60)
    print()
    return source, target, interval


def main():
    parser = argparse.ArgumentParser(
        description="每5分钟自动复制目录A到目录B(支持跨平台)",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例:
  # Linux/macOS
  python3 directory_sync.py
  python3 directory_sync.py /path/to/source /path/to/target
  python3 directory_sync.py ~/Documents/data ~/Documents/backup

  # Windows
  python directory_sync.py
  python directory_sync.py "C:\\Users\\username\\source" "D:\\backup"
  python directory_sync.py "C:\\Users\\username\\Documents\\data" "C:\\backup"

  # 自定义执行间隔(10分钟)
  python3 directory_sync.py /source /target --interval 10
        """,
    )

    parser.add_argument(
        "source", nargs="?", help="源目录的绝对路径或相对路径(支持~展开)"
    )
    parser.add_argument(
        "target", nargs="?", help="目标目录的绝对路径或相对路径(支持~展开)"
    )
    parser.add_argument(
        "--interval", type=int, default=5, help="执行间隔(分钟,默认为5)"
    )

    try:
        args = parser.parse_args()
        source_input, target_input, interval = prompt_config(args)

        # 验证路径
        source_dir, target_dir = validate_paths(source_input, target_input)

        # 启动定时任务
        schedule_task(source_dir, target_dir, interval)
    except ValueError as e:
        print(f"[错误] {e}")
        sys.exit(1)
    except EOFError:
        print()
        print("[错误] 未收到必要的交互输入,脚本已退出")
        sys.exit(1)
    except Exception as e:
        print(f"[错误] 未预期的错误: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()

image
image
image
image
image