Scala 系统进程和空格 [英] Scala System Process and whitespace
问题描述
我正在尝试发出系统命令来运行 FreeSurfer 的 mri_convert.您不需要真正了解 mri_convert 是什么,就像您必须了解进程如何从 Scala 传输到系统一样.该代码在大多数情况下都有效,但是当我尝试发送带有空格的文件路径时,它会中断(即使在我用 \
替换空格之后).我将在下面发布我的代码,然后是使用一个没有目录的文件在其路径中包含一个空格的输出,然后是一个带有空格的目录的文件路径.
I am attempting to issue a system command to run the mri_convert of FreeSurfer. You don't really need to understand what mri_convert is, as much as you have to understand how the processes are transfered from scala to the system. The code works for the most part, but when I attempt to send a file path with spaces it breaks (even after I replace the spaces with \
). I'll post my code below and then the output from using a file without directory containing a space in its path, and then from a file path with a directory with a space.
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 程序将按预期执行.
I think it has to do with the fact that the argument passed to the system breaks the path with a space in the directory as seen in the brackets. Therefore, I believe that there is something funny going on with how my process is created. More importantly, in each situation if I cut and paste the val of path into terminal, the mri_convert program executes as expected.
提前致谢,如果需要更多详细信息,请告诉我.
Thanks in advance, and please let me know if more detail is required.
推荐答案
我建议从参数序列创建您的流程,而不是尝试从下游获取某些内容以正确解析它们.为此,您使用 stringSeqToProcess 隐式方法.
I suggest creating your process from a sequence of the arguments instead of trying to get something downstream to parse them correctly. To do that you use the stringSeqToProcess implicit method.
我创建了一个 shell 脚本,它在单独的行上打印出它的每个参数.为了更好地衡量,我在脚本的路径中放置了一个空格.然后我可以从 Scala 执行它:
I created a shell script that prints out each of its arguments on a separate line. For good measure I put a space in the path to the script. I then was able to execute it from Scala:
import scala.sys.process._
Seq("/home/lwickland/sp ace/script.sh", "a1", "/path/with a/sp ace", "c")!
shell 脚本将包含空格的参数视为单个项目.
The shell script saw the argument containing spaces as a single item.
Arg: a1
Arg: /path/with a/sp ace
Arg: c
我建议尝试将您的代码修改为:
I'd suggest trying to modify your code to be like:
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
}
如果这不起作用,请告诉我.
Please let me know if that doesn't work.
这篇关于Scala 系统进程和空格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!