codex写入文件底层揭秘一、shell_command.rs

📅 2026/7/11 6:01:47
codex写入文件底层揭秘一、shell_command.rs
前情提要使用codex生成dify工作流的一次记录模型GPT-5.5 High当时我认为直接在powerShell的终端执行写入文件的命令它就会出现乱码于是我就直接执行这个命令了Set-Content-Pathtest.txt-Value你好PowerShell没有设置编码方式直接写入默认为ANSI/GBK的编码模式写入但是它是正常的于是我问他他给我这样的答案意思就是它通过API工具把命令发给window shell经过层层解析将解析之后的内容写入文件。于是继续追问它是这样解释的其中这里的shell表示一个总类别意思就是codex调用了API工具它给了4种验证方式分别是实验 1直接 PowerShell 输入Set-Content -Path “direct.txt” -Value 你好PowerShell Get-Content -Path direct.txt这个大概率正常因为你是直接在 PowerShell 里输入。实验 2PowerShell 调 Python 内联中文python-cfrom pathlib import Path; Path(py-inline.txt).write_text(你好Python, encodingutf-8)如果正常说明你当前终端到 Python 的传参链路没问题。实验 3用 here-string 传中文给 Python from pathlib import Path Path(py-heredoc.txt).write_text(你好HereString, encodingutf-8) |python -如果这里也正常说明你本机 PowerShell 管道传输也没问题。实验 4强制看 Python 收到的真实字符串python-cimport sys; print(repr(你好Python))正常应该输出类似你好Python如果输出?????Python说明中文在进入 Python 前已经坏了。到这里就又多了很多个抽象的概念HereString是什么Shell是什么它和powerShell有什么关联。搞清楚这些概念之后又萌生了一个问题图中的tool call指的是什么于是针对这个问题对codex进行了提问他给我进行了解答解释的非常清楚调用codex提供的工具然后举了一些例子等等。于是继续追问github地址https://github.com/openai/codex并且给了查找指引访问codex的document被拒绝了按照关键词搜索了一轮文件非常繁多还是借助了codex帮我筛查了主要集中在这些文件core/src/tools/handlers/shell/shell_command.rs -core/src/shell.rs -shell-command/src/powershell.rs -core/src/exec.rs -sandboxing/src/manager.rs -tui/src/approval_events.rs看的出是用rust语言编写的我们看一下其中一处shell_command.rs捕捉到一些关键的代码// 导入模块# codex原型shell命令调用参数结构体usecodex_protocol::models::ShellCommandToolCallParams;# codex工具codex_toolsusecodex_tools::ShellCommandBackendConfig;# 创建shell命令工具类usesuper::super::shell_spec::create_shell_command_tool;shellCommandHandler实现类# shellCommandHandler实现类implShellCommandHandler实现类里是一些构造方法之类的其中有一个感觉像是比较关键的方法to_exec_paramspub(super)fnto_exec_params(params:ShellCommandToolCallParams,session:crate::session::session::Session,turn_context:TurnContext,turn_environment:TurnEnvironment,cwd:AbsolutePathBuf,allow_login_shell:bool,)-ResultExecParams,FunctionCallError{// 获取session_shell对象letsession_shellsession.user_shell();// 拿到从session_shell对象中拿到shellletshellturn_environment.shell.as_ref().unwrap_or(session_shell.as_ref());letuse_login_shellSelf::resolve_use_login_shell(params.login,allow_login_shell)?;// 指令letcommandSelf::base_command(shell,params.command,use_login_shell);// env对象letmutenvcreate_env(turn_context.config.permissions.shell_environment_policy,Some(session.thread_id),);letactive_permission_profileturn_context.config.permissions.active_permission_profile();inject_permission_profile_env(mutenv,active_permission_profile.as_ref());// result特定写法执行OK返回成功时的执行结果Ok(ExecParams{command,cwd,expiration:params.timeout_ms.into(),capture_policy:ExecCapturePolicy::ShellTool,env,network:turn_context.network.clone(),network_environment_id:Some(turn_environment.environment_id.clone()),sandbox_permissions:params.sandbox_permissions.unwrap_or_default(),windows_sandbox_level:turn_context.windows_sandbox_level,windows_sandbox_private_desktop:turn_context.config.permissions.windows_sandbox_private_desktop,justification:params.justification.clone(),arg0:None,})}大致理解执行方法将env、command指令等对象当作执行参数进行返回。ToolExecutor实现类# 特质实现类ToolExecutorimplToolExecutorToolInvocationforShellCommandHandler{// tool工具名称fntool_name(self)-ToolName{ToolName::plain(shell_command)}// 创建shell_command_tool工具类fnspec(self)-ToolSpec{create_shell_command_tool(CommandToolOptions{allow_login_shell:self.options.allow_login_shell,exec_permission_approvals_enabled:self.options.exec_permission_approvals_enabled,})}fnsupports_parallel_tool_calls(self)-bool{true}// 执行fnhandle(self,invocation:ToolInvocation)-codex_tools::ToolExecutorFuture_{Box::pin(self.handle_call(invocation))}}捕捉到一个很像的create_shell_command_tool创建shell_command工具方法它在shell_spec.rs里pubfncreate_shell_command_tool(options:CommandToolOptions)-ToolSpec{pubfncreate_shell_command_tool(options:CommandToolOptions)-ToolSpec{// 定义propertiesletmutpropertiesBTreeMap::from([(command.to_string(),JsonSchema::string(Some(Shell script to run in the users default shell..to_string(),)),),(workdir.to_string(),JsonSchema::string(Some(Working directory for the command. Defaults to the turn cwd..to_string(),)),),(timeout_ms.to_string(),JsonSchema::number(Some(Maximum command runtime. Defaults to 10000 ms..to_string(),)),),]);// 如果为allow_login_shell命令则执行ifoptions.allow_login_shell{properties.insert(login.to_string(),JsonSchema::boolean(Some(True runs with login shell semantics; false disables them. Defaults to true..to_string(),)),);}//properties.extend(create_approval_parameters(options.exec_permission_approvals_enabled,));// 如果是windows的指令则执行powershell指令否则执行普通shell指令letdescriptionifcfg!(windows){format!(r#Runs a Powershell command (Windows) and returns its output. Examples of valid command strings: - ls -a (show hidden): Get-ChildItem -Force - recursive find by name: Get-ChildItem -Recurse -Filter *.py - recursive grep: Get-ChildItem -Path C:\\myrepo -Recurse | Select-String -Pattern TODO -CaseSensitive - ps aux | grep python: Get-Process | Where-Object {{ $_.ProcessName -like *python* }} - setting an env var: $env:FOObar; echo $env:FOO - running an inline Python script: \\nprint(Hello, world!)\\n | python - {}#,windows_shell_guidance())}else{r#Runs a shell command and returns its output. - Always set the workdir param when using the shell_command function. Do not use cd unless absolutely necessary.#.to_string()};ToolSpec::Function(ResponsesApiTool{name:shell_command.to_string(),description,strict:false,defer_loading:None,parameters:JsonSchema::object(properties,Some(vec![command.to_string()]),Some(false.into()),),output_schema:None,})}看起来比较关键的就是定义description若为windows则执行powershell指令否则执行普通shell指令。后面还有一个CoreToolRuntime也是ShellCommandHandler的特质实现类。总结一下看起来比较关键的部分1、to_exec_params执行方法返回指令相关参数。2、shellCommandHandlershell指令Handler3、create_shell_command_tool里面有执行powershell相关的语法若为windows则执行powershell指令否则执行普通指令。shell_command.rs大致这些内容第一次解读codex源码欢迎各位进行评论、鼓励、批评指正。附加tips我在原来的4个实验中执行了到第三个实验的时候出现异常图中清晰的展示???HereString说明字符通过HereString管道传输给python的时候就已经断了。