修复: 后端若干bug
This commit is contained in:
@@ -22,20 +22,49 @@ pub struct ShellResult {
|
||||
pub enum ShellType {
|
||||
/// Windows cmd.exe (默认 Windows)
|
||||
Cmd,
|
||||
/// PowerShell
|
||||
/// PowerShell 5.x(Windows 自带,不支持 && 运算符)
|
||||
PowerShell,
|
||||
/// PowerShell 7(pwsh,支持 && 运算符;运行时探测,未装回退 PowerShell)
|
||||
Pwsh,
|
||||
/// Unix sh (默认非 Windows)
|
||||
Sh,
|
||||
}
|
||||
|
||||
impl Default for ShellType {
|
||||
fn default() -> Self {
|
||||
// L1 环境感知:Windows 默认 PowerShell(非 Cmd)。PowerShell 对引号/$变量/Unicode 处理
|
||||
// L1 环境感知:Windows 默认 PowerShell 系(非 Cmd)。PowerShell 对引号/$变量/Unicode 处理
|
||||
// 远优于 cmd,从根上避 kms 类引号转义地狱(seq26-52 撞墙 20+ 次)。AI 写文件执行见 env_profile。
|
||||
if cfg!(windows) { ShellType::PowerShell } else { ShellType::Sh }
|
||||
// BUG-260623-04:优先 pwsh(PS7,支持 && 运算符)——LLM 训练数据 Unix 多,普遍生成 `cd x && y`,
|
||||
// PS5 不支持 && 致命令失败(实测会话 6acb7f9b `cd ... && git init` InvalidEndOfLine)。
|
||||
// 探测失败(未装 pwsh)回退 PS5。探测结果 OnceLock 缓存(只探一次)。
|
||||
if cfg!(windows) {
|
||||
if probe_pwsh() { ShellType::Pwsh } else { ShellType::PowerShell }
|
||||
} else {
|
||||
ShellType::Sh
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 探测 pwsh(PowerShell 7)是否可用(OnceLock 缓存,只探一次)。
|
||||
///
|
||||
/// LLM 普遍生成 `&&`(Unix 习惯),仅 PS7+ 支持,Windows 自带 PS5 不支持。
|
||||
/// 探测:成功 spawn `pwsh -Command exit 0` 即可用。同步阻塞仅一次(spawn 极快),
|
||||
/// Windows 加 CREATE_NO_WINDOW 防黑窗闪现。
|
||||
fn probe_pwsh() -> bool {
|
||||
static CACHE: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
|
||||
*CACHE.get_or_init(|| {
|
||||
let mut cmd = std::process::Command::new("pwsh");
|
||||
cmd.arg("-NoProfile").arg("-Command").arg("exit 0");
|
||||
cmd.stdout(Stdio::null()).stderr(Stdio::null());
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::process::CommandExt;
|
||||
cmd.creation_flags(0x0800_0000); // CREATE_NO_WINDOW
|
||||
}
|
||||
cmd.status().map(|s| s.success()).unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
/// Shell 命令执行请求
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ShellRequest {
|
||||
@@ -67,6 +96,13 @@ pub async fn execute(request: ShellRequest) -> anyhow::Result<ShellResult> {
|
||||
c.stdout(Stdio::piped()).stderr(Stdio::piped());
|
||||
c
|
||||
}
|
||||
ShellType::Pwsh => {
|
||||
// PS7(支持 && 运算符),同 PS5 参数语义。-NoProfile 避加载用户 profile(速度+确定性)
|
||||
let mut c = tokio::process::Command::new("pwsh");
|
||||
c.arg("-NoProfile").arg("-Command").arg(&request.command);
|
||||
c.stdout(Stdio::piped()).stderr(Stdio::piped());
|
||||
c
|
||||
}
|
||||
ShellType::Cmd => {
|
||||
let mut c = tokio::process::Command::new("cmd");
|
||||
c.arg("/C").arg(&request.command);
|
||||
|
||||
Reference in New Issue
Block a user