restic 脚本化实战指南:环境变量、退出码与 JSON 输出的完整解析 📅 发布时间:2026/9/6 16:11:17 👁 浏览次数: restic 脚本化实战指南环境变量、退出码与 JSON 输出的完整解析【免费下载链接】resticFast, secure, efficient backup program项目地址: https://gitcode.com/GitHub_Trending/re/restic本篇技术指南以 restic 官方文档中的 Scripting 章节为核心系统讲解在自动化脚本中正确使用 restic 的三大支柱通过环境变量传递配置避免在命令行暴露密码、用cat config与特定退出码判断仓库是否已初始化以及如何消费--json标志产生的 JSON lines / 单文档输出。读完本文你将能够编写健壮、可解析、不泄露敏感凭据的 restic 自动化脚本如 cron 定时备份任务。一、通过环境变量传递选项除了命令行参数restic 支持用环境变量传递各类选项这是脚本化使用的推荐方式——尤其是密码避免其出现在进程列表或 shell 历史中。以下完整列出官方文档定义的环境变量参见 doc/075_scripting.rst通用与仓库选项环境变量作用RESTIC_REPOSITORY_FILE存放仓库位置的文件名等价于--repository-fileRESTIC_REPOSITORY仓库位置等价于-rRESTIC_PASSWORD_FILE密码文件位置等价于--password-fileRESTIC_PASSWORD仓库实际密码RESTIC_PASSWORD_COMMAND打印密码到 stdout 的命令RESTIC_KEY_HINT优先尝试解密的密钥 IDRESTIC_CACERT证书文件位置多个用逗号分隔等价于--cacertRESTIC_TLS_CLIENT_CERTTLS 客户端证书与私钥位置等价于--tls-client-certRESTIC_CACHE_DIR缓存目录位置RESTIC_COMPRESSION压缩模式仅仓库格式 v2 可用RESTIC_HOST只考虑该主机的快照 / 手动设置快照主机名等价于--hostRESTIC_PROGRESS_FPS进度条status 消息每秒刷新帧数RESTIC_PACK_SIZEpack 文件目标大小RESTIC_READ_CONCURRENCY文件读取并发度RESTIC_IGNORE_CTIME比较文件时忽略 ctime 变化等价于--ignore-ctimeRESTIC_IGNORE_INODE比较文件时忽略 inode 变化等价于--ignore-inodecopy 命令专用的源仓库选项环境变量作用RESTIC_FROM_REPOSITORYcopy 的源仓库等价于--from-repoRESTIC_FROM_REPOSITORY_FILE存放源仓库位置的文件等价于--from-repository-fileRESTIC_FROM_PASSWORD源仓库密码RESTIC_FROM_PASSWORD_FILE源仓库密码文件等价于--from-password-fileRESTIC_FROM_PASSWORD_COMMAND获取源仓库密码的命令等价于--from-password-commandRESTIC_FROM_KEY_HINT打开源仓库时优先尝试的密钥 ID等价于--from-key-hint临时目录TMPDIR临时文件位置Windows 之外TMP临时文件位置仅 Windows各后端凭据Amazon S3AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN、AWS_DEFAULT_REGION、AWS_PROFILE替代显式指定 key 和 region 的凭据 profile、AWS_SHARED_CREDENTIALS_FILEAWS CLI 共享凭据文件位置默认~/.aws/credentials以及 IAM 角色扮演相关的RESTIC_AWS_ASSUME_ROLE_ARN要扮演的角色 ARN、RESTIC_AWS_ASSUME_ROLE_SESSION_NAME、RESTIC_AWS_ASSUME_ROLE_EXTERNAL_ID、RESTIC_AWS_ASSUME_ROLE_POLICY内联会话策略、RESTIC_AWS_ASSUME_ROLE_REGIONIAM 调用区域默认us-east-1、RESTIC_AWS_ASSUME_ROLE_STS_ENDPOINTSTS 端点 URL一般无需设置高级用途。AzureAZURE_ACCOUNT_NAME、AZURE_ACCOUNT_KEY、AZURE_ACCOUNT_SAS共享访问签名 SAS、AZURE_ENDPOINT_SUFFIX存储端点后缀默认core.windows.net、AZURE_FORCE_CLI_CREDENTIAL强制使用 Azure CLI 凭据认证。Backblaze B2B2_ACCOUNT_IDAccount ID 或 applicationKeyId、B2_ACCOUNT_KEYAccount Key 或 applicationKey。Google Cloud StorageGOOGLE_PROJECT_ID、GOOGLE_APPLICATION_CREDENTIALS应用凭据文件如$HOME/.config/gs-secret-restic-key.json、GOOGLE_ACCESS_TOKENBearer 令牌替代默认应用凭据。OpenStackkeystoneOS_AUTH_URL、OS_REGION_NAME、OS_USERNAME、OS_USER_IDv3、OS_PASSWORD、OS_TENANT_ID/OS_TENANT_NAMEv2、OS_USER_DOMAIN_NAME/OS_USER_DOMAIN_IDv3、OS_PROJECT_NAME、OS_PROJECT_DOMAIN_NAME/OS_PROJECT_DOMAIN_IDv3、OS_TRUST_IDv3、应用凭据OS_APPLICATION_CREDENTIAL_ID/OS_APPLICATION_CREDENTIAL_NAME/OS_APPLICATION_CREDENTIAL_SECRETv3、令牌认证OS_STORAGE_URL/OS_AUTH_TOKEN。Swiftkeystone v1ST_AUTH、ST_USER、ST_KEY。其他RCLONE_BWLIMITrclone 带宽限制、RESTIC_REST_USERNAME/RESTIC_REST_PASSWORDRestic REST Server 用户名与密码。官方文档同时提醒两点当未设置RESTIC_CACHE_DIR时缓存位置的规则见 doc/cache.rst。restic 可能会执行外部程序rclonerclone 后端和sshSFTP 后端这些程序还会响应各自的手册中记载的环境变量和配置文件。一个典型的 cron 脚本骨架如下环境变量方式传递敏感信息#!/bin/bash export RESTIC_REPOSITORY/srv/restic-repo export RESTIC_PASSWORD_FILE/root/.resticpass # 仅约每分钟输出一条 status 消息适合日志采集 export RESTIC_PROGRESS_FPS0.0166 restic backup /data --json --quiet二、检查仓库是否已初始化脚本中经常需要判断仓库是否已存在避免重复执行init虽然init本身包含防止覆盖现有仓库的检查。官方推荐的做法是用cat config$ restic -r /srv/restic-repo cat config Fatal: repository does not exist: unable to open config file: stat /srv/restic-repo/config: no such file or directory Is there a repository at the following location? /srv/restic-repo判断规则仓库不存在时restic自 0.17.0 起返回退出码10并打印对应错误消息更早版本返回1。其他错误例如cat config密码不正确同样返回退出码1但错误消息不同。无错误时返回0并打印仓库元数据。因此脚本中可以用restic cat config /dev/null 21 || true探测或结合退出码区分仓库不存在与其他失败。三、退出码Exit codesrestic 用退出码指示命令是否成功。官方表格如下退出码含义0命令成功1命令失败详见各命令帮助2Go 运行时错误3backup无法读取部分源数据或forget未能删除一个或多个快照10仓库不存在自 0.17.011获取仓库锁失败自 0.17.012密码错误自 0.17.1130命令被取消如 SIGINT 或 SIGTERM官方警告未来会持续新增退出码遇到未知的非零退出码必须视为命令失败。这些退出码在源码 cmd/restic/main.go 中有集中映射可以印证文档描述ErrInvalidSourceData与ErrFailedToRemoveOneOrMoreSnapshots映射到3global.ErrNoRepository映射到10repository.IsAlreadyLocked映射到11repository.ErrNoKeyFound无可用密钥即密码错误场景映射到12context.Canceled信号取消映射到130其余错误默认1。退出码非零时还会调用printExitError这就是下一节 JSON exit_error 消息的来源。四、JSON 输出restic 在加--json标志时向stdout输出 JSON 数据结构因命令而异。使用约束有三并非所有命令都支持 JSON 输出官方欢迎社区为缺失的命令提 PRJSON 输出保持向后兼容但随时可能新增消息类型或字段枚举型字段有固定允许值列表的也可能被扩展脚本不应假定值域封闭。类型映射规则int32/int64/uint32/uint64/float64编码为 numberbool、string对应 JSON 同名类型类型前缀[]表示数组time.Time编码为 RFC3339 格式字符串os.FileMode编码为uint32。取值为默认值如0、的字段可能从输出中省略。4.1 两种输出格式单 JSON 文档Single JSON document若干命令输出可整体解析的单份 JSON 文档可能是一行或多行。JSON lines长时运行或输出量大的命令使用换行分隔的 JSON 消息流通过message_type字段区分消息类型。其中status类型消息在命令运行期间按固定间隔输出默认约每秒 10 次无论输出目标是终端还是管道--quiet可禁用它们而RESTIC_PROGRESS_FPS环境变量会同时覆盖这两者它设置 status 更新频率且在设置--quiet时也能重新启用输出。该值允许小于 1例如0.0166表示约每分钟一条 status 消息适合日志采集场景。该环境变量在 internal/ui/progress/terminal.go 中通过CalculateProgressInterval读取并解析实际刷新由 internal/ui/progress/updater.go 中的Updater以固定间隔的time.Ticker驱动——这也解释了为何小于 1 的 FPS 值等价于拉长 ticker 间隔是合法的慢速上报模式。4.2 退出错误exit_error致命错误会在进程退出前向stderr打印最后一条 JSON 消息包含错误消息和退出码字段说明类型message_type恒为exit_errorstringcode退出码见上文表格intmessage错误消息string注意Go 运行时错误、命令行解析错误等无法被这样捕获报告。4.3 backupbackup使用 JSON lines消息类型如下。statusstdout字段说明类型message_type恒为statusstringseconds_elapsed自备份开始经过的时间uint64seconds_remaining预计剩余时间uint64percent_done已备份数据比例bytes_done/total_bytesfloat64total_files检测到的文件总数uint64files_done已完成写入仓库的文件数uint64total_bytes备份集总字节数uint64bytes_done已完成字节数uint64error_count错误数量uint64current_files正在备份的文件列表[]stringerror打印到 stderrmessage_type恒为errorerror.message为错误消息during描述 restic 当时在做什么item通常为问题文件路径。verbose_status提供含备份文件明细的进度详情。字段actionnew、unchanged、modified或scan_finished、item相关项、duration耗时秒、data_size项目大小、data_size_in_repo仓库中大小、metadata_size/metadata_size_in_repo、total_files。excluded_item详细列出被排除的备份项字段message_type恒为excluded_item、item为相关项路径。summary成功备份的最后一行输出。字段包括dry_runbool、files_new/files_changed/files_unmodified、dirs_new/dirs_changed/dirs_unmodified均为 uint64、data_blobs/tree_blobsint64、data_added未压缩新增字节数、data_added_packed压缩后新增字节数、total_files_processed、total_bytes_processeduint64、backup_start/backup_endtime.Time、total_durationfloat64、snapshot_id新快照 ID若跳过创建则省略该字段。4.4 catcat命令把仓库内部对象打印到 stdout主要用于调试、理解仓库结构或从受损仓库恢复数据字段细节见 doc/view_repository.rst 中的 View repository objects 部分。4.5 checkcheck使用 JSON lines错误行为 stderr 上的 JSON 对象命令结束时在 stdout 打印一条 JSON summary。summarynum_errors错误数int64、broken_packs受损 pack ID 列表提示运行restic repair packs ID...与restic repair snapshots --forget、suggest_repair_index是否建议运行restic repair indexbool、suggest_prune是否建议运行restic prunebool。errorstderrmessage_type恒为errormessage为错误消息可能随版本任意变化。4.6 diffdiff使用 JSON lines两种消息changepath为变化路径modifier为变化类型由以下字符拼接新增、-删除、T条目类型变化、M文件内容变化、U元数据变化、?检测到 bitrot。statisticssource_snapshot/target_snapshot两个快照 ID、changed_files变化文件数int64、added/removedDiffStat 对象。DiffStat 对象files、dirs、others其他目录条目、data_blobs、tree_blobs均 int64、bytesuint64。4.7 findfind输出单份 JSON 文档是匹配结果的数组按快照组织。若传了--blob、--tree或--pack则输出 Blob 对象数组。按快照组织时每项字段hits该快照匹配数uint64、snapshot快照 ID、matchesMatch 对象数组。Match 对象path、permissionsUNIX 权限string、name、type如 file、dir、atime/mtime/ctimetime.Time、user/group、inodeuint64、modepermissions 的简写os.FileMode、device_id、links硬链接数、linktarget符号链接目标、uid/giduint32、sizeuint64。Blob 对象object_typeblob或tree、id、path快照内路径、parent_tree父树 blob仅 type 为blob时设置、snapshot、time。4.8 forgetforget输出单份 JSON 文档为 ForgetGroup 数组若指定了具体快照 ID 则不产生输出。使用--prune选项时其输出以 JSON lines 形式追加。ForgetGrouptags[]string、host、paths[]string、keep保留的 Snapshot 对象数组、remove被删除的 Snapshot 对象数组、reasonsKeepReason 对象数组。Snapshot 对象time、parent、tree根树 blob ID、paths、hostname、username、uid/giduint32、excludes、tags、program_version、summarySnapshotSummary 对象、id、short_id已废弃。KeepReason 对象snapshot被描述的快照、matches匹配条件描述数组。4.9 pruneprune使用 JSON lines 但只输出一条 summary 消息含三个统计对象PruneBlobsblob 数量used、duplicate、unused、total、repack、repack_remove、remove因删除 pack 而移除、remove_total、remaining。PruneSizes字节大小used、duplicate、unused、unreferenced无引用 pack 文件大小、uncompressed、total、repack、repack_remove、remove、remove_total、remaining、remaining_unused。PrunePackfilespack 文件数量used、unused、partly_used、unreferenced、total、keep、repack、remove、remove_total。4.10 initinit只输出一条消息message_type恒为initialized、id创建的仓库 ID、repository仓库 URL。4.11 key listkey list返回对象数组current当前使用的密钥bool、id唯一密钥 ID、userName创建者用户、hostName创建机器名、created创建时间戳本地 time.Time。4.12 lsls使用 JSON lines例外地以struct_type字段而非message_type判断消息类型。snapshot字段同 4.8 的 Snapshot 对象time、parent、tree、paths、hostname、username、uid、gid、excludes、tags、program_version、summary、id另有已废弃的struct_type恒为snapshot。nodename、type、path、uid/giduint32、sizeuint64、modeos.FileMode、permissionsmode 的字符串形式、atime/mtime/ctime、inodeuint64同样附已废弃的struct_type: node。4.13 restorerestore使用 JSON linesstatusseconds_elapsed、percent_donebytes_restored/total_bytesfloat64、total_files、files_restored、files_skipped因 overwrite 设置跳过、files_deleted、total_bytes、bytes_restored、bytes_skipped。errorstderr字段同 backup 的 error其中during恒为restore。verbose_status仅在--verbose2时打印。字段actionrestored、updated、unchanged或deleted、item、size。summaryseconds_elapsed、total_files、files_restored、files_skipped、files_deleted、total_bytes、bytes_restored、bytes_skipped。4.14 snapshotssnapshots返回单份 JSON 数组对象结构与 4.8 的 Snapshot 对象一致time、parent、tree、paths、hostname、username、uid、gid、excludes、tags、program_version、summary、id、short_id。SnapshotSummary 对象快照创建时刻的统计信息backup_start/backup_endtime.Time、files_new/files_changed/files_unmodified、dirs_new/dirs_changed/dirs_unmodifieduint64、data_blobs/tree_blobsint64、data_added未压缩新增字节、data_added_packed压缩后字节、total_files_processed/total_bytes_processed。4.15 statsstats返回单个 JSON 对象total_size仓库字节数、total_file_count、total_blob_count、snapshots_count处理的快照数、total_uncompressed_sizeblob 未压缩时的总大小、compression_ratio已压缩数据因压缩缩减的因子float64、compression_progress已压缩数据占比float64、compression_space_saving压缩带来的总体空间节省float64。4.16 tagtag使用 JSON lineschangedold_snapshot_id变更前快照 ID、new_snapshot_id变更后快照 ID。summarychanged_snapshots变更的快照总数int64。4.17 versionversion返回单个 JSON 对象message_type恒为version另有versionrestic 版本、go_versionGo 编译版本、go_os、go_arch。五、脚本化实践要点小结凭据优先走环境变量或密码文件RESTIC_PASSWORD_FILE、RESTIC_PASSWORD_COMMAND而不是命令行参数后端凭据使用对应后端约定的环境变量AWS_*、AZURE_*、B2_*、GOOGLE_*、OS_*、ST_*等。用退出码驱动分支0成功3源数据部分失败/快照删除失败10仓库不存在可自动init11锁竞争可重试或用restic unlock清理残留锁12密码错误130被信号取消任何未知非零值一律按失败处理。源码中该映射见 cmd/restic/main.go。用--json解析输出优先读取最后一条summary/initialized消息做决策需要节流日志时用RESTIC_PROGRESS_FPS可小于 1替代默认约 10 FPS 的 status 流注意--quiet与它的覆盖关系。stdout 与 stderr 分开消费主要结果在 stdout错误与exit_error在 stderr解析 JSON lines 时逐行判断message_type不要假定值域封闭。【免费下载链接】resticFast, secure, efficient backup program项目地址: https://gitcode.com/GitHub_Trending/re/restic创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考