7

以下命令在 pdf 文件上执行 ghostscript。(pdf_file变量包含该pdf的路径)

bbox <- system(paste( "C:/gs/gs8.64/bin/gswin32c.exe -sDEVICE=bbox -dNOPAUSE -dBATCH -f", pdf_file, "2>&1" ), intern=TRUE)

执行后bbox包括以下字符串。

GPL Ghostscript 8.64 (2009-02-03)
Copyright (C) 2009 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
%%BoundingBox: 36 2544 248 2825
%%HiResBoundingBox: 36.395015 2544.659922 247.070032 2824.685914
Error: /undefinedfilename in (2>&1)
Operand stack:

Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push
Dictionary stack:
   --dict:1147/1684(ro)(G)--   --dict:1/20(G)--   --dict:69/200(L)--
Current allocation mode is local
Last OS error: No such file or directory
GPL Ghostscript 8.64: Unrecoverable error, exit code 1

然后对该字符串进行操作,以便隔离 BoundingBox 尺寸 (36 2544 248 2825) 并用于裁剪 pdf 文件。到目前为止一切正常。

但是,当我在任务管理器中安排这个脚本(使用 Rscript.exe 或 Rcmd.exe BATCH),或者当脚本在 R 块中并且我按knit HTML时,bbox 会获取以下缺少 BoundingBox 信息的字符串,并使其不可用:

GPL Ghostscript 8.64 (2009-02-03)
Copyright (C) 2009 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Error: /undefinedfilename in (2>&1)
Operand stack:

Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push
Dictionary stack:
   --dict:1147/1684(ro)(G)--   --dict:1/20(G)--   --dict:69/200(L)--
Current allocation mode is local
Last OS error: No such file or directory

我怎样才能克服这个问题并让脚本自动运行?

(脚本来自该问题的公认答案)

4

3 回答 3

6

2>&1您在命令末尾添加的将发送到 ghostscript 解释器,而不是 shell 。Ghostscript 将其解释为 file,因此出现错误。我使用 procmon 来查看进程创建:

stderr 重定向被 ghostscript 视为文件

要让 shell 解释它,你必须在命令前加上cmd /c,像这样

> bbox <- system(paste("cmd /c C:/Progra~1/gs/gs9.07/bin/gswin64c.exe -sDEVICE=bbox -dNOPAUSE -dBATCH -q -f",pdf_file,"2>&1"), intern=TRUE)
> print (bbox)
[1] "%%BoundingBox: 28 37 584 691"                                  "%%HiResBoundingBox: 28.997999 37.511999 583.991982 690.839979"
于 2013-02-19T04:14:31.780 回答
2

设备的输出将输出到标准输出,错误将输出到标准错误。在终端中,这些显然都被发送到终端并一起显示,在第二种情况下,它们显然不是并且标准输出丢失了。

这并不奇怪,因为您在 (2>&1) 上收到错误消息。这看起来像是将标准输出重定向到一个文件,但有两个问题。首先,您没有为要发送到的输出提供文件名,其次,您没有在命令外壳中运行,因此命令处理器不会执行重定向。

我对 R 一无所知,所以我无法告诉你如何做到这一点,但无论如何你都应该从命令行中删除 '2>&1' 开始。您可能还想考虑使用不到 4 年的 Ghostscript 版本。当前版本是 9.07,刚刚发布。

于 2013-02-14T08:44:26.480 回答
1

试试这个。

使用 环境变量设置输出文件

然后使用 %envvar% 表示法,根据上面的链接将是 %TODAY% ,它将被替换为文件名 friday。-f 不是必需的,但不应该受到伤害。如果要路由输出,请设置第二个环境变量并将其路由 >%outenv%。

这样您就可以进行简单的系统调用(请参阅使用变量而不是固定字符串的链接),

Sys.setenv(envvar= "pdf.file")  
Sys.setenv(outenv= "out.file")
"C:/gs/gs8.64/bin/gswin32c.exe -sDEVICE=bbox -dNOPAUSE -dBATCH %envvar% >%outenv%"
于 2013-02-17T07:04:21.700 回答