【问题标题】:Scala System Process and whitespaceScala 系统进程和空白
【发布时间】:2012-02-20 18:56:00
【问题描述】:

我正在尝试发出系统命令来运行 FreeSurfer 的 mri_convert。您不需要真正了解 mri_convert 是什么,就像您必须了解流程如何从 scala 转移到系统一样。该代码在大多数情况下都有效,但是当我尝试发送带有空格的文件路径时,它会中断(即使在我用\ 替换了空格之后)。我将在下面发布我的代码,然后是使用没有目录的文件在其路径中包含空格的输出,然后是从带有空格的目录的文件路径的输出。

def executeAll(): Boolean = {
  while (dataBuf.length != 0) {
    val dir = directory + "subjects/" + dataBuf.first.subjectID + "/mri/orig"
    val expr = """\s+""".r  
    val path = expr.replaceAllIn((dataBuf.first.path), """\\ """)
    val folder = new File(dir)
    val execute = freesurfer + """bin/mri_convert -it dicom -ot mgz -ii """ + path + """ -oi """ + dir + """/001.mgz"""
    if (folder.mkdirs()) {
      val command = Process(execute, folder, ("FREESURFER_HOME", freesurfer))
      val exitCode = command.!
      println(command.toString())
    }
    dataBuf.remove(dataBuf.indexOf(dataBuf.first))
  }
  println("DONE")
  dataListView.listData = dataBuf
  true
} 

输出不带空格的目录:

val path = /Applications/freesurfer/bin/mri_convert -it dicom -ot mgz -ii /Volumes/N/0110547/2008-05-24/data/BIRNSequence_4/IM-0003-0001.dcm -oi /Users/michael/Documents/subjects/dadasd/mri/orig/001.mgz 

[/Applications/freesurfer/bin/mri_convert, -it, dicom, -ot, mgz, -ii, /Volumes/N/0110547/2008-05-24/data/BIRNSequence_4/IM-0003-0001.dcm, -oi, /Users/michael/Documents/subjects/dadasd/mri/orig/001.mgz]

带空格的输出目录:

val path = /Applications/freesurfer/bin/mri_convert -it dicom -ot mgz -ii /Volumes/N/0110547/2005-07-31/this\ is\ the\ data/AXBIRN_4/IM-0004-0001.dcm -oi /Users/michael/Documents/subjects/adsfsdf/mri/orig/001.mgz 

mri_convert: extra arguments ("the\" and following)
 [/Applications/freesurfer/bin/mri_convert, -it, dicom, -ot, mgz, -ii, /Volumes/N/0110547/2005-07-31/this\, is\, the\, data/AXBIRN_4/IM-0004-0001.dcm, -oi, /Users/michael/Documents/subjects/adsfsdf/mri/orig/001.mgz]

我认为这与传递给系统的参数在目录中用括号中的空格中断路径有关。因此,我相信我的流程是如何创建的,这很有趣。更重要的是,在每种情况下,如果我将路径的 val 剪切并粘贴到终端中,mri_convert 程序都会按预期执行。

提前致谢,如果需要更多详细信息,请告诉我。

【问题讨论】:

    标签: scala process system


    【解决方案1】:

    我建议从一系列参数创建您的流程,而不是尝试在下游获取某些内容以正确解析它们。为此,您使用 stringSeqToProcess 隐式方法。

    我创建了一个 shell 脚本,它在单独的行上打印出它的每个参数。为了更好地衡量,我在脚本的路径中放置了一个空格。然后我能够从 Scala 执行它:

    import scala.sys.process._
    Seq("/home/lwickland/sp ace/script.sh", "a1", "/path/with a/sp ace", "c")!
    

    shell 脚本将包含空格的参数视为单个项目。

    Arg: a1
    Arg: /path/with a/sp ace
    Arg: c
    

    我建议尝试将您的代码修改为:

    def executeAll(): Boolean = {
      while (dataBuf.length != 0) {
        val dir = directory + "subjects/" + dataBuf.first.subjectID + "/mri/orig"
        val folder = new File(dir)
        val execute = Seq("sh", freesurfer + "bin/mri_convert", "-it", "dicom", "-ot", "mgz", "-ii", path, "-oi", dir +"/001.mgz")
        if (folder.mkdirs()) {
          val command = Process(execute, folder, ("FREESURFER_HOME", freesurfer))
          val exitCode = command.!
          println(command.toString())
        }
        dataBuf.remove(dataBuf.indexOf(dataBuf.first))
      }
      println("DONE")
      dataListView.listData = dataBuf
      true
    } 
    

    如果这不起作用,请告诉我。

    【讨论】:

    • 您愿意发布您用来尝试这种方法的代码吗?
    • 通过在 Seq() 中添加“sh”作为第一个参数,我能够运行未标记为可执行的 shell 脚本。 Seq("sh", "/home/lwickland/sp ace/script.sh", "a1", "/path/with a/sp ace", "c")! 当然,要让它起作用,你必须在你的路径中“sh”。如果不是,则必须在其中放置“/bin/sh”之类的内容。
    • 这是新问题:带有反斜杠(用于空格)的文件路径在作为参数发送到 .sh 文件时被分解为多个参数。传递的顺序如下:[/Users/michael/Desktop/shell.sh, /Users/michael/Documents/subjects/34242/mri/orig/001.mgz, /Volumes/NOWAK/0110547/2005-07- 31/this\,is\,the\,data/AXBIRN_4/IM-0004-0001.dcm]
    • 此时,我不确定您正在尝试什么。您是否有类似我在上面的答案中附加的内容?具体来说,我认为您不需要进行任何反斜杠替换。另外,您是否使用val execute = Seq("sh", freesurfer + "bin/mri_convert", "-it", "dicom", "-ot", "mgz", "-ii", path, "-oi", dir +"/001.mgz") 之类的第一个参数创建流程?
    • 莱夫,你是对的。如果您使用您指定的方法,您实际上不需要进行任何反斜杠替换。感谢您的帮助,它现在正在工作!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    相关资源
    最近更新 更多