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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22739916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:03:41  来源:igfitidea点击:

Error when running curl inside script (No such file or directory)

bashcurlsh

提问by Brad

I have the following .sh file I pieced together off of things I found on the internet.
The goal is to read the 2nd line 2nd item in a CSV file and use that to send a delete commmand to elasticsearch.

我有以下 .sh 文件,我从网上找到的东西拼凑起来。
目标是读取 CSV 文件中的第二行第二项,并使用它向 elasticsearch 发送删除命令。

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


function quit {
        echo "Quitting Script"
        IFS=$OLDIFS
    exit 1
}
function fileExists {
    if [ ! -f "" ]
        then
            echo "File  does not exists"
                quit
        fi
echo "File Name:  "
}
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

        } < 

}

fileExists 
work 
IFS=$OLDIFS

Everything works except the execution of the curl script. I've tried it with $(), backtics, exec, and I cannot get it to work.

除了执行 curl 脚本外,一切正常。我已经用 $()、backtics、exec 试过了,但我无法让它工作。

The following is the error when I run bash -vx script.sh:

以下是我运行 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 "" ]
    then
        echo "File  does not exists"
        quit
    fi  
echo "File Name:  "
}
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

    } <   

}

fileExists 
+ fileExists catalog.csv
+ '[' '!' -f catalog.csv ']'
+ echo 'File Name:  catalog.csv'
File Name:  catalog.csv
work 
+ 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='     
'

Example CSV file would be

示例 CSV 文件将是

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

回答by 6EQUJ5

Running $("$QUERY")actually tries to run in a sub-shell, a command called <the expanded value of $QUERY>, hence your '(bunch of stuff) No such file or directory'error.

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

You probably want something like:

你可能想要这样的东西:

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

The trick here is how you nest the single and double quotes. Its a bit hard to explain concisely, but here goes:

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

  • Shell variables do not expand inside an outer single quote.
  • But you dont need to escape a double quote inside a single quote
  • So how we get $PROGRAMURLto expand above is immediately concatenate it between a pair of closing-opening single quotes.
  • To subsequently use the variable CURLDATAit has to get passed to the curlcommand inside double quotes
  • A much simpler example:
  • Shell 变量不会在外部单引号内扩展。
  • 但是你不需要在单引号内转义双引号
  • 所以我们如何$PROGRAMURL在上面进行扩展是立即将它连接在一对关闭-打开单引号之间。
  • 要随后使用该变量,CURLDATA它必须传递给curl双引号内的命令
  • 一个更简单的例子:
VARIABLE1="Hello, world"
VARIABLE2='This is "$verbatim" stuff"'$VARIABLE1'" More stuff'
  • This produces a value of $VARIABLE2of This is "$verbatim" stuff"Hello, World" More stuff
  • 这产生的值$VARIABLE2This is "$verbatim" stuff"Hello, World" More stuff

Other things to note:

其他注意事项:

  • The above will put the entire stdout of the curlcommand into the variable RESPONSE
  • You will need to check $?afterwards to see if curl actually managed to talk to the host, etc. - it will be 0 if everything went OK
  • You may wish to turn off the progress bar
  • 以上将把curl命令的整个标准输出放入变量中RESPONSE
  • 之后您需要检查$?curl 是否真的设法与主机对话等 - 如果一切正常,它将为 0
  • 您可能希望关闭进度条

Skipping lines:

跳线:

  • A better way to skip lines is to use:
  • 跳过行的更好方法是使用:
tail -n +$(( $linesToSkip +1 ))