Sunshine 2026.914.233613 常用 CLI 命令与工具详解
Sunshine v2026.914.233613 命令行面全解:3 个子命令+4 开关+2 类位置参数实测(--creds 缺参 core dump、--diagnose 未实现 exit 7、-h 非法 flag 告警等排障实录)、配置目录自动创建、REST API 工具面 curl 速查表(认证/配置/apps/pin/logs/restart/csrf 全接口)、退出码表与无头 restart 挂死排障(实测环境 2026-11-03)。
Sunshine 2026.914.233613 常用 CLI 命令与工具详解
目标:讲清 Sunshine 的命令行面——
sunshine单一二进制支持的 3 个子命令、4 个开关、2 类位置参数(全部实测回显,含--creds缺参崩溃、--diagnose未实现等排障实录),以及"没有更多 CLI"之后该用什么:REST API 工具面 curl 速查表(认证/配置/应用/配对/日志/重启全接口)。配置键语义详解见 C1,部署形态见 B2。本文所有回显均为 2026-11-03 在 Ubuntu 24.04.5 LTS 服务器上逐条实测照抄。
1. 环境信息
| 项目 | 值 |
|---|---|
| 服务器 OS | Ubuntu 24.04.5 LTS(x86_64,内核 7.0.0-38-generic) |
| Sunshine 版本 | 2026.914.233613(commit 63d35f70) |
| 二进制 | sunshine(单文件,无子命令树,无 man 页) |
| 配置目录 | ~/.config/sunshine/(root 实例为 /root/.config/sunshine/) |
| Web UI / API | https://localhost:47990(自签证书,Basic 认证 admin/q1w2e3r4) |
| GameStream HTTP | http://localhost:47989(明文,serverinfo/pair) |
| 源码核对文件 | src/main.cpp(命令分发 79–86 行、250–285 行)、src/config.cpp(apply_flags() 1561–1586 行) |
2. 命令面总览
sunshine --help 实测原文(exit 0):
Usage: sunshine [options] [/path/to/configuration_file] [--cmd]
Any configurable option can be overwritten with: "name=value"
Note: The configuration will be created if it doesn't exist.
--help | print help
--creds username password | set user credentials for the Web manager
--version | print the version of sunshine
flags
-0 | Read PIN from stdin
-1 | Do not load previously saved state and do retain any state after shutdown
| Effectively starting as if for the first time without overwriting any pairings with your devices
-2 | Force replacement of headers in video stream
-p | Enable/Disable UPnP
对照源码,命令面比 help 更窄也更直白:
| 元素 | 实现 | 说明 |
|---|---|---|
| 子命令 | main.cpp 的 cmd_to_func 映射表只有 3 项:creds / help / version | --<name> 形式进入分发;查不到即 Fatal: Unknown command(exit 7) |
| 开关 | -0/-1/-2/-p 走 apply_flags(),与配置文件隐藏键 flags = 012p 同源(见 C1 2.4) | 逐字符翻转语义 |
| 位置参数 | 第一个非 key=value 参数 = 配置文件路径;key=value = 单键覆盖 | 优先级 CLI > 指定文件 > 默认文件 > 内置默认 |
| 解析时序 | config::parse() 先行;--help/--version/--creds 在 parse 阶段完成即 return 0,不启动服务 | parse 阶段日志只进 stdout,不进日志文件(见 8.3) |
结论:Sunshine 的 CLI 只是"启动器 + 三个急救命令",日常管理面全部在 HTTPS REST API(第 7 节)。脚本化运维请优先 API。
3. 子命令详解
3.1 --help
打印第 2 节 usage,exit 0,不碰配置不启动服务。
注意:-h 不是 help 的别名。实测:
$ sunshine -h
[2026-11-03 03:07:47.915959] [0x00007dd3e1589000] [info] config: Unrecognized flag: [h]
Usage: sunshine [options] [/path/to/configuration_file] [--cmd]
...
-h 被当作 flags 字符串逐字符解析,h 不在 0/1/2/p 之列 → 告警后继续走 usage 打印,exit 仍为 0。同理实测 -i:
$ sunshine -i
[2026-11-03 03:07:57.915502] [0x000076024f7a7000] [info] config: Unrecognized flag: [i]
Usage: sunshine [options] ...
help 文本里从未出现过的 -i/-g/-c/-n 等"常见想象参数"一律触发 Unrecognized flag(exit 0),不要指望它们有功能。
3.2 --version
实测原文(exit 0):
$ sunshine --version
[2026-11-03 02:25:52.138]: Info: Sunshine version: 2026.914.233613 commit: 63d35f702ee9e362e43263742981836ec0710384
[2026-11-03 02:25:52.138]: Info: Package Publisher: LizardByte
[2026-11-03 02:25:52.138]: Info: Publisher Website: https://app.lizardbyte.dev
[2026-11-03 02:25:52.138]: Info: Get support: https://app.lizardbyte.dev/support
版本号 + commit + 发布者元数据四行。升级验证、工单取证先跑这条。
3.3 --creds <username> <password>
免 Web UI 设置管理员凭据——首启自动化、凭据找回、CI 冒烟都用它。实测(隔离 HOME 全新目录):
$ HOME=/tmp/d1b sunshine --creds tester pw123456
[2026-11-03 03:08:37.068]: Info: Sunshine version: 2026.914.233613 commit: 63d35f702ee9e362e43263742981836ec0710384
[2026-11-03 03:08:37.069]: Info: New credentials have been created
效果直接落 sunshine_state.json(实测文件内容,密码为加盐 SHA256):
{
"username": "tester",
"salt": "zHWozzacX9Xs2LQS",
"password": "2F43B3E8F859F5D9954BFD0D70E3A69880E2C3B4818BF010E92C5D1EF22C41B9"
}
同时配置目录被自动补全(apps.json/credentials/sunshine.conf/sunshine.log/sunshine_state.json,见第 6 节)。
缺参崩溃实录(不带用户名密码直接跑):
$ sunshine --creds
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string: construction from null is not valid
Aborted (core dumped)
$ echo $?
134
--creds 需要两个位置参数,缺任一个即 std::logic_error abort(exit 134)——这是 v2026.914.233613 的已知粗糙面,脚本里务必校验参数个数。
3.4 --diagnose:help 没列、实际也不存在(排障实录)
nightly 文档里出现过的 --diagnose 在稳定版未实现。实测:
$ sunshine --diagnose
[2026-11-03 03:07:57.842]: Info: Sunshine version: 2026.914.233613 commit: 63d35f702ee9e362e43263742981836ec0710384
[2026-11-03 03:07:57.842]: Fatal: Unknown command: diagnose
[2026-11-03 03:07:57.842]: Info: Possible commands:
[2026-11-03 03:07:57.842]: Info: creds
[2026-11-03 03:07:57.842]: Info: help
[2026-11-03 03:07:57.842]: Info: version
$ echo $?
7
Possible commands 三行就是稳定版 CLI 的全部命令面(exit 7)。诊断需求请改用:--version + GET /api/config + GET /api/logs + 日志文件(8 节)。
4. 开关:-0 / -1 / -2 / -p
四个开关与配置文件隐藏键 flags 一一对应(源码 apply_flags():逐字符翻转,非赋值):
| 开关 | 内部标志 | 语义 |
|---|---|---|
-0 | PIN_STDIN | 配对 PIN 从标准输入读取(不走 Web UI 输入框),无人值守配对接入点 |
-1 | FRESH_STATE | 不加载已保存状态、退出也不保留——"如首次启动",但不覆盖既有配对文件 |
-2 | FORCE_VIDEO_HEADER_REPLACE | 强制替换视频流参数集头(花屏类兼容问题急救) |
-p | UPNP | 开/关 UPnP 端口映射(与 upnp 键同效,翻转语义) |
实测组合启动(隔离 HOME,6 秒后 timeout 杀掉):
$ HOME=/tmp/d1 sunshine -1 -2 -p sunshine_name=d1test
[2026-11-03 03:08:06.931]: Info: Sunshine version: 2026.914.233613 commit: 63d35f702ee9e362e43263742981836ec0710384
[2026-11-03 03:08:06.931]: Info: config: 'sunshine_name' = d1test
[2026-11-03 03:08:16.630]: Warning: Couldn't discover any IPv4 UPNP devices
两个观察:
-p生效(尝试 UPnP,本网络无设备 → 告警但继续运行);- 该次运行目录树里没有
sunshine_state.json——-1(FRESH_STATE)不落盘状态,与语义一致。
-0 单独说明:它改变的是配对时 PIN 的输入通道(终端里直接敲 PIN),服务照常启动;headless 排障环境实测过服务启动不受影响。
5. 位置参数:配置文件路径与 key=value 覆盖
$ sunshine /tmp/my.conf # 用非默认路径的配置文件启动
$ sunshine sunshine_name=cli-override # 单键覆盖(可多个)
$ sunshine port=48999 # 覆盖任意配置键(含端口,见 C1 4.1 平移实测)
实测要点(完整优先级实验见 C1 2.4):
- 位置参数加载自定义文件:日志回显
config: 'upnp' = false、config: 'sunshine_name' = custom-path; key=value覆盖同名文件键:文件里sunshine_name = game-lab,CLI 传sunshine_name=cli-override后生效值为cli-override;key=value必须写成k=v无空格(parse 按=识别);带空格的k = v会被当成位置参数/flags 而误解析。
这套机制让"一份二进制 + N 份场景配置"成为可能:sunshine /etc/sunshine/tv.conf、sunshine /etc/sunshine/office.conf,或 systemd 模板单元传参。
6. 首启行为:配置目录自动创建
任何形态(直接启动、--creds、隔离 HOME)首次运行都会自动建目录并铺好文件。实测 HOME=/tmp/iso 全新环境跑 --creds 后:
/tmp/iso/.config/sunshine/
├── apps.json # 从安装资产复制的默认模板(Desktop/Low Res Desktop/Steam Big Picture)
├── credentials/ # 自签 CA 与服务端证书(cacert.pem/cakey.pem,CN=Sunshine Gamestream Host)
├── sunshine.conf # 空文件(全部键走内置默认)
├── sunshine.log # 本次运行日志
└── sunshine_state.json # 凭据(--creds 写入)
含义:没有"安装向导"步骤,目录即状态。备份/迁移 Sunshine 就是打包这个目录;删掉 sunshine_state.json 等于重置管理员凭据与配对(配合 -1 可临时试新配对而不毁旧数据)。
7. REST API 工具面速查(curl)
CLI 之外的全部管理操作都在 https://localhost:47990(自签证书加 -k;Basic 认证 -u admin:<密码>)。POST 类接口对 curl 免 CSRF(不带 Origin/Referer 直接放行,机制见 C1 4.2),浏览器经反代访问才需要 X-CSRF-Token。
7.1 接口总表(均实测)
| 方法 路径 | 用途 | 实测要点 |
|---|---|---|
GET / | 健康检查/认证面 | 无凭据 401+WWW-Authenticate: Basic realm="Sunshine Gamestream Host";带凭据 200;未设凭据时 307 → /welcome |
POST /api/password | 首启创建管理员 | 体 {newUsername,newPassword,confirmNewPassword} → {"status":true} |
GET /api/config | 读显式覆盖集 | 返回已保存键 + platform/version/status;空配置时只有后三者 |
POST /api/config | 写配置(整体覆盖 sunshine.conf) | 体 {"key":"value",...} → {"status":true};陷阱见 C1 3.3 |
GET /api/configLocale | 读 UI 语言 | {"locale":"en","status":true} |
GET /api/apps | 应用清单 | 返回 apps.json 全量(env+apps) |
POST /api/apps | 新增/替换应用 | 必带 index(-1 新增);缺 index → 400 [json.exception.type_error.302];改后即时生效 |
DELETE /api/apps/{index} | 删应用 | {"result":"application 3 deleted","status":true} |
POST /api/apps/run | 启动应用 | 体 {"app_id":N};无显示环境 400(串流会话前置) |
POST /api/apps/close | 关闭当前应用 | {"status":true} |
GET /api/pin | 查看配对会话 | {"pairings":[{"address":"...","id":"<32hex>","name":"Pixel-8"}]} |
POST /api/pin | 批准配对 | 体 {"pairing_id":"...","pin":"1234","name":"..."};PIN 必须 4 位数字 |
DELETE /api/pin | 撤销配对会话 | 已消费的会话返回 {"status":false} |
GET /api/clients/list | 已配对客户端 | {"named_certs":{...},"status":true} |
POST /api/clients/unpair-all | 全部解绑 | 重置配对的核弹按钮 |
GET /api/logs | 日志尾部 | 纯文本(UI 日志页同源) |
POST /api/restart | 服务自重启 | 无头环境会挂(8.4) |
GET /api/csrf-token | 签发 CSRF 令牌 | {"csrf_token":"<32字符>"},按客户端一次性存储 |
7.2 配对闭环(API 形态,配合 Moonlight)
Moonlight 客户端点"配对"拿到 PIN 后,两条 curl 完成批准(完整握手实测见 B2 第 7 节):
$ curl -sk -u admin:q1w2e3r4 https://localhost:47990/api/pin
{"pairings":[{"address":"10.89.62.1","id":"2b07da1c95c2735e69613739fac44279","name":"Pixel-8"}]}
$ curl -sk -u admin:q1w2e3r4 -X POST -H 'Content-Type: application/json' \
-d '{"pairing_id":"2b07da1c95c2735e69613739fac44279","pin":"1234","name":"Pixel-8"}' \
https://localhost:47990/api/pin
{"status":true}
GameStream 明文面(47989)不属于管理 API 但常被脚本探测:
$ curl -s "http://localhost:47989/serverinfo?uniqueid=00000000-0000-4000-8000-000000000000&hostaddress=10.89.62.1&protocol=128&appversion=7.1.431"
<root appversion="7.1.431.-1" GfeVersion="3.23.0.74" protocolversion="399" ... state="SUNSHINE_SERVER_FREE">
<hostname>game-lab</hostname>
<HttpsPort>47984</HttpsPort>
<ExternalPort>47989</ExternalPort>
</root>
state 字段(SUNSHINE_SERVER_FREE/占用)适合做监控探活;/pair?uniqueid=...&phrase=getservercert&clientcert=<hex>&salt=<32hex>&devicename=... 是客户端侧握手(uniqueid 必须 UUID 格式),一般无需手工调。
7.3 监控最小集
$ curl -sk -o /dev/null -w "%{http_code}" -u admin:q1w2e3r4 https://localhost:47990/ # 200=存活
$ curl -s -o /dev/null -w "%{http_code}" http://localhost:47989/serverinfo?... # 200=GameStream 面正常
8. 退出码与排障
8.1 退出码表(实测汇总)
| 场景 | exit | 证据 |
|---|---|---|
--help / -h / -i 等非法 flag | 0 | usage 照常打印 |
--version / --creds 成功 | 0 | — |
未知命令(--diagnose) | 7 | Fatal: Unknown command: diagnose |
--creds 缺参 | 134 | std::logic_error → SIGABRT(core dumped) |
服务进程被 timeout 杀 | 124 | 非 Sunshine 语义,属测试包装 |
8.2 "命令看起来没反应"——parse 阶段日志只进 stdout
main.cpp 注释原文(259–260 行):日志系统初始化前的输出只出现在标准输出,不进日志文件与 UI 日志页。表现:config: 行出现两次——一次原始格式(微秒+线程 ID,stdout 独有),一次标准格式(进 sunshine.log):
[2026-11-03 03:08:06.931141] [0x000075940a694000] [info] config: 'sunshine_name' = d1test
[2026-11-03 03:08:06.931]: Info: config: 'sunshine_name' = d1test
同理 Unrecognized flag、Warning: Unrecognized configurable option [...](C1 7.1)都只在 stdout。用 systemd 跑的话去 journalctl -u sunshine --user 找,别在 sunshine.log 里空转。
8.3 端口占用 fatal
第二个实例忘改 port:Fatal: Couldn't bind RTSP server to port [48010], Address already in use——进程直接退出。同机多实例先按 C1 4.1 公式平移 port。
8.4 POST /api/restart 在无头环境挂死
无显示/无编码后端时主循环自行退出(Main loop has exited,进程靠 UI 线程存活);此时点 UI 重启按钮或调 API:
[2026-11-03 02:37:52.104]: Info: Interrupt handler called
[2026-11-03 02:38:02.105]: Fatal: 10 seconds passed, yet Sunshine's still running: Forcing shutdown
之后进程不退出,只能服务管理器外部拉起。有头游戏主机不受影响。
8.5 凭据遗忘
sunshine --creds <user> <pass> 直接重写凭据(3.3),无需删 sunshine_state.json(删了会回到 /welcome 首启流程,已配对客户端不受影响——配对证书存在状态文件里,会一并重置,慎用)。
9. 参考链接
- 官方文档(docs.lizardbyte.dev,查询 2026-11-03):https://docs.lizardbyte.dev/projects/sunshine/latest/
- 源码
src/main.cpp/src/config.cpp/src/confighttp.cpp:https://github.com/LizardByte/Sunshine - 站内:Sunshine 介绍与选型指南
- 站内:Sunshine Docker Compose 部署指南
- 站内:Sunshine 2026.914.233613 配置参数详解