@wendongfly/myhi 1.3.22 → 1.3.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/myhi.js +172 -23
- package/package.json +1 -1
package/bin/myhi.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { spawn } from 'child_process';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { dirname, join } from 'path';
|
|
5
|
-
import { mkdirSync, openSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
|
|
5
|
+
import { mkdirSync, openSync, readFileSync, writeFileSync, unlinkSync, existsSync } from 'fs';
|
|
6
6
|
import { homedir } from 'os';
|
|
7
7
|
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -557,38 +557,65 @@ SSH 账号管理:为 myhi 用户创建独立的 SSH 开发账号
|
|
|
557
557
|
});
|
|
558
558
|
|
|
559
559
|
} else if (cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|
560
|
-
|
|
561
|
-
|
|
560
|
+
const isWin = process.platform === 'win32';
|
|
561
|
+
const isLinux = process.platform === 'linux';
|
|
562
|
+
const isMac = process.platform === 'darwin';
|
|
563
|
+
const platform = isWin ? 'Windows' : isMac ? 'macOS' : 'Linux';
|
|
564
|
+
const configPath = isWin ? '%USERPROFILE%\\.myhi\\' : '~/.myhi/';
|
|
565
|
+
const sep = isWin ? '\\' : '/';
|
|
566
|
+
|
|
567
|
+
let help = `
|
|
568
|
+
myhi — 基于 Web 的终端共享工具 (${platform})
|
|
562
569
|
通过局域网或 Tailscale 在手机/平板上控制电脑终端,无需中继服务器。
|
|
563
570
|
|
|
564
|
-
|
|
571
|
+
启动服务:
|
|
565
572
|
myhi 前台启动服务器
|
|
566
573
|
myhi start 前台启动服务器
|
|
567
574
|
myhi -p <port> 指定监听端口(默认 12300)
|
|
568
|
-
myhi -d
|
|
575
|
+
myhi -d 后台启动(日志写入 ${configPath}daemon.log)
|
|
569
576
|
myhi stop 停止后台服务器
|
|
570
577
|
myhi restart 重启后台服务器
|
|
571
|
-
myhi status
|
|
578
|
+
myhi status 查看运行状态
|
|
572
579
|
myhi log [N] 查看后台日志(最后 N 行,默认 50)
|
|
580
|
+
`;
|
|
581
|
+
|
|
582
|
+
if (isLinux) {
|
|
583
|
+
help += `
|
|
584
|
+
系统服务(systemd):
|
|
585
|
+
sudo myhi service install 安装为系统服务(开机自启)
|
|
586
|
+
sudo myhi service uninstall 卸载系统服务
|
|
587
|
+
myhi service status 查看服务状态
|
|
588
|
+
|
|
589
|
+
提示: 使用 systemd 管理时,不要混用 myhi -d / myhi stop
|
|
590
|
+
统一用 systemctl start/stop/restart myhi
|
|
591
|
+
`;
|
|
592
|
+
}
|
|
573
593
|
|
|
594
|
+
help += `
|
|
574
595
|
用户管理:
|
|
575
|
-
myhi user list
|
|
596
|
+
myhi user list 列出所有用户
|
|
576
597
|
myhi user add <密码> <名称> <目录> 添加用户
|
|
577
|
-
myhi user remove <密码>
|
|
578
|
-
myhi exclusive on
|
|
579
|
-
myhi exclusive off
|
|
598
|
+
myhi user remove <密码> 删除用户
|
|
599
|
+
myhi exclusive on 开启独占模式(一次只能一个账号)
|
|
600
|
+
myhi exclusive off 关闭独占模式(多人同时使用,默认)
|
|
601
|
+
`;
|
|
580
602
|
|
|
603
|
+
if (!isWin) {
|
|
604
|
+
help += `
|
|
581
605
|
SSH 开发:
|
|
582
606
|
myhi ssh add <用户名> [密码] 为 myhi 用户创建 SSH 账号
|
|
583
607
|
myhi ssh list 列出所有 SSH 账号
|
|
584
608
|
myhi ssh remove <用户名> 删除 SSH 账号
|
|
609
|
+
`;
|
|
610
|
+
}
|
|
585
611
|
|
|
612
|
+
help += `
|
|
586
613
|
远程连接:
|
|
587
|
-
myhi attach
|
|
614
|
+
myhi attach 交互式选择会话并附加
|
|
588
615
|
myhi attach <id> 直接附加到指定会话
|
|
589
616
|
myhi attach --new 创建新会话并附加
|
|
590
|
-
myhi attach --password <密码>
|
|
591
|
-
myhi kick
|
|
617
|
+
myhi attach --password <密码> 用指定用户身份连接
|
|
618
|
+
myhi kick 踢出在线用户
|
|
592
619
|
|
|
593
620
|
快捷键(attach 模式):
|
|
594
621
|
Ctrl+] 分离终端(退出但不关闭会话)
|
|
@@ -603,23 +630,145 @@ SSH 开发:
|
|
|
603
630
|
MYHI_CWD 会话工作目录(默认当前目录)
|
|
604
631
|
MYHI_SERVER attach 连接的服务器地址(默认 http://localhost:12300)
|
|
605
632
|
|
|
606
|
-
|
|
633
|
+
配置目录:${configPath}
|
|
607
634
|
token 认证令牌(自动生成)
|
|
608
635
|
password 登录密码(自动生成,可手动修改)
|
|
609
|
-
users.json
|
|
636
|
+
users.json 独占用户配置
|
|
610
637
|
roles.json 多用户角色配置(可选)
|
|
611
638
|
sessions.json 会话持久化数据
|
|
612
639
|
daemon.pid 后台进程 PID
|
|
613
640
|
daemon.log 后台运行日志
|
|
614
641
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
myhi
|
|
621
|
-
myhi
|
|
622
|
-
|
|
642
|
+
示例:`;
|
|
643
|
+
|
|
644
|
+
if (isWin) {
|
|
645
|
+
help += `
|
|
646
|
+
myhi # 启动后扫描二维码即可在手机上操作
|
|
647
|
+
myhi -p 8080 # 指定 8080 端口启动
|
|
648
|
+
myhi -p 8080 -d # 8080 端口后台启动
|
|
649
|
+
set MYHI_CWD=D:\\project && myhi # 指定工作目录
|
|
650
|
+
myhi attach # 从另一台机器连接
|
|
651
|
+
myhi user add 1234 张三 D:\\project # 添加用户`;
|
|
652
|
+
} else if (isLinux) {
|
|
653
|
+
help += `
|
|
654
|
+
myhi # 启动后扫描二维码即可在手机上操作
|
|
655
|
+
myhi -p 8080 # 指定 8080 端口启动
|
|
656
|
+
sudo myhi service install # 安装为系统服务(推荐)
|
|
657
|
+
MYHI_CWD=/project myhi # 指定工作目录
|
|
658
|
+
myhi attach # 从另一台机器连接
|
|
659
|
+
myhi user add 1234 张三 /home/dev # 添加用户`;
|
|
660
|
+
} else {
|
|
661
|
+
help += `
|
|
662
|
+
myhi # 启动后扫描二维码即可在手机上操作
|
|
663
|
+
myhi -p 8080 # 指定 8080 端口启动
|
|
664
|
+
myhi -p 8080 -d # 8080 端口后台启动
|
|
665
|
+
MYHI_CWD=/project myhi # 指定工作目录
|
|
666
|
+
myhi attach # 从另一台机器连接
|
|
667
|
+
myhi user add 1234 张三 /Users/dev # 添加用户`;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
console.log(help + '\n');
|
|
671
|
+
|
|
672
|
+
} else if (cmd === 'service') {
|
|
673
|
+
// systemd service 管理
|
|
674
|
+
const subCmd = args[1] || 'install';
|
|
675
|
+
const { execSync: ex } = await import('child_process');
|
|
676
|
+
|
|
677
|
+
if (process.platform !== 'linux') {
|
|
678
|
+
console.log('[myhi] service 命令仅支持 Linux (systemd)');
|
|
679
|
+
process.exit(1);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// 找到 myhi 可执行文件路径
|
|
683
|
+
let myhiBin;
|
|
684
|
+
try { myhiBin = ex('which myhi', { encoding: 'utf8' }).trim(); } catch { myhiBin = '/usr/local/bin/myhi'; }
|
|
685
|
+
|
|
686
|
+
const user = process.env.USER || 'root';
|
|
687
|
+
const home = homedir();
|
|
688
|
+
const cwd = process.env.MYHI_CWD || process.cwd();
|
|
689
|
+
const port = process.env.PORT || '12300';
|
|
690
|
+
const serviceFile = '/etc/systemd/system/myhi.service';
|
|
691
|
+
|
|
692
|
+
const unitContent = `[Unit]
|
|
693
|
+
Description=myhi - Web Terminal Sharing
|
|
694
|
+
After=network.target
|
|
695
|
+
|
|
696
|
+
[Service]
|
|
697
|
+
Type=forking
|
|
698
|
+
PIDFile=${home}/.myhi/daemon.pid
|
|
699
|
+
ExecStart=${myhiBin} -d
|
|
700
|
+
ExecStop=${myhiBin} stop
|
|
701
|
+
WorkingDirectory=${cwd}
|
|
702
|
+
Restart=on-failure
|
|
703
|
+
RestartSec=10
|
|
704
|
+
User=${user}
|
|
705
|
+
Environment=PORT=${port}
|
|
706
|
+
Environment=HOME=${home}
|
|
707
|
+
|
|
708
|
+
[Install]
|
|
709
|
+
WantedBy=multi-user.target
|
|
710
|
+
`;
|
|
711
|
+
|
|
712
|
+
if (subCmd === 'install') {
|
|
713
|
+
try {
|
|
714
|
+
writeFileSync(serviceFile, unitContent);
|
|
715
|
+
} catch (e) {
|
|
716
|
+
if (e.code === 'EACCES') {
|
|
717
|
+
console.log('[myhi] 需要 root 权限,请使用: sudo myhi service install');
|
|
718
|
+
process.exit(1);
|
|
719
|
+
}
|
|
720
|
+
throw e;
|
|
721
|
+
}
|
|
722
|
+
console.log(`[myhi] 已创建 ${serviceFile}`);
|
|
723
|
+
console.log(` User: ${user}`);
|
|
724
|
+
console.log(` Port: ${port}`);
|
|
725
|
+
console.log(` WorkingDirectory: ${cwd}`);
|
|
726
|
+
console.log(` ExecStart: ${myhiBin} -d`);
|
|
727
|
+
console.log('');
|
|
728
|
+
try {
|
|
729
|
+
ex('systemctl daemon-reload', { stdio: 'inherit' });
|
|
730
|
+
ex('systemctl enable myhi.service', { stdio: 'inherit' });
|
|
731
|
+
ex('systemctl start myhi.service', { stdio: 'inherit' });
|
|
732
|
+
console.log('');
|
|
733
|
+
console.log('[myhi] 服务已启动并设为开机自启');
|
|
734
|
+
console.log(' 查看状态: systemctl status myhi.service');
|
|
735
|
+
console.log(' 查看日志: journalctl -u myhi -f');
|
|
736
|
+
console.log(' 停止服务: sudo systemctl stop myhi.service');
|
|
737
|
+
} catch (e) {
|
|
738
|
+
console.log('[myhi] systemctl 执行失败,请手动运行:');
|
|
739
|
+
console.log(' sudo systemctl daemon-reload');
|
|
740
|
+
console.log(' sudo systemctl enable myhi.service');
|
|
741
|
+
console.log(' sudo systemctl start myhi.service');
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
} else if (subCmd === 'uninstall' || subCmd === 'remove') {
|
|
745
|
+
try {
|
|
746
|
+
ex('systemctl stop myhi.service', { stdio: 'pipe' });
|
|
747
|
+
ex('systemctl disable myhi.service', { stdio: 'pipe' });
|
|
748
|
+
} catch {}
|
|
749
|
+
try {
|
|
750
|
+
unlinkSync(serviceFile);
|
|
751
|
+
ex('systemctl daemon-reload', { stdio: 'pipe' });
|
|
752
|
+
console.log('[myhi] 已卸载 systemd 服务');
|
|
753
|
+
} catch (e) {
|
|
754
|
+
if (e.code === 'EACCES') {
|
|
755
|
+
console.log('[myhi] 需要 root 权限,请使用: sudo myhi service uninstall');
|
|
756
|
+
} else if (e.code === 'ENOENT') {
|
|
757
|
+
console.log('[myhi] 服务文件不存在');
|
|
758
|
+
} else {
|
|
759
|
+
console.log('[myhi] 卸载失败:', e.message);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
} else if (subCmd === 'status') {
|
|
764
|
+
try {
|
|
765
|
+
ex('systemctl status myhi.service', { stdio: 'inherit' });
|
|
766
|
+
} catch {}
|
|
767
|
+
|
|
768
|
+
} else {
|
|
769
|
+
console.log('用法: myhi service [install|uninstall|status]');
|
|
770
|
+
}
|
|
771
|
+
process.exit(0);
|
|
623
772
|
|
|
624
773
|
} else if (cmd === '-d' || cmd === '--daemon' || cmd === 'daemon') {
|
|
625
774
|
startDaemon();
|