从Java到Terminal再到Applescript的空白

从Java到Terminal再到Applescript的空白,java,terminal,arguments,applescript,quoting,Java,Terminal,Arguments,Applescript,Quoting,我正试图使用mac终端中的“osascript”命令从java程序运行applescript。当我从终端尝试时,applescript与名称中带有空格的应用程序完美配合,如“osascript ActivateApp.scpt Google\Chrome”,但当我尝试在java中使用它时,它将打开一个没有空格的应用程序。到目前为止我已经试过了 Runtime.getRuntime().exec("osascript pathTo/ActivateApp.scpt Google Chrome");

我正试图使用mac终端中的“
osascript
”命令从java程序运行applescript。当我从终端尝试时,applescript与名称中带有空格的应用程序完美配合,如“
osascript ActivateApp.scpt Google\Chrome
”,但当我尝试在java中使用它时,它将打开一个没有空格的应用程序。到目前为止我已经试过了

Runtime.getRuntime().exec("osascript pathTo/ActivateApp.scpt Google Chrome");

但它们都不起作用。以下是applescript:

on run argv
tell application (item 1 of argv)
activate
end tell
end run
尝试:

您看到的问题是,应用程序名称被视为两个参数,而不是一个参数。在命令行上,转义空间不会导致bash基于它进行拆分,而是将其作为参数的一部分进行传递。转义在Java中不起作用,因为Java正在将转义空间转换为常规空间。您可以通过执行类似于
“osascript pathToScript/ActivateApp.scpt Google\\Chrome”
的操作来正确处理转义,以便传递
\
,但最好更仔细地引用

这类问题的最佳解决方案是使用支持逐段构建命令的库,这样您就不必担心空格会无意中打断应为单个参数的内容,例如:

Map map = new HashMap();
map.put("file", new File("invoice.pdf"));
CommandLine cmdLine = new CommandLine("AcroRd32.exe");
cmdLine.addArgument("/p");
cmdLine.addArgument("/h");
cmdLine.addArgument("${file}");
cmdLine.setSubstitutionMap(map);
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
ExecuteWatchdog watchdog = new ExecuteWatchdog(60000);
executor.setWatchdog(watchdog);
int exitValue = executor.execute(cmdLine);
虽然一开始可能看起来很复杂,但当一些原本无害的输入微妙地破坏了某些东西时,正确的方法可以让你省去很多麻烦

Runtime.getRuntime().exec("osascript pathToScript/ActivateApp.scpt 'Google Chrome'");
Map map = new HashMap();
map.put("file", new File("invoice.pdf"));
CommandLine cmdLine = new CommandLine("AcroRd32.exe");
cmdLine.addArgument("/p");
cmdLine.addArgument("/h");
cmdLine.addArgument("${file}");
cmdLine.setSubstitutionMap(map);
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
ExecuteWatchdog watchdog = new ExecuteWatchdog(60000);
executor.setWatchdog(watchdog);
int exitValue = executor.execute(cmdLine);