返回技能市场
开发运维 安全

本地文件定时同步到OSS

@aliyun/alibabacloud-oss-manage-cron-upload

本地指定文件夹,定时上传到OSS(禁止同名文件覆盖)

云Skills门户 热度 27v0.0.2

OSS 定时本地同步

使用阿里云 CLI 优先的工作流,规划并验证从本地文件夹到 OSS 的定时上传。

场景说明

此 skill 适用于本地文件夹会随时间变化且必须定期上传到 OSS 的场景。

架构Local folder + aliyun CLI (integrated ossutil) + cron/Task Scheduler + OSS Bucket

能力划分

  • [aliyun CLI] 安装检查、配置文件验证、命令发现、OSS 端验证,以及集成的 aliyun ossutil 上传/列出命令。
  • [OS-local] cron 或 Windows 任务计划程序配置。
  • [Manual/Console] 附加 RAM 策略,以及选择性地在 OSS 控制台中进行可视化验证。

安装

预检查:强制要求阿里云 CLI >= 3.3.3
运行 aliyun version,验证版本是否满足 >= 3.3.3 的要求。如果尚未安装或版本过低,
请参阅 references/cli-installation-guide.md 获取安装说明。
然后运行 aliyun configure set --auto-plugin-install true
在核心工作流开始时(调用任何 CLI 之前):
[必须] 启用 AI-Mode——AI-mode 是执行 Agent Skill 的强制要求。
调用任何 CLI 之前,请运行以下命令:
```bash
aliyun configure ai-mode enable
aliyun configure ai-mode set-user-agent --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload"
```
[必须] 在每个退出点禁用 AI-Mode——无论出于何种原因,在提供最终响应之前,都必须先禁用 AI-mode。这适用于所有退出路径:工作流成功、工作流失败、错误/异常、用户取消、会话结束,以及任何其他不再执行后续 CLI 命令的场景。
AI-mode 仅用于 Agent Skill 调用场景,skill 停止运行后不得继续保持启用状态。
```bash
aliyun configure ai-mode disable
```
[必须] CLI User-Agent——每次调用 aliyun CLI 命令时都必须包含:
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload

必需的本地工具:

| 工具 | 必需 | 用途 | 验证 | | --- | --- | --- | --- | | aliyun CLI | 是 | 凭证校验、命令发现和集成的 ossutil 上传/列出命令入口 | aliyun versionaliyun ossutil --help | | cronschtasks | 是 | 本地周期性执行 | crontab -lschtasks /Query /TN "OSS Scheduled Sync" |

仅将 references/cli-installation-guide.md 用于 CLI 安装和插件设置。对于此 skill,请使用集成的 aliyun ossutil 命令入口——不得要求安装独立的 ossutil,也不得直接使用 ossutil 命令。

环境变量

除了已配置的阿里云配置文件外,不需要任何额外的云服务专用环境变量。

示例中使用的可选本地变量:

| 变量 | 必填/可选 | 说明 | 默认值 | | --- | --- | --- | --- | | ALIBABA_CLOUD_PROFILE | 可选 | 选择预先配置的阿里云 CLI 配置文件 | CLI 当前配置文件 | | ALIYUN_BIN | 可选 | 当 aliyun 尚未加入 PATH 时,其绝对路径 | aliyun | | OSS_SYNC_LOG | 可选 | 定时执行的日志文件路径 | 特定于 OS 的本地路径 |

参数确认

参数提取——直接从用户请求中提取所有可由用户自定义的参数。
当用户消息已指定具体值(例如地域、存储桶名称、路径、计划或 MaxAge)时,
直接使用这些值,无需再次确认。
仅当用户请求中确实缺少某个必需参数
且无法根据上下文合理推断时,才向用户询问以澄清。

| 参数名称 | 必填/可选 | 说明 | 验证模式 | 默认值 | | --- | --- | --- | --- | --- | | RegionId | 必需 | OSS 地域,例如 cn-hangzhou | ^[a-z]{2}-[a-z]+(|-[0-9]+)$ | 无 | | BucketName | 必填 | 目标 OSS 存储桶名称 | ^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$ | 无 | | TargetOssPrefix | 必填 | 相对于存储桶的目标 OSS 前缀,例如 backup/photos/(确认不以 / 开头) | ^[A-Za-z0-9/_.-]*$(不以 / 开头) | 无 | | LocalSourcePath | 必填 | 要上传的本地文件夹 | 绝对路径,不得包含 ~$、反引号或 ; | 无 | | Schedule | 必填 | Cron 表达式或 Windows 计划执行时间/频率 | 标准 5 字段 cron 表达式或 schtasks 时间 | 无 | | MaxAge | 必填 | aliyun ossutil --max-age 时间窗口,例如 7d24h | ^[0-9]+[dhm]$ | 无 | | OperatingSystem | 必填 | linuxmacoswindows | ^(linux|macos|windows)$ | 无 | | BucketAlreadyExists | 必填 | 目标存储桶是否已存在 | ^(yes|no)$ | 无 | | AliyunBinaryPath | 可选 | 供调度器使用的 aliyun 绝对路径 | 绝对路径,不得包含 $、反引号或 ; | aliyun | | LogPath | 可选 | 计划任务的本地日志路径 | 绝对路径,不得包含 $、反引号或 ; | 特定于 OS 的本地路径 |

输入验证——所有参数在使用前都必须经过验证。
将所有输入(包括从用户消息中提取的值)视为不可信。在将任何参数代入 shell 命令之前:
1. 根据上方的 验证模式 列验证该值。拒绝不匹配的值。
2. BucketName 只能包含小写字母、数字和连字符([a-z0-9-]),长度必须为 3–63 个字符,并且不得以连字符开头或结尾。
3. RegionId 必须符合阿里云地域格式(例如 cn-hangzhouus-west-1ap-southeast-5)。
4. MaxAge 必须为正整数,后跟 d(天)、h(小时)或 m(分钟)。
5. LocalSourcePathAliyunBinaryPathLogPath 必须是绝对路径,并且不得包含 shell 元字符($、` `$(;|&><\n`)。
6. TargetOssPrefix 只能包含字母、数字、/_.-,并且不得以 / 开头。
7. 如果任何参数未通过验证,必须停止并向用户报告错误。不得尝试净化或转义无效值——应直接拒绝这些值。

身份认证

预检查:必须具备阿里云凭据
安全规则:
- 严禁读取、回显或打印 AK/SK 的值(例如,严禁执行 echo $ALIBABA_CLOUD_ACCESS_KEY_ID
- 严禁读取或使用 cat 查看凭据文件,例如 ~/.aliyun/config.json~/.ossutil/config,或任何可能包含机密信息的文件
- 严禁要求用户直接在对话或命令行中输入 AK/SK
- 严禁aliyun configure set 中直接提供凭据值
- 只能使用 aliyun configure list 检查凭据状态
```bash
aliyun configure list
```
检查输出中是否存在有效的配置文件(AK、STS 或 OAuth 身份)。
如果不存在有效的配置文件,必须在此处停止。
1. 从 阿里云控制台 获取凭据
2. 在此会话之外配置凭据(在终端中使用 aliyun configure,或使用 shell 配置文件中的环境变量)
3. 待 aliyun configure list 显示有效的配置文件后,返回并重新运行

对所有 aliyun ossutil 命令复用当前启用的 CLI 配置文件。不得打印或硬编码机密信息。不得使用 ossutil config 或任何其他机密信息输入流程取代此检查环节。

RAM 策略

默认工作流需要拥有用于发现存储桶、验证存储桶元数据以及在已确认前缀下上传对象的最小权限。

| 范围 | 必需操作 | | --- | --- | | 账号级验证 | oss:ListBuckets | | 目标存储桶验证 | oss:GetBucketInfo | | 增量上传到目标前缀 | oss:PutObject, oss:GetObject, oss:ListObjects | | 可选的测试清理 | oss:DeleteObject |

有关策略 JSON 和限定于前缀范围的资源示例,请参阅 references/ram-policies.md

不得oss:AbortMultipartUpload 为核心重新定义默认最小权限集。在此 skill 中,默认最小权限路径仍以存储桶发现、存储桶元数据验证以及限定于前缀范围的上传、列举和读取操作为基础。只有当用户明确要求时,才将分片上传清理权限作为后续工作处理。

核心工作流

实际执行,不得只写文档。 直接在环境中运行每个步骤的命令。不得只编写解决方案文档或脚本,而要在实际环境中真正执行 aliyun versionaliyun configure listaliyun ossutil cp 等命令。
从用户请求中提取 RegionIdBucketNameTargetOssPrefixLocalSourcePathScheduleMaxAgeOperatingSystemBucketAlreadyExists。仅当确实缺少必需参数时才询问用户。

步骤 1:验证 CLI 和凭据 [aliyun CLI]

aliyun version
aliyun configure list
aliyun configure ai-mode enable

验证以下事项:

  • aliyun 版本为 >= 3.3.3
  • 至少存在一个有效配置文件
  • AI 安全模式已启用(危险操作将被阻止)

如果版本过低或缺少 aliyun,请参阅 references/cli-installation-guide.md。不得通过改用独立版 ossutilaliyun ossutil sync 来绕过缺少 CLI 的问题。

步骤 2:验证或创建存储桶前置条件 [aliyun CLI]

必须始终先检查候选存储桶清单:

aliyun ossutil api list-buckets --output-format json \
  --read-timeout 60 --connect-timeout 30 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload

如果 BucketAlreadyExists=yes,请明确验证所选存储桶:

aliyun ossutil stat "oss://${BucketName}" --region "${RegionId}" --output-format json \
  --read-timeout 60 --connect-timeout 30 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload
跨区域说明:如果当前 CLI 配置文件的区域(由 aliyun configure list 显示)与目标存储桶的 RegionId 不同,则必须statlscp 命令中添加 --region "${RegionId}"。仅使用 --endpoint 并不足够,因为请求签名区域也必须匹配。--region 标志可一次性覆盖端点和签名区域。

需要确认:

  • 账户资源清单中存在该存储桶名称
  • 存储桶区域与 RegionId 匹配
  • 可以使用当前配置文件访问该存储桶
  • 如果多个现有存储桶都可满足同一备份目标,可以提醒用户,启用了版本控制的存储桶更有利于保障备份安全;但这只是一项建议,不会阻止使用已确认的现有存储桶

如果 BucketAlreadyExists=no,请使用先检查后操作的幂等模式:

  1. 首先运行上面的 list-buckets,确认该存储桶确实不存在于账户中——如果已经存在,则跳过创建,直接进行 stat 验证。
  2. 仅当确认存储桶不存在时,才按照此 skill 的现有创建流程创建存储桶。
  3. 创建后,立即重新运行 stat 进行验证:
aliyun ossutil stat "oss://${BucketName}" --region "${RegionId}" --output-format json \
  --read-timeout 60 --connect-timeout 30 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload

定期备份场景的可选建议:

  • 如果存在多个候选存储桶,并且其中一个已启用版本控制,请说明该存储桶更有利于保障备份回滚安全
  • 如果已确认的现有存储桶未启用版本控制,仍可用于此工作流;启用版本控制只是一项可选的加固建议,并非前置条件

aliyun ossutil 作为 cplsstat 等上传与验证命令的标准操作入口。创建存储桶时,应遵循此 skill 中已有文档记录的创建流程,而不是在此凭空引入新的命令系列。不得为了掩盖缺失的前置条件而伪造成功结果、额外部署文件或虚假的本地制品。

步骤 3:运行标准增量上传测试 [aliyun CLI / integrated ossutil]

通过 aliyun ossutil 使用官方数据面命令系列执行实际的定时上传任务:

aliyun ossutil cp "${LocalSourcePath}" "oss://${BucketName}/${TargetOssPrefix}" \
  -r -u \
  --max-age "${MaxAge}" \
  --region "${RegionId}" \
  --read-timeout 300 --connect-timeout 30 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload

此命令的关键规则:

  • -u 是强制要求:仅在目标对象不存在,或源文件比现有 OSS 对象更新时才上传
  • -r -u --max-age 必须始终一起使用,作为标准标志组合
  • --region "${RegionId}" 可确保端点和签名区域均正确
  • --read-timeout 300 --connect-timeout 30 可防止命令无限期挂起;必要时可为超大文件增大 --read-timeout 的值
  • 仅对无人值守运行(cron、任务计划程序、CI)添加 -f
  • LocalSourcePath 必须使用绝对路径(不得使用 ~
  • 规范化 TargetOssPrefix,使其不以 / 开头
  • 不得改用裸命令 ossutilaliyun ossutil syncCache-Control 元数据重写

如果 TargetOssPrefix 为空,请使用 oss://${BucketName}/(末尾带斜杠)。否则,请在规范化前缀后使用 oss://${BucketName}/${TargetOssPrefix}

如果当前环境中不存在 LocalSourcePath(例如容器或 CI 运行器),请在当前工作目录下创建该目录并放入一个小型测试文件,然后对其运行上传命令,并使用 aliyun ossutil ls 进行验证。这样可以证明上传路径能够端到端正常工作。不得仅因为目录不存在就跳过上传测试——请创建该目录,并验证连接、权限和命令正确性:
```bash
mkdir -p "${LocalSourcePath}" && echo "test" > "${LocalSourcePath}/test.txt"
aliyun ossutil cp "${LocalSourcePath}" "oss://${BucketName}/${TargetOssPrefix}" \
-r -u --max-age "${MaxAge}" --region "${RegionId}" \
--read-timeout 300 --connect-timeout 30 \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload
aliyun ossutil ls "oss://${BucketName}/${TargetOssPrefix}" --region "${RegionId}" \
--read-timeout 60 --connect-timeout 30 \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload
```

步骤 4:将上传操作封装到本地脚本中 [aliyun CLI + OS-local]

最小脚本模板:

#!/usr/bin/env bash
set -euo pipefail

ALIYUN_BIN="${ALIYUN_BIN:-aliyun}"
LOCAL_SOURCE_PATH="${LocalSourcePath}"   # MUST be an absolute path, never use ~
BUCKET_NAME="${BucketName}"
TARGET_OSS_PREFIX="${TargetOssPrefix#/}"
MAX_AGE="${MaxAge}"
REGION_ID="${RegionId}"
LOG_FILE="${OSS_SYNC_LOG:-$HOME/oss-sync.log}"
READ_TIMEOUT="${READ_TIMEOUT:-600}"
CONNECT_TIMEOUT="${CONNECT_TIMEOUT:-30}"

# --- Input validation ---
[[ "${BUCKET_NAME}" =~ ^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$ ]] || { echo "ERROR: Invalid BucketName: ${BUCKET_NAME}" >&2; exit 1; }
[[ "${REGION_ID}" =~ ^[a-z]{2}-[a-z]+(|-[0-9]+)$ ]]          || { echo "ERROR: Invalid RegionId: ${REGION_ID}" >&2; exit 1; }
[[ "${MAX_AGE}" =~ ^[0-9]+[dhm]$ ]]                           || { echo "ERROR: Invalid MaxAge: ${MAX_AGE}" >&2; exit 1; }
[[ "${TARGET_OSS_PREFIX}" =~ ^[A-Za-z0-9/_.-]*$ ]]            || { echo "ERROR: Invalid TargetOssPrefix: ${TARGET_OSS_PREFIX}" >&2; exit 1; }
[[ "${LOCAL_SOURCE_PATH}" == /* ]]                             || { echo "ERROR: LocalSourcePath must be absolute: ${LOCAL_SOURCE_PATH}" >&2; exit 1; }

TARGET_URI="oss://${BUCKET_NAME}/"

if [ -n "${TARGET_OSS_PREFIX}" ]; then
  TARGET_URI="oss://${BUCKET_NAME}/${TARGET_OSS_PREFIX}"
fi

"${ALIYUN_BIN}" ossutil cp "${LOCAL_SOURCE_PATH}" "${TARGET_URI}" \
  -r -u -f \
  --max-age "${MAX_AGE}" \
  --region "${REGION_ID}" \
  --read-timeout "${READ_TIMEOUT}" --connect-timeout "${CONNECT_TIMEOUT}" \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload >> "${LOG_FILE}" 2>&1
注意:脚本模板包含 -f 标志,因为该脚本用于无人值守的 cron 或任务计划程序执行,在这类执行中,交互式提示不得阻塞任务。相较于 --endpoint,优先使用 --region 标志,因为它能正确设置端点和签名区域;当 CLI 配置文件的默认区域与目标存储桶区域不同时,这是必需的。

步骤 5:配置调度器 [OS-local]

Linux/macOS cron 定时任务

对于此 skill 中默认的 Linux/macOS 路径,应继续将 cron / crontab 作为文档中规定的调度器操作入口。除非用户明确要求 launchd 专用变体,否则不得擅自将方案替换为 launchd

如果找不到 crontab:在容器或最小化环境中,可能未预先安装 crontab。请先安装 cronie 软件包:
- CentOS/阿里云 Linux/RHEL:yum install -y cronie
- Debian/Ubuntu: apt-get install -y cron
如果 systemctl start crond 失败(例如容器中没有 systemd),仍可通过 crontab 添加 cron 条目——添加条目本身并不强制要求 cron 守护进程,只有实际执行才需要。在这种情况下,请记录该 cron 条目,供用户部署到生产主机上,且不得因缺少守护进程而阻塞工作流的其余部分。
crontab -e

示例条目(非交互式安装时使用 echo ... | crontab -):

0 3 * * * /usr/local/bin/oss-sync-upload.sh >> /var/log/oss-sync-cron.log 2>&1

Windows 任务计划程序(通过本地 CLI):

schtasks /Create /SC DAILY /ST 03:00 /TN "OSS Scheduled Sync" /TR "C:\tools\oss-sync-upload.bat"

将此步骤明确标记为 OS 本地操作。它不是一项阿里云 API 操作。计划任务相关输出应精简且可直接操作;除非用户明确要求,否则不要让此步骤衍生出额外的 README 文件、XML 导出文件、PowerShell 封装脚本、演示载荷或其他辅助产物。

步骤 6:验证上传目标 [aliyun CLI / integrated ossutil]

任何上传完成后,都必须执行此验证(包括步骤 3 中的测试上传):

aliyun ossutil ls "oss://${BucketName}/${TargetOssPrefix}" --region "${RegionId}" \
  --read-timeout 60 --connect-timeout 30 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload

确认预期对象出现在目标前缀下。不得跳过此步骤——此步骤可验证端到端连通性和权限。

如果用户希望进行手动可视化检查,请将其明确标记为 [Manual/Console],并在 OSS 控制台中确认目标前缀。

步骤 7:明确说明能力边界

适用时,必须始终说明以下限制:

  • 实际的增量同步步骤通过 aliyun ossutil 执行。 此 skill 始终使用 aliyun CLI 命令界面,无需另外安装独立版 ossutil
  • 计划任务设置属于 OS 本地操作。 Cron 和任务计划程序在主机 OS 上配置,而不是通过阿里云 APIs 配置。
  • RAM 策略的附加通常需手动完成,或遵循用户现有的 IAM 工作流。
  • 缺少目标存储桶时,应在定时上传前创建存储桶。 对于此前提条件,请遵循此 skill 中已有的创建流程。
  • 如果有多个等效的现有存储桶,可以提醒用户,为确保备份安全,启用版本控制的存储桶更合适。 如果没有已启用版本控制的存储桶,请继续使用已确认的现有存储桶,而不要阻塞工作流。
  • 可选的 OSS 控制台检查需手动完成。
  • 不得模拟成功。 缺少前提条件时,应明确说明,而不是创建虚假的本地测试数据、伪造的执行日志或额外的打包产物。

成功验证方法

使用 references/verification-method.md 作为权威检查清单。

最低通过条件:

  1. aliyun configure list 显示有效的配置文件。
  2. aliyun ossutil cp --help 执行成功。
  3. 规范的 aliyun ossutil cp ... -r -u --max-age ... --region ... 命令执行完成,且未出现权限或端点错误。
  4. aliyun ossutil ls ... --region ... 显示已确认前缀下预期的已上传对象。
  5. 上传命令保留 -u,即仅当目标对象不存在或本地源文件比现有 OSS 对象更新时才上传。
  6. 可通过 crontab -l 或任务计划程序的历史记录/查询结果看到本地计划任务条目;如果当前环境中没有 crontab,则已为用户记录该条目。

清理

由于此 skill 用于周期性同步,清理是可选操作,但可以安全删除测试产物和计划任务条目。

Linux/macOS cron 定时任务 [OS-local]

  • 使用 crontab -e 删除 cron 条目
  • 仅当用户明确希望回滚时,才删除本地脚本和日志文件

Windows 任务计划程序 [OS-local]

schtasks /Delete /TN "OSS Scheduled Sync" /F

可选的 OSS 测试清理 [aliyun CLI / integrated ossutil]

aliyun ossutil rm "oss://${BucketName}/${TargetOssPrefix}test-object.txt" --region "${RegionId}" \
  --read-timeout 60 --connect-timeout 30 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-oss-manage-cron-upload

除非用户明确要求相应的清理范围,否则不得删除存储桶或生产对象。

禁用 AI 安全模式 [aliyun CLI]

所有任务完成后,禁用 AI 安全模式,以恢复 CLI 的正常行为:

aliyun configure ai-mode disable

API 和命令表

有关命令清单、OSS 能力说明和验证说明,请参阅 references/related-apis.md。该文件仅作为参考元数据。

最佳实践

  1. aliyun 用于预检查、命令发现和存储桶验证,并将集成的 aliyun ossutil cp 用于实际的定时上传。
  2. 在所有 aliyun ossutil 命令(statcplsrm)中使用 --region "${RegionId}",以确保端点和签名区域均正确。当 CLI 配置文件的默认区域与目标存储桶的区域不同时,这一点尤其重要。不得仅依赖 --endpoint,因为它不会覆盖签名区域,并且跨区域使用 STS 令牌时会因“Authorization 标头中的签名区域无效”错误而失败。
  3. 始终将计划任务步骤标记为 OS 本地操作,让用户了解这些步骤不属于阿里云 APIs 的范畴。
  4. 尽可能使用范围最小的 RAM 策略:在账户范围内获取存储桶清单、获取目标存储桶信息,并且仅向已确认的前缀上传对象。
  5. 在目标机器上实际执行前,运行 aliyun versionaliyun configure list
  6. 禁止打印 AK/SK 值,禁止在脚本中硬编码这些值,禁止读取 ~/.aliyun/config.json 等凭证文件,也禁止用内联密钥处理取代凭证检查关卡。
  7. 如果存储桶不存在,应先创建,再配置定时上传。如果多个现有存储桶均可满足同一备份目标,可以提醒用户,为确保备份安全,启用版本控制的存储桶更合适;但如果不存在此类存储桶,请继续使用已确认的现有存储桶。
  8. 在命令和脚本中,始终为 LocalSourcePath 使用绝对路径。不要使用 ~(波浪号),因为它在带引号的字符串中可能不会展开,从而导致“不是目录”错误。
  9. 在为 cron 或任务计划程序生成的脚本中,请加入 -f 标志,以防止交互式确认提示阻塞无人值守执行。

参考链接

| 参考资料 | 描述 | | --- | --- | | references/cli-installation-guide.md | 从创作者 skill 资产复制而来的必备 CLI 安装指南 | | references/verification-method.md | 预检查、上传、调度器和手动验证清单 | | references/related-apis.md | aliyun 及集成式 ossutil 的命令清单和 OSS API 映射 | | references/ram-policies.md | 用于验证和上传的最小权限 RAM 策略指南 | | references/acceptance-criteria.md | 此场景的正确和错误命令模式 |

qianwen skills install @aliyun/alibabacloud-oss-manage-cron-upload