bash参数中的引号使用curl失败
在bash脚本中调用函数时,我希望记录各种事情,因此我尝试在一个特殊的地方完成这项工作bash参数中的引号使用curl失败,bash,curl,double-quotes,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="
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
函数CallAndLog{
echo“$@”>/tmp/debug
res=$(“$@”2>/tmp/error)
如果[$?-gt 0]
然后
echo“error:$(正如您所猜测的,问题在于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>
现在,从Google返回的错误结果是另一个问题。您的执行正确,但日志记录不正确。这就是为什么在命令失败时日志显示良好的原因
调用应该是简单的
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
函数CallAndLog{
printf“%q”$@>/tmp/debug
echo>>/tmp/debug#添加换行符
res=$(“$@”2>/tmp/error)
如果[$?-gt 0]
然后
echo“错误:$(可能是重复的,我不知道您是如何得到http://google.com
在调试中自“”从未出现在您的示例中,调试/日志输出无法与您显示的输入相对应。不可能知道其余输入是否相对应,但我对此表示怀疑,因为示例应以不同的方式失败。输出看起来像来自CallAndLog curl--data''query=$val''' http://google.com
@glennjackman我不认为它是重复的,因为$@或$*和引号有些可疑。url编码可能是一种解决方法,但我不知道它为什么会失败,我不相信这个分析是正确的。“$@”
将保留参数中的单词分隔。此外,OP不希望将实际的双引号传递给curl,afaik.True,但“$@”仅在将其发送到$()
时才保留单词分隔,在本例中,这是它丢失它们的时候。并非如此。(set--bash-c echo\\\\$1\\\\\\\\\$a b”c;res=$(“$@”);echo“$res”)
从OP中可以清楚地看到,它正在丢失“a test”的内部引号什么是“a test”的内部引号?val=“a test”
没有将任何引号放入$val
中(curl也不期望它们。正确的调用是--data query a%20test
)。您当然不希望使用--data \“query=a%20test\”
.TIAS。如果调用ANDLOG“curl…”query=$val“,$val将不会被其值替换,因为它是单引号。我还没有测试您的日志语句,但我可以告诉您我执行得不正确(请参阅/tmp/error)@托马斯:在eval
uation@Thomas不,我的意思是CallAndLog中的执行行是正确的,但是调用CallAndLog是错误的,因为您试图取悦错误的日志语句,而不是正确的执行行。答案显示了如何正确调用它。我已经尝试过了,但确实如此esn不会被替换,它保持为$val
$ 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, ...