clojure.java.shell/sh执行KahyPar与命令行行为不一致问题排查
问题分析与解决
核心原因
Clojure的clojure.java.shell/sh(底层基于Java的Runtime.exec())和终端shell的参数处理逻辑完全不一样:
- 终端输入命令时,shell会自动把整行字符串拆分成独立的参数列表,比如把
-k 2拆成["-k", "2"]两个参数传给程序。 - 但你把所有参数拼成一个字符串传给
shell/sh时,它会把这个完整字符串当作单个参数交给KaHyPar。KaHyPar用Boost解析参数时,会把这个长字符串当成-k选项的参数值,自然就报“无效参数”的错了。
你用echoArgs.sh测试时看起来输出和命令行一致,是因为bash脚本接收到单个字符串参数后,会自动帮你做一次拆分,但KaHyPar是直接读取程序启动时的argv数组,不会做额外拆分,所以两者表现不同。
正确的调用写法
必须把每个命令行参数拆成独立的项,作为shell/sh的单独参数传入,不能拼成一个大字符串。正确代码如下:
(let [khpPath ".../git/kahypar/build/kahypar/application/KaHyPar" rv (shell/sh khpPath "-k" "2" "-e" "0.03" "-m" "direct" "-o" "cut" "-w" "true" "-p" configFile "-h" hgrFile)] ;; 这里处理返回结果 )
关于你尝试过的“单独传递”
如果你之前尝试的是把"-k 2"作为一个参数传进去,那还是错的——必须把选项名("-k")和它对应的值("2")拆成两个独立参数,每个选项和值都要分开传。
补充说明
Java的Runtime.exec()系列方法不会像终端shell那样做参数拆分,完全依赖你传入的参数数组。Clojure的shell/sh只是这个API的封装,所以必须严格按独立参数的方式传递,不能依赖字符串拼接来模拟命令行输入。
内容的提问来源于stack exchange,提问作者rikb
相关产品推荐
相关产品推荐

