Процесс системы Scala и пробелы - PullRequest
1 голос
/ 27 января 2012

Я пытаюсь выполнить системную команду для запуска mri_convert из FreeSurfer. Вам на самом деле не нужно понимать, что такое mri_convert, так же, как вы должны понимать, как процессы передаются из системы в систему. Код работает по большей части, но когда я пытаюсь отправить путь к файлу с пробелами, он прерывается (даже после того, как я заменяю пробелы на \). Я опубликую свой код ниже, а затем вывод от использования файла без каталога, содержащего пробел в его пути, а затем из пути к файлу с каталогом с пробелом.

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 выполняется, как и ожидалось.

Заранее спасибо, и, пожалуйста, дайте мне знать, если потребуется более подробная информация.

1 Ответ

7 голосов
/ 28 января 2012

Я предлагаю создать ваш процесс из последовательности аргументов, а не пытаться получить что-то нижестоящее для правильного их анализа.Для этого вы используете неявный метод stringSeqToProcess .

Я создал сценарий оболочки, который выводит каждый из его аргументов в отдельной строке.Для хорошей меры я поставил пробел в пути к сценарию.Затем я смог выполнить его из Scala:

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

Сценарий оболочки рассматривал аргумент, содержащий пробелы, как один элемент.

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
} 

Пожалуйста, дайте мне знать, если это не сработает.

...