2012-01-27 25 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