You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Elixir结合pdftk合并PDF时遇文件找不到错误求助

问题解决:Elixir调用pdftk合并PDF时文件找不到错误

核心问题

你的代码中错误地将多个输入文件路径拼接成单个字符串传递给System.cmd,导致pdftk把这个拼接后的字符串当作一个完整的文件名,自然找不到对应的文件。终端直接执行时shell会自动拆分空格分隔的参数,但System.cmd不会做这件事——它要求每个命令参数都是列表中的独立元素。

另外,command_exists?/1函数的实现过于僵化,硬匹配/usr/bin/路径,会导致在pdftk安装在其他路径(比如/usr/local/bin)时误判未安装。

修正后的代码

defmodule PdfMerger.MergePdfs do
  def method(input_files, output_file) do
    if pdftk_installed?() do
      merge_pdfs(input_files, output_file)
    else
      IO.puts("Error: pdftk is not installed.")
    end
  end

  defp command_exists?(command) do
    # 只检查命令执行状态码是否为0,不硬匹配路径
    {_output, status} = System.cmd("which", [command])
    status == 0
  end

  defp pdftk_installed? do
    command_exists?("pdftk")
  end

  defp merge_pdfs(input_files, output_file) do
    # 对每个输入文件路径做路径展开,处理相对路径或带特殊字符的路径
    expanded_inputs = Enum.map(input_files, &Path.expand/1)
    expanded_output = Path.expand(output_file)

    files_exist? = Enum.all?(expanded_inputs, &File.exists?/1)

    if files_exist? do
      # 关键修正:将输入文件列表直接作为参数的一部分,不拼接字符串
      {output, status} =
        System.cmd("pdftk", expanded_inputs ++ ["cat", "output", expanded_output])

      case status do
        0 ->
          IO.puts("PDFs merged successfully.")

        _ ->
          IO.puts("Error: PDF merging failed.")
          IO.puts("pdftk output: #{output}") # 增加错误输出,方便排查
      end
    else
      missing_files = Enum.filter(expanded_inputs, &(not File.exists?(&1)))
      IO.puts("Error: Input files do not exist: #{Enum.join(missing_files, ", ")}")
    end
  end
end

关键修改点说明

  1. 参数传递修正:
    原代码中["#{input_files_string}", "cat", "output", "#{output_file}"]会把所有输入文件当作一个参数,改为expanded_inputs ++ ["cat", "output", expanded_output]后,每个文件路径都是独立的命令参数,和终端执行的逻辑一致。

  2. 命令存在性检查优化:
    去掉硬编码的/usr/bin/路径,只通过which命令的退出状态码判断命令是否存在,适配不同系统的安装路径。

  3. 额外优化:

    • 对所有输入输出路径执行Path.expand/1,确保处理相对路径或包含特殊字符的路径;
    • 错误时输出缺失的具体文件名,以及pdftk的原始输出,方便后续排查问题。

验证方法

修改后调用函数时,直接传入输入文件列表(比如["file1.pdf", "file2.pdf"]),pdftk会正确识别每个文件路径,完成合并操作。

内容的提问来源于stack exchange,提问作者SANONICHAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 18:56:06