在脚本中运行curl时出错(没有这样的文件或目录)

4

我有一个.sh文件,是从互联网上找到的内容拼凑而成的。
目标是读取CSV文件中第二行第二个项目,并使用该项目向elasticsearch发送删除命令。

#!/bin/sh
OLDIFS=$IFS
IFS=,


function quit {
        echo "Quitting Script"
        IFS=$OLDIFS
    exit 1
}
function fileExists {
    if [ ! -f "$1" ]
        then
            echo "File $1 does not exists"
                quit
        fi
echo "File Name:  $1"
}
function work {
        linesToSkip=1
        {
            for ((i=$linesToSkip;i--;)) ;do
                read
            done
                #Read 2nd item of the 2nd line of CSV file to get PROGRAMURL
            read INDEX PROGRAMURL JUNK
                echo "$PROGRAMURL"
                QUERY="curl -XDELETE http://127.0.0.1:9200/cj/_query  -d '{ \"query\" : { \"match\" : { \"PROGRAMURL\" : "$PROGRAMURL" } } }'"
                $("$QUERY")
                #RESPONSE=`$QUERY`
                #echo $RESPONSE

        } < $1

}

fileExists $1
work $1
IFS=$OLDIFS

除了执行curl脚本之外,一切都正常。 我已经尝试使用$(),backtics,exec等方式,但无法使其正常工作。
当我运行bash -vx script.sh时,出现以下错误:
bash -vx ./deleteExisting.sh catalog.csv
#!/bin/sh
OLDIFS=$IFS
+ OLDIFS='  
'
IFS=,
+ IFS=,


function quit {
    echo "Quitting Script"
    IFS=$OLDIFS
    exit 1
}
function fileExists {
    if [ ! -f "$1" ]
    then
        echo "File $1 does not exists"
        quit
    fi  
echo "File Name:  $1"
}
function work {
    linesToSkip=1
    {
        for ((i=$linesToSkip;i--;)) ;do
            read
        done
        #Read 2nd item of the 2nd line of CSV file to get PROGRAMURL
        read INDEX PROGRAMURL JUNK
        echo "$PROGRAMURL"
        QUERY="curl -XDELETE http://127.0.0.1:9200/cj/_query  -d '{ \"query\" : { \"match\" : { \"PROGRAMURL\" : "$PROGRAMURL" } } }'"
        $("$QUERY")
        #RESPONSE=`$QUERY`
        #echo $RESPONSE

    } < $1  

}

fileExists $1
+ fileExists catalog.csv
+ '[' '!' -f catalog.csv ']'
+ echo 'File Name:  catalog.csv'
File Name:  catalog.csv
work $1
+ work catalog.csv
+ linesToSkip=1
+ (( i=1 ))
+ (( i-- ))
+ read
+ (( 1 ))
+ (( i-- ))
+ read INDEX PROGRAMURL JUNK
+ echo '"http://www.website.com"'
"http://www.website.com"
+ QUERY='curl -XDELETE http://127.0.0.1:9200/cj/_query  -d '\''{ "query" : { "match" : { "PROGRAMURL" : "http://www.website.com" } } }'\'''
"$QUERY")
"$QUERY"
++ 'curl -XDELETE http://127.0.0.1:9200/cj/_query  -d '\''{ "query" : { "match" : { "PROGRAMURL" : "http://www.website.com" } } }'\'''
./deleteExisting.sh: line 29: curl -XDELETE http://127.0.0.1:9200/cj/_query  -d '{ "query" : { "match" : { "PROGRAMURL" : "http://www.website.com" } } }': No such file or directory
IFS=$OLDIFS 
+ IFS='     
'

示例CSV文件如下:

INDEX, PROGRAMURL, other, info
"1", "http://website.com", "other info", "information"

不要试图从字符串和变量的片段中形成命令。使用一个函数 - n. m.
你能再详细解释一下吗? - Brad
即使在使用函数的情况下,在Shell脚本中,有时候需要将各个部分粘合在一起...这通常是一个指示,表明现在可能是考虑另一种语言(如Python)的时候了。 - 6EQUJ5
编写一个名为 query 的函数。将 $PROGRAMURL 作为参数传递。 - n. m.
他仍然需要知道如何将随后成为$1的内容与该函数内的其余参数-d连接起来... - 6EQUJ5
1个回答

10

运行 $("$QUERY") 实际上尝试在一个子 shell 中运行一个名为 <the expanded value of $QUERY> 的命令,因此你会收到 '(bunch of stuff) No such file or directory' 错误。

你可能想要做的是:

CURLURL="http://127.0.0.1:9200/cj/_query"
CURLDATA='{ "query" : { "match" : { "PROGRAMURL" : "'$PROGRAMURL'" } } }'
RESPONSE=`curl -XDELETE "$CURLURL"  -d "$DATA"`

这里的技巧在于如何嵌套单引号和双引号。简明扼要地解释有点困难,但是我们来试一试:

  • 外部单引号中不会展开shell变量。
  • 但是你不需要在单引号中转义双引号。
  • 所以我们如何让上面的$PROGRAMURL展开,就是立即将它连接在一对单引号之间。
  • 要后续使用变量CURLDATA,它必须在双引号内传递给curl命令。
  • 一个更简单的例子:
VARIABLE1="Hello, world"
VARIABLE2='This is "$verbatim" stuff"'$VARIABLE1'" More stuff'
  • 这将生成一个值为$VARIABLE2的字符串,其内容为This is "$verbatim" stuff"Hello, World" More stuff

其他需要注意的事情:

  • 上述代码将把curl命令的整个标准输出存入变量RESPONSE
  • 您需要在之后检查$?以查看curl是否成功连接到主机等-如果一切正常,则它将为0
  • 您可能希望关闭进度条

跳过行:

  • 跳过行的更好方法是使用:
tail -n +$(( $linesToSkip +1 ))

看起来这个有效了,感谢您的解释。 - Brad
我按照你说的更新了脚本,但是我仍然遇到了同样的问题,我认为我做得没错... 你能看一下吗?http://stackoverflow.com/questions/22759076/bash-script-not-running-propperly 谢谢。 - Brad
很棒的东西 :) 上帝保佑你。 - Pinak Mazumdar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接