2012-01-27 50 views
0

我试图发出系统命令来运行FreeSurfer的mri_convert。您并不需要了解mri_convert是什么,就像您必须了解如何将流程从scala转移到系统一样。代码大部分工作,但是当我尝试发送文件路径时,它会打破空格(即使我用\替换空格后)。我将在下面发布我的代码,然后使用没有包含其路径中的空间的目录的文件的输出,然后从具有空间的目录的文件路径中输出。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/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 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剪切并粘贴到终端,则mri_convert程序按预期执行。

在此先感谢,并请让我知道是否需要更多细节。

回答

6

我建议从一系列参数中创建你的过程,而不是尝试去下游某些东西来正确解析它们。要做到这一点,请使用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 
} 

请让我知道,如果不工作。

+0

脚本是否标记为可执行文件? – 2012-01-27 20:58:41

+0

你愿意发布你正在使用的代码来尝试这种方法吗? – 2012-01-27 20:59:06

+0

我能够通过在Seq()中添加“sh”作为第一个参数来运行未标记为可执行的shell脚本。 'Seq(“sh”,“/ home/lwickland/sp ace/script.sh”,“a1”,“/ path/with a sp ace”,“c”)!'当然为了工作,你你必须在你的道路上“sh”。如果不是,那么你必须在其中放入类似“/ bin/sh”的内容。 – 2012-01-27 21:00:54