bash参数中的引号因curl而失败

时间:2013-12-19 16:35:28

标签: bash curl double-quotes

我想在bash脚本中调用函数时记录各种事情,所以我想尝试一个特殊的地方来做这件事

function CallAndLog {
  echo "$@" > /tmp/debug
  res=$("$@" 2> /tmp/error)
  if [ $? -gt 0 ]
  then
    echo "error : $(</tmp/error)" >> /tmp/log
  fi
  echo "$res" >> /tmp/log
}

val="a test"
CallAndLog curl --data '"'"query=$val"'"' http://google.com

我明白了

  • 的/ tmp /调试

curl --data“query = a test”http://google.com

  • 的/ tmp /错误

curl:(6)无法解析主持人'test''   %总收到百分比%Xferd平均速度时间时间当前时间                                  Dload上载总左转速度 100 967 100 959 100 8 1060 8 0:00:01 - : - : - 0:00:01 1572

  • 的/ tmp /日志

<!DOCTYPE html>...

/ tmp / debug是完美的,这正是我想要执行的,如果我复制并粘贴它可以工作。然而,错误表明“a”和“test”被分成2个,curl尝试“test”作为url。这是我不明白的事情

我尝试了很多不同的东西:$ ,$ @,“$ ”,“* @”,各种方式放单引号和双引号,所以经过几个小时的挣扎我打电话给你的帮助 !!!非常感谢

2 个答案:

答案 0 :(得分:1)

您执行正确,但记录不正确。这就是命令失败时日志显示正常的原因。

调用应该只是

CallAndLog curl --data "query=$val"

要记录该语句,请使用

printf "%q " "$@" >> /tmp/debug

您的引用将被重新格式化,但在语义上是相同的(即您可以复制粘贴语句以相同的方式运行相同的命令)。这是因为引用是shell语法,它控制各种形式的拆分和扩展,只有效果(而不是语法)被带入函数。


以下是一个例子:

function CallAndLog {
  printf "%q " "$@" > /tmp/debug
  echo >> /tmp/debug # add line feed
  res=$("$@" 2> /tmp/error)
  if [ $? -gt 0 ]
  then
    echo "error : $(</tmp/error)" >> /tmp/log
  fi
  echo "$res" >> /tmp/log
}

val="a test"
CallAndLog curl --data "query=$val" http://google.com

运行之后,我们可以查看输出日志文件:

$ cat /tmp/debug
curl --data query=a\ test http://google.com 

$ cat /tmp/error
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   971  100   959  100    12   6101     76 --:--:-- --:--:-- --:--:-- 43590

$ cat /tmp/log
<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, ...

答案 1 :(得分:0)

正如您所猜测的那样,问题在于res=$("$@" 2> /tmp/error)。在执行示例curl语句时,引号会丢失,因此实际传递的是:

curl --data query=a test http://google.com

那么,我们该如何解决这个问题呢?好吧,我认为最简单的方法就是修改你的陈述方式:

val="a test"
CallAndLog curl --data query=\"${val}\"

通过转义引号, 现在应该以正确的语法发送:

curl --data query="a test" http://google.com

此代码可在本地使用

~/tmp › cat /tmp/debug 
curl --data query="a test" http://google.com

~/tmp › cat /tmp/log 
<!DOCTYPE html> <html lang=en>   <meta charset=utf-8>   <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">   <title>Error 405 (Method Not Allowed)!!1</title>   <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}} </style>   <a href=//www.google.com/><img src=//www.google.com/images/errors/logo_sm.gif alt=Google></a>   <p><b>405.</b> <ins>That’s an error.</ins>   <p>The request method <code>POST</code> is inappropriate for the URL <code>/</code>.  <ins>That’s all we know.</ins>

现在,谷歌发回的错误结果完全是另一个问题。