codex 方便快速执行:

codex --ask-for-approval never

Linux 服务器 Codex 执行 pwdls 无响应:bubblewrap 沙箱卡死的解决方案

一、问题现象

在 Linux 服务器上通过 OpenAI 官方安装脚本安装 Codex CLI 后,Codex 可以正常启动、登录和调用模型:

codex

但当 Codex 尝试读取或修改本地文件时,会提示:

暂未修改文件:当前终端执行异常,连 pwd、ls 等基础只读命令都持续无响应,因此无法安全读取、编辑并验证目标脚本。

直接测试 Codex 沙箱也会超时:

timeout 15 codex sandbox -- /bin/pwd
echo $?

返回:

124

124 表示命令被 timeout 强制终止,说明问题不是 pwdls 命令本身,而是 Codex 的 Linux 沙箱没有成功启动。


二、问题原因

Codex CLI 安装成功,只代表 Codex 主程序可以正常启动,并不代表 Linux 本地沙箱环境一定正常。

Codex 在 Linux 上执行本地命令时,需要使用 bubblewrap,其命令名为:

bwrap

本次问题的根因是:

  1. Conda 环境中的 bwrap 被替换成了一个异常的 Bash 脚本;
  2. 该脚本只有 132 字节,运行 bwrap --version 时会一直卡住;
  3. 系统自带的 /usr/bin/bwrap 版本为 0.3.0,版本较旧;
  4. Codex优先使用 PATH 中排在前面的 Conda bwrap,导致沙箱启动一直无响应。

通过下面的命令可以查看当前使用的 bwrap

type -a bwrap
command -v bwrap
file "$(command -v bwrap)"

异常情况下可能显示:

bwrap is /home/用户名/anaconda3/bin/bwrap
bwrap is /usr/bin/bwrap

并且:

/home/用户名/anaconda3/bin/bwrap: a /usr/bin/env bash script

正常的 bubblewrap 应该是 ELF 二进制文件,而不是 Bash 脚本。


三、解决思路

正确的解决方案是:

  1. 使用独立 Conda 环境安装新版 bubblewrap
  2. 使用全新的 Conda 包缓存,避免继续读取损坏的缓存;
  3. 使用 --copy,避免 Conda 硬链接再次污染软件包缓存;
  4. 为 Codex建立独立的 bwrap 命令路径;
  5. 将该路径放到 PATH 最前面;
  6. 验证 Codex 沙箱是否恢复正常。

以下操作不需要 sudo 权限。


四、备份异常的 Conda bwrap

先检查当前 Conda 中的 bwrap

ls -lh "$HOME/anaconda3/bin/bwrap"
file "$HOME/anaconda3/bin/bwrap"

如果它是异常脚本,先进行备份:

if [ -e "$HOME/anaconda3/bin/bwrap" ]; then
    mv "$HOME/anaconda3/bin/bwrap" \
       "$HOME/anaconda3/bin/bwrap.broken.$(date +%Y%m%d_%H%M%S)"
fi

hash -r

不要直接修改或覆盖 Conda 包目录中的文件。


五、清理旧的独立环境和损坏缓存

删除之前可能创建的不完整环境:

conda env remove \
  -p "$HOME/.local/opt/codex-bwrap" \
  -y 2>/dev/null || true

rm -rf "$HOME/.local/opt/codex-bwrap"

删除原 Conda 缓存中损坏的 bubblewrap 包:

rm -rf \
  "$HOME/anaconda3/pkgs/bubblewrap-0.11.2-h424e585_1"

rm -f \
  "$HOME/anaconda3/pkgs/bubblewrap-0.11.2-h424e585_1.conda" \
  "$HOME/anaconda3/pkgs/bubblewrap-0.11.2-h424e585_1.tar.bz2"

检查是否清理干净:

find "$HOME/anaconda3/pkgs" \
  -maxdepth 1 \
  -name 'bubblewrap-0.11.2-h424e585_1*' \
  -print

没有输出表示对应缓存已经删除。


六、使用全新缓存安装 bubblewrap 0.11.2

创建一个独立的软件包缓存目录:

rm -rf "$HOME/.cache/conda-codex-pkgs"
mkdir -p "$HOME/.cache/conda-codex-pkgs"

使用该缓存创建专门供 Codex 使用的 bubblewrap 环境:

CONDA_PKGS_DIRS="$HOME/.cache/conda-codex-pkgs" \
conda create \
  -y \
  --copy \
  --override-channels \
  -p "$HOME/.local/opt/codex-bwrap" \
  -c conda-forge \
  bubblewrap=0.11.2

参数说明:

CONDA_PKGS_DIRS

指定一个全新的软件包缓存目录,防止继续使用原来损坏的 Conda 缓存。

--copy

要求 Conda 复制文件,而不是使用硬链接,避免修改环境文件时污染缓存中的原始文件。

--override-channels

只使用本次指定的 conda-forge 通道。

-p

将 bubblewrap 安装到独立目录,不污染 Conda base 环境。


七、验证新版 bubblewrap

设置变量:

BWRAP_NEW="$HOME/.local/opt/codex-bwrap/bin/bwrap"

检查文件:

echo "路径:$BWRAP_NEW"

ls -lh "$BWRAP_NEW"

stat -c '大小:%s bytes' "$BWRAP_NEW"

file "$BWRAP_NEW"

ldd "$BWRAP_NEW"

正常结果应满足:

大小约为 83136 bytes
ELF 64-bit LSB shared object

不能再显示:

132 bytes
a /usr/bin/env bash script

检查版本:

/usr/bin/timeout -k 1 5 \
  "$BWRAP_NEW" --version

echo "version_exit=$?"

正常输出:

bubblewrap 0.11.2
version_exit=0

八、测试 bubblewrap 沙箱

直接使用新安装的 bubblewrap 执行一个只读命令:

/usr/bin/timeout -k 2 10 \
  "$BWRAP_NEW" \
  --ro-bind / / \
  --proc /proc \
  --dev /dev \
  /bin/pwd

echo "bwrap_test_exit=$?"

正常情况下,会输出当前工作目录:

/home/用户名/work/codex_test

并返回:

bwrap_test_exit=0

这表示:

  • bubblewrap 二进制文件正常;
  • 当前用户可以创建所需命名空间;
  • Linux 服务器内核支持 bubblewrap 沙箱;
  • 不需要管理员修改 user namespace 参数。

九、为 Codex创建专用 bwrap 路径

创建一个专门放置 Codex 沙箱命令的目录:

mkdir -p "$HOME/.local/codex-sandbox-bin"

创建软链接:

ln -sfn \
  "$HOME/.local/opt/codex-bwrap/bin/bwrap" \
  "$HOME/.local/codex-sandbox-bin/bwrap"

将该目录放到当前终端 PATH 最前面:

export PATH="$HOME/.local/codex-sandbox-bin:$HOME/.local/bin:$PATH"
hash -r

验证 Codex实际会找到哪个 bwrap

command -v bwrap
readlink -f "$(command -v bwrap)"
bwrap --version

正确结果类似:

/home/用户名/.local/codex-sandbox-bin/bwrap
/home/用户名/.local/opt/codex-bwrap/bin/bwrap
bubblewrap 0.11.2

十、测试 Codex 沙箱

注意,当前版本的测试命令应使用:

codex sandbox -- 命令

不要在 sandbox 后面额外添加 linux

测试当前目录:

/usr/bin/timeout -k 2 20 \
  codex sandbox -- /bin/pwd

echo "codex_sandbox_exit=$?"

正常情况下会输出当前目录,并返回:

codex_sandbox_exit=0

测试读取项目目录:

/usr/bin/timeout -k 2 20 \
  codex sandbox -- \
  /bin/ls -la "$HOME/work/codex_test"

echo "codex_ls_exit=$?"

正常情况下会列出目录内容,并返回:

codex_ls_exit=0

如果使用下面这种命令:

codex sandbox linux /bin/pwd

Codex可能会把 linux 当成要执行的程序,从而出现:

Failed to execvp linux: Permission denied

因此应使用:

codex sandbox -- /bin/pwd

十一、永久配置 PATH

确认新版 bubblewrap 和 Codex 沙箱均正常后,将路径配置写入 ~/.bashrc

cat >> "$HOME/.bashrc" <<'EOF'

# Codex Linux sandbox: use bubblewrap 0.11.2
export PATH="$HOME/.local/codex-sandbox-bin:$HOME/.local/bin:$PATH"
EOF

建议将该配置放在 ~/.bashrc 中 Conda 初始化代码之后,确保不会再次被 Conda 的 PATH 覆盖。

重新加载配置:

source "$HOME/.bashrc"
hash -r

最终验证:

command -v bwrap
readlink -f "$(command -v bwrap)"
bwrap --version

然后测试 Codex 沙箱:

timeout 20 codex sandbox -- /bin/pwd
echo "sandbox_exit=$?"

如果返回:

sandbox_exit=0

说明配置已经永久生效。


十二、重新启动 Codex

进入项目目录:

cd "$HOME/work/codex_test"

正常启动 Codex:

codex \
  --sandbox workspace-write \
  --ask-for-approval on-request

进入 Codex 后,可以让它执行:

执行 pwd 和 ls -la,只读取当前项目内容,不要修改文件。

此时 Codex应该能够正常:

  • 执行 pwd
  • 执行 ls
  • 读取项目文件;
  • 编辑工作区文件;
  • 验证修改结果。

十三、一键检查命令

后续遇到类似问题时,可以先运行下面的检查脚本:

echo "========== Codex =========="
command -v codex
codex --version

echo
echo "========== bwrap =========="
type -a bwrap
command -v bwrap
readlink -f "$(command -v bwrap)"
file "$(command -v bwrap)"
bwrap --version

echo
echo "========== bubblewrap test =========="
timeout 10 bwrap \
  --ro-bind / / \
  --proc /proc \
  --dev /dev \
  /bin/pwd

echo "bwrap_exit=$?"

echo
echo "========== Codex sandbox test =========="
timeout 20 codex sandbox -- /bin/pwd

echo "codex_sandbox_exit=$?"

正常情况下,最后两个退出码都应为:

0

十四、完整安装命令汇总

下面是精简后的完整正确流程:

# 1. 备份异常的 Conda bwrap
if [ -e "$HOME/anaconda3/bin/bwrap" ]; then
    mv "$HOME/anaconda3/bin/bwrap" \
       "$HOME/anaconda3/bin/bwrap.broken.$(date +%Y%m%d_%H%M%S)"
fi

hash -r

# 2. 删除旧环境
conda env remove \
  -p "$HOME/.local/opt/codex-bwrap" \
  -y 2>/dev/null || true

rm -rf "$HOME/.local/opt/codex-bwrap"

# 3. 创建全新 Conda 缓存
rm -rf "$HOME/.cache/conda-codex-pkgs"
mkdir -p "$HOME/.cache/conda-codex-pkgs"

# 4. 安装 bubblewrap 0.11.2
CONDA_PKGS_DIRS="$HOME/.cache/conda-codex-pkgs" \
conda create \
  -y \
  --copy \
  --override-channels \
  -p "$HOME/.local/opt/codex-bwrap" \
  -c conda-forge \
  bubblewrap=0.11.2

# 5. 验证 bubblewrap
BWRAP_NEW="$HOME/.local/opt/codex-bwrap/bin/bwrap"

file "$BWRAP_NEW"
"$BWRAP_NEW" --version

timeout 10 "$BWRAP_NEW" \
  --ro-bind / / \
  --proc /proc \
  --dev /dev \
  /bin/pwd

# 6. 创建 Codex 专用软链接
mkdir -p "$HOME/.local/codex-sandbox-bin"

ln -sfn \
  "$BWRAP_NEW" \
  "$HOME/.local/codex-sandbox-bin/bwrap"

# 7. 设置 PATH
export PATH="$HOME/.local/codex-sandbox-bin:$HOME/.local/bin:$PATH"
hash -r

# 8. 检查实际版本
command -v bwrap
readlink -f "$(command -v bwrap)"
bwrap --version

# 9. 测试 Codex 沙箱
timeout 20 codex sandbox -- /bin/pwd
echo "sandbox_exit=$?"

# 10. 永久写入 bashrc
grep -qxF \
  'export PATH="$HOME/.local/codex-sandbox-bin:$HOME/.local/bin:$PATH"' \
  "$HOME/.bashrc" || \
echo 'export PATH="$HOME/.local/codex-sandbox-bin:$HOME/.local/bin:$PATH"' \
  >> "$HOME/.bashrc"

source "$HOME/.bashrc"
hash -r

十五、总结

Codex能够启动和登录,但无法执行 pwdls,通常不是 Codex主程序安装失败,而是 Linux 本地沙箱中的 bubblewrap 异常。

问题的关键点是:

Conda 中的 bwrap 是损坏的 132 字节 Bash 脚本

正确处理方式不是反复重装 Codex,而是:

使用独立 Conda 环境安装真正的 bubblewrap 0.11.2
使用全新的 Conda 缓存
使用 --copy 避免硬链接污染
将新版 bwrap 放到 PATH 最前面
使用 codex sandbox -- /bin/pwd 验证

完成配置后,Codex即可正常执行本地命令、读取代码、修改文件并验证运行结果。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐