# 使用方法

> HTML: https://remote.ivjn.us/docs/ja/usage/

この手順はオペレーター向けです。CLI とデバイス側プログラムを用意し、ログインしてデバイスを追加し、接続したデバイスでリモートコマンドを実行してシェルを開きます。ブラウザーコンソール、モバイルコンソール、Android デバイス側アプリ、ペアリング、自己更新については末尾のリンクを参照してください。それぞれのページの手順はここでは繰り返しません。

例のアドレスとトークンは自分のものに置き換えてください。トークンは作成時に一度しか表示されません。リポジトリには保存しないでください。

**名前付き ID とアカウント権限。** グローバルな `--profile <name>` は `REMOTE_CLI_PROFILE` より優先されます。`config.toml`、暗号化 ID の秘密鍵、ルートの信頼、grant キャッシュは `<config_base>/remote-cli/profiles/<name>/` に保存されます。`config_base` は従来の XDG_CONFIG_HOME、HOME/.config、Windows APPDATA です。名前は ASCII 英数字、点、ハイフン、下線の 1〜64 文字で、`.` と `..` は使用できません。名前付き profile は `REMOTE_CLI_CONFIG` より優先されます。profile 未指定時は従来のパスと `REMOTE_CLI_CONFIG` の動作を維持します。profile ごとにログインし、以降も同じ profile を選択してください。

`operator set` はアカウント ID または一意の名前を受け取り、デバイス引数はデバイス ID です。`--restricted` は明示的に許可されたデバイスのみを表示し、`--unrestricted` はロールに基づく範囲に戻します。範囲変更は最高管理者のみ可能です。ロールと権限は最高管理者が管理し、最高管理者がいない場合は管理者が許可範囲内で管理できます。自身の変更は不可です。`operator grant list` は呼び出し元が閲覧できる権限のみ返します。データベースのデバイス権限と署名付き grant は別の検査であり、変更しても `seal approve` の代わりにはなりません。作成 API は範囲の原子的な設定をサポートしません。`operator add` の一度限りのトークンを保存してから、別リクエストで `operator set` / `operator grant set` を実行してください。

operator の全操作は `-o text|json|xml` に対応します。JSON は `op=list|add|set|grant_list|grant_set|grant_remove` を使用します。`set` は `operator` と `role` / `restricted` の少なくとも一方、`grant_set` は `operator`、`device`、必須の真偽値 `can_manage` を受け取ります。`grant_list` の `operator` は省略可能、`grant_remove` は `operator` と `device` が必須です。`--json` とサブコマンドは併用できません。

```bash
remote-cli --profile alice login --server https://exchange.example.com
remote-cli --profile root operator set alice --restricted
remote-cli --profile root operator set alice --role readonly
remote-cli --profile root operator grant list --operator alice -o json
remote-cli --profile root operator grant set alice lab --view
remote-cli --profile root operator grant set alice lab --manage
remote-cli --profile root operator grant remove alice lab
remote-cli --profile root operator set alice --unrestricted
remote-cli --profile root operator --json '{"op":"grant_set","operator":"alice","device":"lab","can_manage":false}' -o json
```


## XML リクエストと出力

インストール済みバージョンの対応オプションを `remote-cli --help` で確認してください。`--xml` と `--xml-file` は既存の `--json` / `--json-file` リクエストに XML 入力を追加します。4 つの入力指定は排他的で、リクエスト本体全体を渡します。同じコマンドのオプションやサブコマンドと併用しないでください。デバイス位置引数の規則は変わりません。入力と出力は独立し、`-o text|json|xml` の既定はテキストです。

```powershell
remote-cli device --xml '<request><op>list</op></request>' -o xml
remote-cli exec my-device --xml-file request.xml -o xml
```

子要素がなければ文字列、あればオブジェクトが既定です。数値、真偽値、配列、null にはそれぞれ `type="number"`、`type="boolean"`、`type="array"`、`type="null"` を指定します。配列の子要素は `<item>`、空オブジェクトは `type="object"` を使います。任意のキーには `<field name="arbitrary key">value</field>`、空リクエストには `<request type="object"/>` を使います。

```xml
<request>
  <command>echo hello</command>
  <timeout_secs type="number">30</timeout_secs>
  <hold type="boolean">false</hold>
  <env><GREETING>hello &amp; welcome</GREETING></env>
</request>
```

出力ルートは `<response type="...">`、オブジェクトのメンバーは `<field name="..." type="...">`、配列の要素は `<item type="...">` です。型を明示し、テキストを XML 1.0 に従ってエスケープします。実行時エラーは `ok=false` / `error` と非ゼロ終了コードを返します。コマンドラインの構文エラーは引き続き `stderr` に出力します。

XML 出力は `device list/update`, `operator list/add/set/grant`, `exec`, `session list/kill`, `ui`, `ubus`, `sensors`, `net`, `metrics`, `preset`, `audit`, `browser` と exec ジョブ操作に対応します。その他のコマンドは `-o xml` を明示的に拒否しますが、XML 入力と既存の出力形式は使用できます。

ストリーム `exec` / `sensors --live` / `browser session` は 1 行につき独立した XML 文書を出力するため、行単位で解析します。exec データイベントには `stream` / `encoding=base64` / `data` が含まれ、Base64 が元のバイト列を保持します。通常の exec は終了状態で終わります。`browser session` の対話入力は JSON Lines のままです。`ui xml` は `-o xml` を指定しなければ生の UI 階層 XML を返します。

リクエストの上限は 1 MiB、入れ子は 64 階層です。重複フィールド、テキストと子要素の混在、DTD、外部実体を拒否します。XML 1.0 で表現できない制御文字を含むテキストには JSON を選んでください。Agent 設定と通信プロトコルは JSON のままで、XML は CLI の入出力変換だけに使用します。

## remote-cli と remote-agent の入手

リポジトリのルートでビルドします。

```bash
cargo build --release
```

CLI は `target/release/remote-cli` です。同じコマンドで `target/release/remote-agent` も生成されます。フラッシュ容量が少ないデバイスには、サイズを優先した agent を使用します。

```bash
cargo build -p agent --no-default-features --profile release-small
```

生成物は `target/release-small/remote-agent` です。

Windows、Linux、macOS では、Web サイトのインストールスクリプトでいずれか一方のバイナリを一度の操作でインストールすることもできます。[マルチプラットフォームへのデバイス展開](/docs/ja/platform-installation.md#コマンド-1-つでインストールwindows--linux--macos--freebsd--netbsd)を参照してください。以下のコマンドは `remote-cli` と `remote-agent` が `PATH` にあることを前提とします。ローカルでビルドした直後なら、上記の `target/...` パスを使用してください。

中継サービスを自分で運用する場合は、[開発ガイド](/docs/ja/development.md)に従い `DATABASE_URL` を設定して `exchange` を起動し、起動ログから管理者トークンを取得します。公開インスタンスを使う場合は、管理者から運用トークンを取得してください。

## ログイン

```bash
remote-cli login --server http://127.0.0.1:8080 --token '<运维令牌>'
```

`--server` には `http://` または `https://` を指定します。CLI は同じセキュリティレベルの WebSocket アドレスを導出します。`https` は `wss`、`http` は `ws` に対応します。

ログインに成功すると、次の場所に設定を書き込みます。

- Linux / macOS: `$XDG_CONFIG_HOME/remote-cli/config.toml`。`XDG_CONFIG_HOME` が未設定の場合は `~/.config/remote-cli/config.toml`
- Windows: `%APPDATA%\remote-cli\config.toml`

ファイルにあるキーは `server` と `token` の 2 つだけです。別のパスを使うには `REMOTE_CLI_CONFIG` を設定します。以降の `device`、`exec`、`shell` はこの設定を読み込むため、毎回トークンを渡す必要はありません。

## デバイスの追加

```bash
remote-cli device add lab-router --name "实验室路由"
```

`<id>` はデバイス ID です。英数字と `-` `_` `.` のみ使用でき、最大 64 文字です。`--name` は省略可能で、省略すると表示名は ID と同じになります。出力されるデバイストークンは、このとき一度だけ表示されます。

## agent の起動

管理対象のマシンで、サーバー、デバイス ID、先ほどのデバイストークンを指定してデバイス側プログラムを起動します。

```bash
remote-agent --server wss://127.0.0.1:8080 --device-id lab-router --token '<设备令牌>'
```

3 つの引数は環境変数 `REMOTE_SERVER`、`REMOTE_DEVICE_ID`、`REMOTE_TOKEN` でも指定できます。

`--server` は `ws://` または `wss://` で始まる必要があります。ホストのみ（例: `wss://mgmt.example.com`）を指定すると、agent は `/ws/device` を自動的に追加します。パスがある場合はそのまま使用します。ローカルの exchange に TLS がない場合は `ws://127.0.0.1:8080` を使用してください。

プロセス引数にトークンを含めたくない場合は、`server`、`device_id`、`token` をキーとする JSON を作成します。

```json
{
  "server": "wss://mgmt.example.com",
  "device_id": "lab-router",
  "token": "<设备令牌>"
}
```

その後 `remote-agent --config /path/to/config.json` を実行します。デスクトップシステムでのインストールと自動起動は[マルチプラットフォームへのデバイス展開](/docs/ja/platform-installation.md)を参照してください。

`remote-cli` と `remote-agent` の WebSocket は、どちらも `HTTPS_PROXY` / `https_proxy` → `ALL_PROXY` / `all_proxy` → `HTTP_PROXY` / `http_proxy` の順にプロキシ設定を読み、`NO_PROXY` / `no_proxy` に従います。agent のヘッドレスモードと `--ui` モードは同じ接続経路を使用します。プロキシには HTTP CONNECT のサポートが必要です（SOCKS は非対応）。WSS の ALPN は `http/1.1` のみを宣言します。バックグラウンドサービスではサービス環境に変数を設定してください。詳しくは[外向きプロキシと接続の維持](/docs/ja/platform-installation.md#アウトバウンドプロキシと接続維持)を参照してください。

デバイスが接続したら、次を実行します。

```bash
remote-cli device list
```

一覧でデバイスのオンライン状態を確認できます。

## リモートコマンドの実行

`--` 以降の内容はデバイスに渡され、ローカルの CLI では解析しません。

```bash
remote-cli exec lab-router -- uname -a
```

`--` の後に指定する引数の数によって、リモート側の解釈が変わります。

- **複数の引数**は argv としてそのまま送信し、引数ごとの境界を保持します。デバイス上でそれらの引数を直接入力するのと同じ動作です。必要に応じて CLI が自動で引用符を追加します（Windows デバイスでは PowerShell の規則を使用）。
- **引数が 1 つだけ**の場合は、文字列全体をデバイスのシェルがコマンドラインとして解析するため、パイプ、`;`、ワイルドカード、変数を使えます。

```bash
remote-cli exec lab-router -- sh -c 'uname -a; cat /proc/uptime'   # 多个参数，第三个参数完整交给 sh -c
remote-cli exec lab-router -- 'dmesg | tail -20'                    # 一个参数，管道在设备上执行
```

注意: 複数引数形式では、ローカルシェルからそのまま渡された `*` や `$VAR`（PowerShell でよく見られます）はリテラルとして扱われ、リモートでは展開されません。デバイス上で展開するには、`-- 'ls /etc/*.conf'` のように 1 つの引数にします。

exec は既定で hold が有効です。既定のタイムアウトは 3600 秒（絶対上限は 86400 秒）で、オペレーターが切断しても出力を切り離すだけでジョブは終了しません。`--timeout` で制限時間を指定できます。例: `remote-cli exec lab-router --timeout 120 -- uname -a`。`--hold-timeout` で hold の制限時間を上書きできます。`--no-hold` を付けるとオペレーターの切断時にキャンセルする動作になり、既定のタイムアウトは 60 秒です。コマンドが正常に戻ると、その終了コードが `remote-cli` の終了コードになります。

### ジョブの確認と終了、セッション枠の解放

```bash
remote-cli exec-holds lab-router
remote-cli exec-hold-kill lab-router <job_id>
remote-cli exec-hold-tail lab-router <job_id>
remote-cli exec-hold-cat lab-router <job_id>
remote-cli exec-attach lab-router <job_id>
remote-cli sessions lab-router
remote-cli session-kill lab-router <session_id>
```

`exec-holds` は exec ジョブと進行中のダウンロード、アップロード、ディレクトリ照会を一覧表示します。`job_id`、`kind`、`status`、`age_secs`、現在のデバイス側 `session_id`（ある場合）、短く切り詰めたコマンドまたはパスの概要が表示されます。`exec-hold-kill` はジョブ番号を指定してプロセスグループを終了するか、ファイル転送を中止します。tail、cat、attach は exec ジョブ専用です。

`sessions` は Exchange のルーティングテーブルを直接読み、現在の `count/limit` とデバイス側のセッション番号を表示します。`session-kill` はこの**デバイス側**番号を使用してデバイスにキャンセル指示を送り、直ちに Exchange の枠を解放します。デバイスから応答がなくても解放できます。どちらもデバイスへの追加セッションを作らず、同時実行枠を消費しないため、枠が埋まって停止したセッションへの対処に適しています。読み取り専用アカウントは使用できません。

exec のタイムアウト時はプロセスグループ全体を終了します。出力の排出と終了メッセージの送信にも制限時間があります。Exchange は同時実行上限に達すると、オペレーターを失ったルートや期限切れのルートを自動回収してから、新しいセッションを試みます。exec の期限は実際の実行制限時間に 15 秒の猶予を加えたもの、ファイル転送は 3600 秒に 15 秒を加えたもの（デバイス側には別途 30 秒のアイドルタイムアウト）、その他のセッションは 24 時間です。hold exec は期限内であればオペレーターの切断だけでは終了せず、切断は引き続き detach として扱います。明示的な `session-kill` または期限超過では hold プロセスをキャンセルします。

## シェルを開く

```bash
remote-cli shell lab-router
```

これはデバイス上の PTY セッションです。SSH ではありません。シェルを終了するとセッションも終了します。

## その他の入口

- ブラウザーコンソール: [Web コンソール](/docs/ja/web-console-and-notifications.md)
- モバイルコンソール: [モバイルクライアント](/docs/ja/platform-installation.md)
- Android デバイス側 APK: [Android スタンドアロン APK](/docs/ja/platform-installation.md#android-独立-apk)
- QR コード、6 桁コード、アカウント: [初期化とペアリング](/docs/ja/pairing-and-enrollment.md)
- CLI と agent の自己更新: [自己更新](/docs/ja/self-update.md)

## エンドツーエンド暗号化（密封セッション）

`remote-cli exec <设备> -- <命令>`、`remote-cli shell <设备>` は追加の引数なしで、エンドツーエンドの密封セッションを使用します。Exchange は暗号文のみを中継し、コマンド、出力、端末内容を読み取れません。デバイスはワークスペースのルート（スーパー管理者の鍵。スーパー管理者のログイン時に自動生成）と、ルートが発行した認可のみを信頼します。ルートクライアントはアカウントの役割に従ってメンバーに自動発行します。初回のみ必要な設定はリンク先を参照してください。詳しくは[エンドツーエンド密封セッション](/docs/ja/sealed-sessions.md)を参照してください。

すべての CLI デバイスセッションはエンドツーエンドの密封のみを使用し、追加の引数は不要です。デバイスの機能情報がない場合や密封ハンドシェイクに失敗した場合も、平文に切り替えることはありません。LAN 直接接続とブラウザー操作にも同じ密封要件が適用されます。

## 永続バックグラウンドタスク

`tasks` を公開する Agent は単一操作と宣言的 DAG をデバイス上で実行します。切断後も実行を継続し、再接続すると進捗、出力、成果物を取得できます。ランタイム再起動時は未完了の処理を `interrupted` にし、自動再実行しません。

作成には密封された `manage/owner` 権限が必要です。依存関係、固定条件、祖先の結果への JSON Pointer 参照、失敗方針、最大 5 回の明示的な再試行を設定できます。再試行は副作用を繰り返す場合があり、取消は元に戻しません。Web とモバイルはフォームと JSON 入出力に対応します。デスクトップ、Android、ブラウザ、LuCI のローカル画面で履歴、出力、取消、削除を管理します。

最初に操作一覧でデバイスの対応状況と除外理由を確認し、入力ファイルを準備してください。既定は履歴 30 日、1000 件、合計 64 MiB、タスクあたりテキスト 8 MiB、並列ステップ 4（OpenWrt は 2）です。ステップの既定制限は 30 分、最大 24 時間です。古い Agent にはタスク入口を表示しません。
```sh
remote-cli task DEVICE operations
remote-cli task DEVICE create pipeline.json --wait
remote-cli task DEVICE list
remote-cli task DEVICE get TASK_ID
remote-cli task DEVICE logs TASK_ID --offset 0
remote-cli task DEVICE cancel TASK_ID
remote-cli task DEVICE upload ./input.bin
remote-cli task DEVICE download TASK_ID STEP.artifact ./result.json
remote-cli task DEVICE delete TASK_ID
```

## 常駐サービス

Task の Service モードは、ネイティブのフォアグラウンドコマンドを管理します。実行状態の永続化、終了時の再起動、指数バックオフ、起動頻度の制限、Agent 再起動後の復帰に対応します。初期状態は停止です。編集や削除の前に停止を完了してください。権限の期限切れや取消で停止します。通常の DAG は再実行しません。Web、モバイル、デスクトップ、Android で管理でき、LuCI の設定は Console または CLI で行います。ブラウザー Agent はシステムプロセスを管理できません。

command.command または command.argv を使い、cwd/env、restart (never/on_failure/always)、start_secs、stop_grace_secs、backoff_secs、max_backoff_secs、restart_window_secs、max_starts を設定できます。Windows の正常終了には stop_command が必要です。Unix は SIGTERM を送り、猶予期間後にプロセスツリーを強制終了します。Agent の自動起動は別途設定します。service get の run_id を task get/logs で参照できます。

```sh
remote-cli task DEVICE service put worker.json
remote-cli task DEVICE service list
remote-cli task DEVICE service start worker
remote-cli task DEVICE service get worker
remote-cli task DEVICE service restart worker
remote-cli task DEVICE service stop worker
remote-cli task DEVICE service delete worker
remote-agent task service put worker.json
```
