clojure.java.shell/sh 给出了与命令行不同的行为?

ne5o7dgx  于 2023-03-30  发布在  Shell
关注(0)|答案(1)|浏览(98)

我正在使用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的调用与标准命令行的不同之处?

mw3dktmi

mw3dktmi1#

clojure.java.shell/sh期望进程的所有参数作为 separate 参数运行。您的代码将 all 参数作为单个参数传递,因此您会得到错误参数的错误。
所以正确的调用应该是这样的:

(sh "KaHyPar" "-k" "2" "-e" "0.03" "-m" "direct" "-o" "cut" "-w" "true" "-p" configFile  "-h" hgrFile)

如果使用了太多参数,或者命令已经从其他地方提供(例如用户输入或配置文件),那么通过(UNIX)“shell规则”解析并像这样拆分命令可能会很繁琐。在这种情况下,或者当你需要(UNIX)“shell-ism”时,你也可以通过(UNIX)shell运行它:

(sh "/bin/sh" "-c" "KaHyPar -k 2 -e 0.03 -m direct ...")

这样,参数就可以遵循shell规则。

相关问题