代码之家  ›  专栏  ›  技术社区  ›  PoVa

curl:(26)从字符串获取命令参数时无法打开文件

  •  0
  • PoVa  · 技术社区  · 6 年前

    get_common_curl_headers() {
      local crash_path="$1"
    
      echo -n \
        "-H 'Accept: text/plain'" \
        "-F 'model=<$crash_path/model'" \
        "-F 'version=<$crash_path/fw_version'"
    
      echo -n ' '
    }
    

    我希望返回的文件路径被引用为 $crash_path 变量可能包含空格。然后我像这样使用这个函数:

    send_app_crash() {
      local crash_path="$1"
      local common_headers
    
      common_headers=$(get_common_curl_headers "$crash_path")
      [ $? -ne 0 ] && return 1
    
      curl -vk -X POST \
        $common_headers\
        "$SERVER_URL"
    }
    
    

    $common_headers 这里没有引述,因为我想扩大论点,这对我的理解应该是有效的。但是,该命令会导致以下错误:

    curl: (6) Couldn't resolve host 'text'
    curl: (26) couldn't open file "/tmp//model'"
    

    奇怪的是,在文件名的末尾有一个额外的单引号,它应该被shell删除。我也不知道第一个错误意味着什么 Accept: text/plain

    手动运行命令(即 set -x 在命令出现在脚本中并通过管道将其发送到 sh )按计划工作:

    curl -vk -X POST -H 'Accept: text/plain' -F 'model=</tmp//model' -F 'version=</tmp//fw_version' 192.168.2.100:8888
    
    0 回复  |  直到 6 年前
        1
  •  1
  •   root    6 年前

    如何调试

    set -x 在执行curl命令之前,您会看到:

    curl -vk -X POST -H ''\''Accept:' 'text/plain'\''' -F ''\''model=<some-crash-path/model'\''' -F ''\''version=<some-crash-path/fw_version'\''' example.com
    

    现在让我们做一些魔术:

    $ printf "%s\n" curl -vk -X POST -H ''\''Accept:' 'text/plain'\''' -F ''\''model=<some-crash-path/model'\''' -F ''\''version=<some-crash-path/fw_version'\''' example.com
    curl
    -vk
    -X
    POST
    -H
    'Accept:
    text/plain'
    -F
    'model=<some-crash-path/model'
    -F
    'version=<some-crash-path/fw_version'
    example.com
    

    这个 printf Accept: test/plain ,您生成了2个参数: 'Accept: text/plain' .

    -H 'Accept: (即标题以 ' 不包含预期值),下一个参数是 文本/纯文本' ,它没有任何前缀,所以curl认为它是URL,这就是为什么它说 text

    这也解释了为什么它找不到 /tmp/model' (与 ' 最后)。

    而不是使用

    curl -vk -X POST $common_headers "$SERVER_URL"
    

    只需添加 eval

    eval curl -vk -X POST $common_headers "$SERVER_URL"
    

    为了你的目的, 相当于管道 sh

    正确的道路

    评估 (或管道 上海

    否则你怎么做?

    get_common_curl_headers() 里面 send_app_crash()

    send_app_crash() {
        local crash_path="$1"
        curl -vk \
            -X POST \
            -H "Accept: text/plain" \
            -F "model=<$crash_path/model" \
            -F "version=<$crash_path/fw_version" \
            "$SERVER_URL"
    }
    

    选项2-在全局数组中生成参数:

    get_common_curl_headers() {
        local crash_path="$1"
    
        COMMON_HEADERS=( \
            -H "Accept: text/plain" \
            -F "model=<$crash_path/model" \
            -F "version=<$crash_path/fw_version" \
        )
    }
    
    send_app_crash() {
        local crash_path="$1"
        local common_headers
    
        get_common_curl_headers "$crash_path"
        [ $? -ne 0 ] && return 1
    
        curl -vk -X POST "${COMMON_HEADERS[@]}" "$SERVER_URL"
    }
    

    注意数组解引用的引号,注意不能返回数组。