Skip to content

Bug: Windows PowerShell 5.1 上 supervisor-windows.ps1 无法运行(Join-Path 三参数 + $pid 撞自动变量) #108

Description

@mioyuan

Bug: Windows PowerShell 5.1 上 supervisor-windows.ps1 无法运行(Join-Path 三参数 + $pid 撞自动变量)

环境

  • OS:Windows 10 Pro (10.0.19043)
  • Shell:Windows PowerShell 5.1.19041.2364(系统自带)
  • 调用方式:bash scripts/daemon.sh <任意子命令>

现象

在 PS 5.1 上运行任意 daemon.sh 子命令(stop / status / logs / start …)都直接报错,无法管理 bridge。

错误 1(脚本加载阶段):

supervisor-windows.ps1 : A positional parameter cannot be found that accepts argument 'bridge.log'.
    + CategoryInfo          : InvalidArgument: (:) [supervisor-windows.ps1], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,supervisor-windows.ps1

错误 2(修掉错误 1 后执行 stop/status):

supervisor-windows.ps1 : Cannot overwrite variable PID because the variable has been optimized.
    + CategoryInfo          : WriteError: (PID:String) [supervisor-windows.ps1],
                              SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableNotWritable,supervisor-windows.ps1

根因

Join-Path 在 PS 5.1 只支持 2 个位置参数

# scripts/supervisor-windows.ps1:36-37
$LogFile    = Join-Path $CtiHome 'logs' 'bridge.log'    # 3 个位置参数
$DaemonMjs  = Join-Path $SkillDir 'dist' 'daemon.mjs'   # 3 个位置参数

PowerShell 7+ 才支持 -AdditionalChildPath / 多个位置参数。PS 5.1 的 Join-Path 仅接受 -Path + -ChildPath,第三个参数无法绑定,脚本在全局赋值阶段就直接抛错,导致所有子命令在加载时即失败。

$pid 与 PowerShell 自动只读变量 $PID 冲突

function Test-PidAlive {
    param([string]$Pid)         # 参数名撞 $PID
    ...
}

# stop / status / start-fallback 分支
$pid = Read-Pid                 # 给只读自动变量赋值

$PID 是 PowerShell 内置的只读自动变量(当前进程 PID)。PS 变量名不区分大小写,所以 $pid$Pid 都指向它,赋值时抛 VariableNotWritable

注:脚本里同时存在的 $PidFile(完整名 PidFile)与 $PID 不冲突,可保留。

修复(diff)

--- a/scripts/supervisor-windows.ps1
+++ b/scripts/supervisor-windows.ps1
@@ -33,8 +33,8 @@
 $PidFile    = Join-Path $RuntimeDir 'bridge.pid'
 $StatusFile = Join-Path $RuntimeDir 'status.json'
-$LogFile    = Join-Path $CtiHome 'logs' 'bridge.log'
-$DaemonMjs  = Join-Path $SkillDir 'dist' 'daemon.mjs'
+$LogFile    = Join-Path (Join-Path $CtiHome 'logs') 'bridge.log'
+$DaemonMjs  = Join-Path (Join-Path $SkillDir 'dist') 'daemon.mjs'

@@ -74,9 +74,9 @@
 function Test-PidAlive {
-    param([string]$Pid)
-    if (-not $Pid) { return $false }
-    try { $null = Get-Process -Id ([int]$Pid) -ErrorAction Stop; return $true }
+    param([string]$ProcId)
+    if (-not $ProcId) { return $false }
+    try { $null = Get-Process -Id ([int]$ProcId) -ErrorAction Stop; return $true }
     catch { return $false }
 }

@@ -270,1 +270,1 @@
-            $pid = Start-Fallback
+            $bridgePid = Start-Fallback

@@ -297,5 +297,5 @@
-            $pid = Read-Pid
-            if (-not $pid) { Write-Host "No bridge running"; exit 0 }
-            if (Test-PidAlive $pid) {
-                Stop-Process -Id ([int]$pid) -Force
+            $bridgePid = Read-Pid
+            if (-not $bridgePid) { Write-Host "No bridge running"; exit 0 }
+            if (Test-PidAlive $bridgePid) {
+                Stop-Process -Id ([int]$bridgePid) -Force

@@ -310,3 +310,3 @@
-        $pid = Read-Pid
+        $bridgePid = Read-Pid
@@ -318,2 +318,2 @@
-        if ($pid -and (Test-PidAlive $pid)) {
-            Write-Host "Bridge process is running (PID: $pid)"
+        if ($bridgePid -and (Test-PidAlive $bridgePid)) {
+            Write-Host "Bridge process is running (PID: $bridgePid)"

验证

修复后:

$ bash ~/.claude/skills/claude-to-im/scripts/daemon.sh stop
Windows detected. Delegating to supervisor-windows.ps1...
Bridge stopped

额外建议

  1. CI 上跑一遍 Windows PowerShell 5.1(GitHub Actions windows-2019 runner 默认就是 5.1),可以提前发现 PS7-only 语法。
  2. 仓库里其他脚本(如 doctor.ps1 等未检查全部)可能也有同类问题,建议统一 grep:
    rg 'Join-Path\s+\S+\s+\S+\s+\S+' scripts/
    rg '\$pid\b' scripts/
  3. 或者在 daemon 脚本头加版本检查:
    if ($PSVersionTable.PSVersion.Major -lt 7) {
        Write-Warning "Detected PS $($PSVersionTable.PSVersion). Some features require PowerShell 7+."
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions