我正在使用clojure对一个程序(https://github.com/kahypar)进行shell调用,但是当以这种方式调用时,我可以成功地从命令行进行的相同调用不起作用。
kahypar -k 2 -e 0.03 -m direct -o cut -w true -p .../baseConfig-direct.ini -h .../g0.hgr
我在clojure中创建了这个命令,并像这样使用clojure.java.shell/sh
(通过Java的Runtime.exec()
):
(let [khpPath ".../git/kahypar/build/kahypar/application/KaHyPar"
param (format "-k 2 -e 0.03 -m direct -o cut -w true -p %s -h %s" configFile hgrFile)
rv (shell/sh khpPath param) ]
我得到以下错误kahypar/boost:
khpEval: exit=134 err=libc++abi: terminating with uncaught exception of type boost::wrapexcept<boost::program_options::invalid_option_value>: the argument (' 2 -e 0.03 -m direct -o cut -w true -p .../baseConfig-direct.ini -h .../g0.hgr') for option '--blocks' is invalid
但是如果我把对kahypar的调用替换为对这个简单的www.example.com脚本的调用echoArgs.sh
#!/bin/bash
echo "echo:"
echo "$@"
echo "printf"
printf '%s\n' "$*"
并将khpPath
替换为指向此脚本的echoPath
,它会返回与命令行上完全相同的参数:
echo:
-k 2 -e 0.03 -m direct -o cut -w true -p ...baseConfig-direct.ini -h .../g0.hgr
printf
-k 2 -e 0.03 -m direct -o cut -w true -p ...baseConfig-direct.ini -h .../g0.hgr
我还尝试过将多个参数单独传递而不是作为单个字符串的一部分;还是没有爱。
因为(shell/sh)
使用futures,所以我不能深入到调用堆栈中进行更深入的跟踪。有没有办法看看clojure对shell的调用与标准命令行的不同之处?
1条答案
按热度按时间mw3dktmi1#
clojure.java.shell/sh
期望进程的所有参数作为 separate 参数运行。您的代码将 all 参数作为单个参数传递,因此您会得到错误参数的错误。所以正确的调用应该是这样的:
如果使用了太多参数,或者命令已经从其他地方提供(例如用户输入或配置文件),那么通过(UNIX)“shell规则”解析并像这样拆分命令可能会很繁琐。在这种情况下,或者当你需要(UNIX)“shell-ism”时,你也可以通过(UNIX)shell运行它:
这样,参数就可以遵循shell规则。