使用groovy为cURL创建命令行字符串-cURL会忽略选项



我需要帮助弄清楚为什么我的cURL查询的最后两个参数被忽略。

请不要评论这不是打休息电话的最佳方式。我知道。这将是一种针对另一个问题的后备方法。我将使用wslite(1.1.2)API处理我的休息工作。

现在让我解释一下我的工作:我使用groovy shell执行器通过cURL对rest服务进行命令行调用。

我已经构建了一个小类来构建查询字符串并处理命令行:

    class Curl {
    def static getUserLogin(){
        def url                 = '"https://some-login.someSystem-dev.someHost.com/someResource.beyond.foobar/login/LoginAUser '
        def requestFilePath     = '-d @temp/LoginPayload.json '
        def heads               = "-H 'Content-Type: application/json' -H 'Accept: text/plain' " 
        def params              = '-k -v' //-k = ignore unsecure -v = more verbose output
        def fullurl             = url+requestFilePath+heads+params
        return ex(fullurl)
    }
    /**
    * 
    * @param _command The command you want to execute on your shell. 
    * @param _workingDir Optional: You may specify the directory where the command will be executed. Default is user dir.
    * @return Exit value for the process. 0 = normal termination.
    */
  def static ex(String _command, File _workingDir = new File(System.properties.'user.dir')) {
    println "Executing command> $_command n"
    def process = new ProcessBuilder(addShellPrefix(_command))
                                      .directory(_workingDir)
                                      .redirectErrorStream(true)
                                      .start()
    process.inputStream.eachLine {println it}
    process.waitFor();
    return process.exitValue().value
  }
  private static addShellPrefix(String _command) {
    def commandArray = new String[2]
    commandArray[0] = "curl "
    commandArray[1] = _command
    return commandArray
  }
}

Curl.getUserLogin() //to execute

我希望代码足够自我解释。它分别适用于参数较少的简单URL。

执行此操作将产生以下响应(摘录自完整调试输出):

执行命令>"https://some-login.someSystem-dev.someHost.com/someResource.beyond.foobar/login/LoginAUser"-d@temp/LoginPyload.json-H"内容类型:application/json"-H"接受:text/plain"-k-v

%总接收百分比平均速度时间时间时间时间现在的Dload上传总花费左速度

0 0 0 0----:--:--0 0 0 0 00 0 0 0--:----:--::--:--0 curl:(60)SSL证书问题:证书链中的自签名证书此处提供详细信息:http://curl.haxx.se/docs/sslcerts.html

curl默认情况下使用证书颁发机构(CA)公钥(CA证书)的"捆绑包"。如果默认的捆绑文件不够,可以指定一个备用文件使用--cacert选项。如果此HTTPS服务器使用证书由捆绑包中代表的CA签名,证书验证可能由于证书问题而失败(它可能已过期,或者名称可能与中的域名不匹配URL)。如果您想关闭curl对证书,请使用-k(或--unsecurity)选项。

现在,正如您所看到的,我已经将所需的选项"-k"附加到查询字符串中,但不知何故它被忽略了。不过,在windows命令行工具中直接使用此字符串(如果您尝试这样做,请确保转义潜在的双引号)效果非常好。

有什么想法为什么会发生这种情况,或者我如何获取更多的调试信息吗?

提前Thx!

更新:解决方案:
将ever选项作为单个参数(通过列表)传递解决了这个问题。

新发行:之后,我希望curl使用参数列表中的"-o C:\Temp\response.txt"来输出对文件的响应。从命令行工具中使用时,效果良好。从groovy脚本执行它的结果是:

curl:(23)写入正文失败(0!=386)

我可以通过将流写入文件来解决这个问题。真正困扰我的是,响应中似乎没有包含任何信息。从windows命令行工具执行curl命令会返回一个相当长的令牌。

安迪的想法?

如果使用ProcessBuilder,则必须将每个参数作为自己的参数。为构造函数提供两个参数,程序名和作为一个参数的其余参数,就像在命令行中在整个字符串周围加引号一样。将fullurl改为列表,其中每个参数都是自己的列表元素,并且应该按预期工作。不过,你可以也应该省略URL周围的任何其他引用。

您的代码可以得到极大的改进。您不应该将命令部分连接到单个字符串中,只需使用列表即可。

此外,变量上的_前缀通常用于私有字段或仅用于内部,而不是显然不是内部的方法参数。

在Groovy中使用字符串数组是很奇怪的,你肯定应该学习一些Groovy!

无论如何,这里有一个更好的版本的代码:

def static getUserLogin() {
    def url = '"https://some-login.someSystem-dev.someHost.com/someResource.beyond.foobar/login/LoginAUser'
    def requestFilePath = '-d @temp/LoginPayload.json'
    def heads = "-H 'Content-Type: application/json' -H 'Accept: text/plain' "
    def insecure = '-k'
    def verbose = '-v'
    return ex( [ url, requestFilePath, heads, insecure, verbose ] )
}
/**
 *
 * @param commands The command + args you want to execute on your shell.
 * @param _workingDir Optional: You may specify the directory where the command will be executed. Default is user dir.
 * @return Exit value for the process. 0 = normal termination.
 */
static ex( List<String> commands, File _workingDir = new File( System.properties.'user.dir' ) ) {
    println "Executing command> $commands n"
    def process = new ProcessBuilder( addShellPrefix( commands ) )
            .directory( _workingDir )
            .inheritIO()
            .start()
    process.waitFor()
    return process.exitValue().value
}
private static addShellPrefix( List<String> commands ) {
    [ 'curl' ] + commands
}

最新更新