【问题标题】:Running a system command (pdflatex) within my Rails Controller在我的 Rails 控制器中运行系统命令 (pdflatex)
【发布时间】:2012-03-24 15:18:24
【问题描述】:

所以我有一个 Rails 应用程序,在用户提交后,它应该根据用户输入生成某种 .tex 文件,将其编译成 pdf,然后交付 pdf。通过消除过程,我非常肯定除了一条线外一切正常;调用 pdflatex 的那个。

以下是重要的 sn-p 代码: (如果重要,它位于生成操作下的 Questions 控制器中,该操作在表单发送相关信息后调用。虽然这可能不是最好的方法,但我很确定它不是错误的原因)

texHeader = 'app\assets\tex\QuestionsFront.txt' 
texOut = 'app\assets\tex\Questions.tex'

#copy latex header to new file
FileUtils.cp(texHeader, texOut)

File.open(texOut, 'a+') do |fout|
      fout.write("\n")
         # a loop writes some more code to fout (its quite lengthy)
      fout.write("\\end{enumerate}\n")
      fout.write("\\end{document}")
      #The problem line:
      puts `pdflatex app/assets/tex/Questions.tex --output-directory=app/assets/tex`
    end

    filename = 'Questions.pdf'
    filelocation = "app\\assets\\tex\\" + filename

    File.open(filelocation, 'r') do |file|
      send_file file, :filename => filename, :type => "application/pdf", :disposition => "attachment"
    end
end

这是我的推理:它正确地生成 .tex 文件,并且给定一个预先创建的 Questions.pdf 文件,它可以很好地发送它。当 puts 中的命令被复制到终端时,它会顺利运行(文件以 \nonstopmode 开头,所以不用担心小错误)。但是由于某种原因,当我运行上面的脚本时,甚至没有创建一个错误的日志文件。

我忽略了什么?有任何想法吗?有什么方法可以查看 puts 行正在创建什么输出?

提前非常感谢!

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 io pdflatex


    【解决方案1】:

    反引号(和%x{})提供与双引号字符串相同的解析上下文。这意味着通常的反斜杠转义序列在反引号内解释;特别是,\t 是一个选项卡,因此:

    puts `pdflatex app\assets\tex\Questions.tex --output-directory=app\assets\tex`
    

    最终会出现两个标签,这会破坏一切。您可以开始转义反斜杠(我认为您需要两个或三个反斜杠才能将一个反斜杠放到 shell 中)或切换到普通斜杠(Windows 通常在路径中接受):

    puts `pdflatex app/assets/tex/Questions.tex --output-directory=app/assets/tex`
    

    或者,您可以切换到open3 以避免转义和引用问题,并获得更好的错误处理能力。

    【讨论】:

    • 感谢您的反馈。我总是混淆我的斜线。我更改了代码行,但仍然一无所获。没有日志文件,没有输出。我相应地更新了我的问题。
    • @ngmiceli:pdflatex 是否会在标准输出上打印任何有用的信息,还是会将其全部写入--output-directory
    • 它将大量内容打印到标准输出,但通常相同的 exact 内容通常也会打印到日志文件中。我承认,我不太了解脚本是否有计划的情况,在这种情况下它可以打印到标准输出但不创建日志文件。我只是不明白将命令复制粘贴到终端时会发生这种情况。
    • 某些程序在不与终端通信时表现不同,因此pdflatex 在不与终端通信时可能不会向标准输出打印任何内容。
    【解决方案2】:

    想出了我自己的问题。这个错误非常有趣。你会看到我在打电话

     puts `pdflatex app/assets/tex/Questions.tex --output-directory=app/assets/tex`
    

    在区块内

    File.open(texOut, 'a+') do |fout|
    

    前几行

    texOut = 'app\assets\tex\Questions.tex'
    

    基本上,我试图让乳胶在文件仍然打开时编译文档只要我在 File.open 块中,该文件已打开,并在块结束时自动关闭。 将代码行剪切并粘贴到块末尾的下方,使它像我想要的那样工作。但是,为了清楚起见和其他人遇到此问题的罕见情况,实际上最好打开一个单独的系统外壳,导航到乳胶文档所在的目录并在那里进行编译。因此,我更新后的代码如下所示:

      fout.write("\\end{document}")
    end
    
    system 'runlatex.bat'
    

    该批处理文件如下:

    cd app/assets/tex
    pdflatex Questions.tex
    

    这样可以找到 tex 目录中的任何其他文件,在那里创建日志文件等。

    为什么我从来没有得到日志文件? pdflatex 从未执行过 - 操作系统在它运行之前以权限错误停止它。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-15
      • 2012-06-21
      • 2019-03-05
      • 2012-01-13
      • 1970-01-01
      • 2014-02-09
      • 1970-01-01
      • 2014-07-18
      相关资源
      最近更新 更多