URL: /built-in/shell_exec

---
title: shell_exec — 执行命令
description: 在本地系统执行 shell 命令并返回标准输出、标准错误和退出码
---

在本地系统执行 shell 命令并返回标准输出、标准错误和退出码。

**适用场景**：让 AI 运行代码检查、查询系统信息、操作文件、执行 git 命令等。

## 参数

| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| `command` | string | 是 | 要执行的 shell 命令 |
| `description` | string | 是 | 向用户解释为什么执行此命令及预期效果 |
| `working_directory` | string | 否 | 命令执行的工作目录（绝对路径），不指定则使用当前目录 |

## 安全机制

交互模式（TTY）下，AI Agent 每次执行命令前都会弹出确认提示，由你决定是否授权：

```
⚠️  准备执行命令:
  └ 描述: 检查当前目录下 Rust 文件的编码格式
  └ 命令: file src/*.rs

? 是否确认执行？
  ▸ 1. 允许
    0. 拒绝
```

- **允许** — 按 `Enter` 或 `1`，命令将被执行
- **拒绝** — 按 `0`，命令被取消
- `Ctrl+C` — 安全退出

> **非交互环境**（管道、CI、重定向等）：默认拒绝所有命令执行，这是安全设计。

### 自动放行

对于绝对安全的只读命令（如查看系统信息、打印工作目录等），shell_exec 会自动放行，
不会弹出确认提示。内置命令列表按操作系统划分：

<Tabs>

<Tab title="macOS / Linux">
适用于 Unix 系操作系统：

| 类别 | 命令 | 说明 |
|------|------|------|
| 通用 | `pwd` | 打印工作目录 |
| | `whoami` | 打印当前用户名 |
| | `true` `false` | 无操作，返回 0/1 |
| | `echo` | 输出文本（需带参数，裸 `echo` 不放行） |
| | `printf` | 格式化输出（需带参数） |
| | `cd` | 改变工作目录 |
| 系统信息 | `uname` | 系统信息 |
| | `hostname` | 主机名 |
| | `uptime` | 系统运行时间 |
| | `arch` | 硬件架构 |
| | `which` | 定位命令路径（需带参数） |
| | `id` | 用户身份信息 |
| | `logname` | 登录用户名 |
| | `tty` | 终端设备名 |
| | `cal` | 显示日历 |
| | `seq` | 生成数字序列（需带参数） |
| | `getconf` | 系统配置变量（需带参数） |
| | `pathchk` | 路径名检查（需带参数） |
| 路径操作 | `basename` | 从路径中提取文件名（需带参数） |
| | `dirname` | 从路径中提取目录名（需带参数） |
| | `realpath` | 解析为绝对路径（需带参数） |
| 目录列表 | `ls` | 列出目录内容 |
| 日期时间 | `date` | 查看当前日期时间 |

</Tab>

<Tab title="Windows">
适用于 Windows 操作系统：

| 类别 | 命令 | 说明 |
|------|------|------|
| 通用 | `pwd` | 打印工作目录 |
| | `whoami` | 打印当前用户名 |
| | `true` `false` | 无操作，返回 0/1 |
| | `echo` | 输出文本（需带参数，裸 `echo` 不放行） |
| | `printf` | 格式化输出（需带参数） |
| | `cd` | 改变工作目录 |
| 系统信息 | `hostname` | 主机名 |
| | `which` | 定位命令路径（需带参数） |
| | `id` | 用户身份信息 |
| | `ver` | 显示 Windows 版本 |
| | `systeminfo` | 显示系统信息 |
| 目录列表 | `dir` | 列出目录 |
| 日期时间 | `date /t` | 显示日期（`/t` 表示只查看不设置） |
| | `time /t` | 显示时间（`/t` 表示只查看不设置） |
| | `vol` | 显示卷标 |

</Tab>
</Tabs>

**匹配规则**：命令以列表中的某个条目开头即匹配（前缀匹配）。
例如 `ls` 会放行 `ls` 和 `ls -la`，但不会误放 `lsblk`。

> 即使前缀匹配，包含 `;` `|` `>` `<` `` ` `` `$` `&` 等控制运算符的命令仍会要求确认，这是安全保护。

> 内置列表的設計原则是"宁可漏放（回到确认流程）也不错放"。
> 如果内置列表未覆盖你常用的安全命令，可以通过 `[permissions.commands]` 配置自行扩展。

### 自定义权限配置

你可以在 `~/.zapmyco/settings.toml` 中配置命令的自动放行（白名单）和自动拒绝（黑名单）：

```toml
[permissions.commands]
# 自动放行的命令前缀列表（白名单）
# 命令将以"开头匹配"的方式检查：
# - "git status" 会放行 "git status" 和 "git status -s"
# - 匹配的命令会跳过用户确认
allow = [
    "git status",
    "git diff",
    "git log",
    "cargo check",
    "cargo clippy",
    "cargo fmt --check",
]

# 自动拒绝的命令前缀列表（黑名单，优先于 allow）
# 如果一个命令同时匹配 allow 和 deny，deny 优先生效
deny = [
    "rm -rf",
    "sudo",
]
```

> 在配置自定义放行命令时请谨慎评估安全性。
> 即使配置了放行列表，包含控制运算符的命令仍会要求确认。

## 约束与限制

| 限制项 | 值 |
|--------|:----:|
| 执行超时 | 30 秒 |
| 输出最大长度 | 100,000 字符（stdout + stderr 合计） |
| Shell（Unix） | `sh -c` |
| Shell（Windows） | `cmd.exe /C` |

## 错误场景

| 错误类型 | 说明 |
|----------|------|
| 超时 | 命令执行超过 30 秒 |
| 命令未找到 | Shell 无法找到指定的可执行文件 |
| 输出过大 | stdout + stderr 超过 100K 字符限制 |
| 用户拒绝 | 用户在确认提示中选择了"拒绝"或 `Ctrl+C` |

## 使用示例

```bash
zapmyco run '列出当前目录的文件'
zapmyco run '运行测试并显示结果'
zapmyco run --profile advanced '重构 src/cli.rs 中的重复代码，然后运行 cargo fmt'
```

## 相关文档

- [内置工具目录](/guide/built-in-tools) — 查看所有工具
