在clojure.java.shell中运行具有冲突名称的特定可执行文件

时间:2013-03-18 06:49:39

标签: shell clojure

我的convert.exe中有两个名为PATH的可执行文件。其中一个来自ImageMagick,另一个来自Windows。

user=> (clojure.java.shell/sh "where" "convert")
{:exit 0, :out "E:\\Program Files\\ImageMagick-6.8.3-Q16\\convert.exe\r\nC:\\Windows\\System32\\convert.exe\r\n", :err ""}

我想在convert.exe内运行ImageMagick的clojure.java.shell/sh。通常,我可以在PowerShell中执行此操作。

PS E:\Users\bt> convert --version
Version: ImageMagick 6.8.3-8 2013-03-04 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2013 ImageMagick Studio LLC
Features: DPC OpenMP
Delegates: bzlib fontconfig freetype jng jp2 jpeg lcms lzma pango png ps tiff x xml zlib

但是,这不适用于clojure.java.shell/sh

user=> (clojure.java.shell/sh "convert" "--version" :dir "E:/Users/bt")
{:exit 4, :out "", :err "Invalid drive specification.\r\n"}

最初,我认为我需要将ImageMagick的路径移到PATH的前面,这样它才能优先于Windows的二进制文件,但这没有任何效果。另外,我把它移到PATH的末尾只是为了踢。这也行不通。

我知道解决此问题的唯一方法是重命名任一可执行文件。但这是不受欢迎的,因为我不希望其他人重命名他们的ImageMagick / Windows二进制文件只是为了使我的代码工作。

如果此信息有用,则在cmd.exe中开始打开一个新的命令shell(不是PowerShell,而是C:\Windows\System32)。我觉得这可能会影响可执行文件的选择,但我不确定。只有从Launchy运行cmd.exe时才会发生这种情况。如果我使用“开始”菜单,它将从我的主目录开始。

有没有办法做到这一点?我觉得我错过了一些明显的东西。

2 个答案:

答案 0 :(得分:1)

您可以尝试为可执行文件提供绝对PATH吗? 等,

user=> (clojure.java.shell/sh "E:\\Program Files\\ImageMagick-6.8.3-Q16\\convert.exe" "--version" :dir "E:/Users/bt")

OR

user=> (clojure.java.shell/sh "E:\\Progra~1\\ImageMagick-6.8.3-Q16\\convert.exe" "--version" :dir "E:/Users/bt")

答案 1 :(得分:1)

我可以重现你的结果。无论原因是什么,它都被Java Runtime.exec隐藏在哪里接收PATH,但是它可能会在前面添加Windows System目录? 如果你想彻底了解它,这是你应该继续调查的地方。

sh中查看对其的调用:

  (let [...
        proc (.exec (Runtime/getRuntime)
          (into-array cmd)
          (as-env-string (:env opts))
          (as-file (:dir opts)))]

但是,如果给出可执行文件的绝对路径,它确实有效。因此,有两种方法可以解决问题:

  • 如果可以安全地假设IM convert.exe是PATH上的第一个,只需执行问题中显示的“where”,从:out返回第一个路径,追加对convert.exe sh并将结果用作{{1}}的程序。
  • 如果您无法假定正确的PATH,请询问用户Image Magick的安装位置并将程序路径存储在某处。将其添加到程序路径中。