Code 与 Execute Command 节点:原理、对比与最佳实践

本章对比 n8n 中两类可执行单元:在运行时内执行用户代码的 Code 节点(JavaScript / Python(Beta))与在宿主或容器内运行命令的 Execute Command 节点。目标是帮你快速选择合适节点、规避常见坑并给出实用示例。

要点:

  • 以数据转换、小型逻辑与低延迟为主,优先用 Code 节点(JavaScript 优先)。
  • 需要调用系统工具、处理大文件或用到本地依赖时,用 Execute Command 节点并在部署时预装/挂载所需资源。
  • Code 的 Python 是基于 Pyodide 的实验性实现,包有限且启动/运行开销较大;需要完整 Python 能力请使用 Execute Command 调用宿主 Python 环境。

概要与实现差异

下面按运行模型说明两节点的关键差异,便于决策。

Code 节点原理与适用场景

Code 节点是在 n8n 进程内部启动一个受控的运行环境来执行自定义代码。默认情况下其语言为 JavaScript。n8n 1.0 版起增加了 Python 支持,但这并非通过系统的 Python 可执行文件实现,而是通过 将 CPython 编译为 WebAssembly。这意味着它只能使用随 Pyodide 发布的部分 Python 库,并且首次调用时 n8n 会自动下载依赖。由于 Python 需要额外的编译步骤,性能明显慢于 JavaScript。

Code 节点支持两种执行模式:

  • Run Once for All Items:默认模式,工作流运行时,该节点中的代码只执行一次,无论输入有多少条数据。
  • Run Once for Each Item:当你需要对每条输入数据单独运行代码时,可以选择该模式。

在 JavaScript 模式下,Code 节点支持返回 Promise,并可使用 console.log 输出调试信息。n8n 提供了 $node$json 等内置变量和方法,用于访问前置节点的数据或执行环境。

可用库与模块限制

为了安全起见,Code 节点默认禁止 require() 任意模块,并限制访问 Node.js 内置模块、文件系统和网络。例如,n8n 明确指出在 Code 节点中不能访问本地文件系统或发起 HTTP 请求,需要改用专用的 Read/Write File 或 HTTP Request 节点。如果自建部署希望在 Code 节点中使用额外的内置或第三方 npm 模块,可以通过设置环境变量开启:

  • NODE_FUNCTION_ALLOW_BUILTIN:允许加载特定内置模块,例如 cryptofs

  • NODE_FUNCTION_ALLOW_EXTERNAL:允许从 n8n 容器的 node_modules 中加载指定的外部模块。

  • 例如在部署的 Docker 容器中设置:

# 允许使用 crypto 和 fs 两个内置模块
export NODE_FUNCTION_ALLOW_BUILTIN=crypto,fs
# 允许加载 moment 和 lodash 两个外部模块
export NODE_FUNCTION_ALLOW_EXTERNAL=moment,lodash

n8n Cloud 环境无法安装外部模块,官方仅提供 cryptomoment 两个可用模块。

Code 节点的使用场景

Code 节点适合在工作流内部快速编写逻辑,尤其是结构化数据转换和轻量算法:

  • 数据转换和清洗:解析 JSON、重构字段、合并数组等操作,通常只需几行 JavaScript,就可以灵活地处理 $items
  • 复杂条件逻辑:当 If/Set 等节点组合无法满足需求时,可以在 Code 节点内使用完整的编程语言表达复杂条件。
  • 调用受限的内置函数:例如利用 crypto 进行哈希或签名,用 moment 格式化时间。
  • 自定义算法与验证:对输入数据做校验、计算统计结果或生成随机值。

对于短耗时任务建议优先使用 Code 节点,因为其运行在 n8n 的进程内,延迟和开销较低。

技术限制与注意事项

Code 节点存在以下限制:

  • 沙箱环境:Code 节点内部运行的代码受限于 vm2 沙箱,无法访问宿主机的文件系统和网络。使用时应避免尝试读取磁盘或调用第三方 API,而应该通过 n8n 的专用节点来实现这些功能。
  • 模块限制:外部模块需通过环境变量显式允许;在 n8n Cloud 中无法安装自定义模块,只能使用官方提供的 cryptomoment
  • 性能和阻塞问题:Code 节点的运行与 n8n 的主进程共享事件循环。长时间的同步计算可能阻塞整个服务,导致其他节点等待。因此,编写代码时应避免使用耗时的循环或大型计算,可通过拆分任务或转移到 Execute Command 节点处理。
  • Python 的限制:由于使用 Pyodide,Python 代码执行速度较慢,且只能使用有限的包;不适合重度数据科学或机器学习任务。
  • 数据项与链接:如果输入和输出的数据项数量不一致,需要在代码中处理 Item linking,否则下游节点可能接收到不匹配的数据。

Execute Command 节点原理与适用场景

Execute Command 节点允许在运行 n8n 的宿主机上执行任何 Shell 命令。命令在宿主机的默认 Shell 中运行,例如 Windows 上的 cmd 或 macOS 的 zsh。如果 n8n 以 Docker 部署,则命令运行在 n8n 容器中,而不是宿主操作系统。需要注意:此节点在 n8n Cloud 不可用

节点有两个常用参数:

  • Execute Once:控制是为输入的所有数据执行一次命令,还是每条数据执行一次。
  • Command:编写要执行的 Shell 命令,可以在同一个节点中通过 && 串联多条命令,或换行写在不同行。如果需要运行 curl 等工具,官方建议构建自定义 Docker 镜像并安装缺少的软件包。

Execute Command 节点的使用场景

Execute Command 节点非常适合需要调用系统工具或已经存在的脚本的场景:

  • 运行本地脚本或程序:执行 Bash/Python/PowerShell 脚本,或调用如 ffmpegimagemagickpandoc 等命令行工具进行媒体转换、文档处理、批量操作等。
  • 利用现有 CLI 工具:例如通过 sshscpaws cli 与服务器或云服务交互,通过 git 管理代码仓库。
  • 大规模数据或二进制处理:在 Code 节点难以承载的重度计算,可以借助外部程序在子进程中完成,避免阻塞 n8n 主进程。
  • 与宿主环境交互:如访问数据库命令行工具、备份文件、更新系统等。

Execute Command 节点的限制

Execute Command 节点存在以下限制:

  • 部署方式影响环境:在本地或裸机安装的 n8n 中,Execute Command 节点直接访问宿主机的环境;在 Docker 部署中,它只能访问容器内的文件系统和工具。因此需要在镜像中安装所需命令,或者通过挂载卷提供脚本和数据。
  • 不可用于 n8n Cloud:出于安全考虑,n8n Cloud 禁用了 Execute Command 节点。
  • 命令注入和安全:当命令包含来自用户输入的变量时,应避免简单拼接字符串。推荐使用严格的输入校验和参数化方式,或在脚本内部解析环境变量来读取参数。
  • 权限:执行的命令以运行 n8n 的系统用户身份运行。确保 n8n 用户对要访问的文件和程序具有相应权限。尤其在生产环境要限制 Execute Command 的权限,以防止执行危险命令。
  • 资源限制:子进程可能消耗大量 CPU 或内存,应在部署层面使用 cgroups/Kubernetes 等方式限制容器资源,并在 Execute Command 节点设置合理的超时时间。

在 n8n 中调用本地环境的实践

很多用户希望在 n8n 中调用本地的 Python 脚本或其他工具。下面是通过 Execute Command 节点在不同环境下运行 Python 脚本的建议:

自建 n8n + 本地虚拟环境:假设你希望在虚拟环境中运行脚本,可以在命令中先激活 venv,然后运行脚本。例如社区建议:

  • Linux/MacOS:source /path/to/venv/bin/activate && python /path/to/script.py
  • Windows CMD:\path\to\venv\Scripts\activate.bat && python \path\to\script.py
  • Windows PowerShell:& \path\to\venv\Scripts\Activate.ps1; python \path\to\script.py。 也可以直接指定虚拟环境中的 Python 可执行文件,如 /path/to/venv/bin/python /path/to/script.py

Docker 部署的 n8n:由于命令在容器内部执行,必须确保容器内安装了 pythonffmpeg 等工具。可以通过构建自定义镜像,在 Dockerfile 中安装所需软件包,并将脚本或虚拟环境挂载进容器。如果虚拟环境位于宿主机,可在容器运行时使用 -v /host/venv:/data/venv 挂载,并在命令中激活该环境。提到,如在 Docker 中需创建包含虚拟环境和依赖的自定义镜像或挂载卷。

权限管理:无论哪种方式,确保运行 n8n 的用户有权访问虚拟环境目录、脚本文件以及任何读写目录。

常见坑与规避建议

下面是关于 Code 节点的常见问题及其规避建议:

常见问题原因与影响规避策略
无法访问文件系统或网络Code 节点被限制访问宿主机文件系统和 HTTP 网络使用 Read/Write File、HTTP Request 等专用节点读取文件或调用 API;不要尝试在代码中读取磁盘或执行网络请求
第三方模块加载失败默认安全配置禁止导入外部模块,n8n Cloud 仅提供 cryptomoment自建部署时通过环境变量 NODE_FUNCTION_ALLOW_BUILTINNODE_FUNCTION_ALLOW_EXTERNAL 启用所需模块
执行阻塞导致 n8n 卡死在 Code 节点中执行计算密集或长时间循环会阻塞 n8n 主进程将重度计算任务拆分到 Execute Command 节点或外部服务;在代码中使用异步操作和 Promise,避免阻塞
Python 运行缓慢或缺少库Python 通过 Pyodide 运行,速度慢且只包含少量库仅在简单逻辑场景使用 Python;需要完整 Python 功能时改用 Execute Command 节点运行系统 Python
数据项不匹配输入/输出 items 数量不一致,但未处理 Item linking理解 n8n 的数据结构;在代码中使用正确的循环与输出格式,对应每个输入 item 生成输出

下面是关于 Execute Command 节点的常见问题及其规避建议:

常见问题原因与影响规避策略
命令在 n8n Cloud 不可用出于安全考虑,Execute Command 节点在云端被禁用如果需要运行本地脚本,必须自建部署 n8n
命令执行失败缺少所需程序或路径不正确;在 Docker 容器内没有安装工具在宿主系统或自定义镜像中预装必要的软件;使用绝对路径;通过 && 或换行组合多条命令确保环境正确
安全风险将用户输入拼接到 Shell 命令,可能造成命令注入或意外执行使用参数化脚本或在命令中通过环境变量传递参数;对输入进行严格的校验和转义
资源争用和长时间运行子进程执行耗时任务,可能占用过多 CPU/IO,影响 n8n 性能为 Execute Command 节点设置超时;在容器层面限制资源;将复杂任务拆分为后台脚本并异步调用
宿主与容器环境差异在 Docker 部署下,命令只能访问容器内文件和环境明确安装路径、挂载卷和环境变量;必要时构建自定义镜像并在其中准备运行环境

示例

下面示例旨在展示典型用法,真实场景请将脚本和参数放到受控仓库并进行版本管理。

Code 节点示例

Code 节点 JavaScript 简单字段映射:

return items.map(item => ({
  json: {
    id: item.json.id,
    fullName: `${item.json.firstName} ${item.json.lastName}`,
    timestamp: new Date().toISOString(),
  },
}));

Code 节点 Python(Pyodide)访问与转换:

# _json 是传入的 JsProxy / dict
data = _json
if hasattr(data, 'to_py'):
    data = data.to_py()
result = {'fullName': data.get('firstName','') + ' ' + data.get('lastName','')}
return [{ 'json': result }]

Execute Command 节点示例

Execute Command 节点以环境变量传参的 Python 调用:

脚本 repository/scripts/process_data.py

import os, json
payload = os.environ.get('N8N_PAYLOAD')
data = json.loads(payload)
# 处理逻辑

节点配置示例:

  • Command: python3
  • Arguments: ['/data/scripts/process_data.py']
  • Environment: N8N_PAYLOAD = {{ $json | jsonEncode }}

这样避免将不可信字符串直接注入 shell,并在脚本中做严格校验。

总结与建议

  • 优先使用 Code 节点处理轻量、结构化的数据转换和逻辑。它运行在 n8n 的沙箱中,延迟低并且方便访问 $node 数据。尽量使用 JavaScript 实现,避免在代码中进行长时间阻塞操作。若需要外部模块,自建部署时通过环境变量允许;在云端只能使用官方提供的少数模块。
  • 使用 Execute Command 节点运行外部脚本或系统工具。它适合 CPU/IO 密集型任务、调用已有 CLI 工具或需要访问宿主环境时。请注意安全:验证输入、限制权限、合理设置超时,并在 Docker 环境中提前安装所需工具。由于该节点在 n8n Cloud 不可用,使用此功能时需自建部署。
  • 调用本地 Python 环境的最佳方式是通过 Execute Command 节点激活虚拟环境并运行脚本。在 Docker 环境下,可构建自定义镜像或挂载卷提供依赖。
  • 规范部署与监控:无论使用哪种节点,都建议在容器或主机层面限制资源、监控执行时间,并通过版本控制管理脚本和依赖,使工作流可维护且可复制。

文章导航

独立页面

这是书籍中的独立页面。

书籍首页

评论区