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)。

SunshineSunshine运维游戏串流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. 环境信息

项目值
服务器 OSUbuntu 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 / APIhttps://localhost:47990(自签证书,Basic 认证 admin/q1w2e3r4)
GameStream HTTPhttp://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():逐字符翻转,非赋值):

开关内部标志语义
-0PIN_STDIN配对 PIN 从标准输入读取(不走 Web UI 输入框),无人值守配对接入点
-1FRESH_STATE不加载已保存状态、退出也不保留——"如首次启动",但不覆盖既有配对文件
-2FORCE_VIDEO_HEADER_REPLACE强制替换视频流参数集头(花屏类兼容问题急救)
-pUPNP开/关 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

两个观察:

  1. -p 生效(尝试 UPnP,本网络无设备 → 告警但继续运行);
  2. 该次运行目录树里没有 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 等非法 flag0usage 照常打印
--version / --creds 成功0—
未知命令(--diagnose)7Fatal: Unknown command: diagnose
--creds 缺参134std::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. 参考链接