命令替换中变量中的引用处理
Quote handling in variables inside a command substitution
我想 assemble 一个带有两个变量的 curl
调用(一个用于公共参数,一个用于 URL)并通过命令替换捕获输出。当我添加需要包含引号的参数时,这会中断,比如 -H "Accept: text/html"
.
这是一个演示问题的小脚本,它调用一个 public echo service 来显示发送的请求 headers:
#!/bin/bash
COMMON_ARGS="--http1.1 -H \"Accept: text/html\""
URL="http://scooterlabs.com/echo"
RETVAL=$(curl -s $COMMON_ARGS $URL | grep Accept)
echo "1 $RETVAL"
RETVAL=$(curl -s --http1.1 -H "Accept: text/html" $URL | grep Accept)
echo "2 $RETVAL"
输出:
1 [Accept] => */*
2 [Accept] => text/html
所以我尝试通过变量提供 header 的第一次尝试不起作用(curl
发送默认 Accept: */*
),而第二次尝试,我手动添加 header,有效。使用单引号和引号转义都没有帮助。
更新: 当我偶然发现 shell 的解析器在它之前执行的 BashFaq/050 just before submitting the question. The problem is word splitting 时,我在这里学到了至少一部分课程调用给定的命令。正确的方法是将参数作为数组提供(旧的 bash
es 可能不支持这个):
COMMON_ARGS=(--http1.1 -H "Accept: text/html")
RETVAL=$(curl -s "${COMMON_ARGS[@]}" $URL | grep Accept)
echo "3 $RETVAL"
输出:
3 [Accept] => text/html
但还有一件事我想不通:如果默认情况下分词作用于 a space, a tab, and a newline. 那么为什么这个变体不起作用 - 没有 space 可以错误地分词?
COMMON_ARGS="--http1.1 -H 'Accept:text/html'"
RETVAL=$(curl -s $COMMON_ARGS $URL | grep Accept)
echo "4 $RETVAL"
输出:
4 [Accept] => */*
there's no space to wrongly split?
但是在 curl 看到 header 之前,通常会在引号删除中删除单引号。通过将它们包含在双引号中,它们得以保留,但 curl 不知道如何处理它们。
我想 assemble 一个带有两个变量的 curl
调用(一个用于公共参数,一个用于 URL)并通过命令替换捕获输出。当我添加需要包含引号的参数时,这会中断,比如 -H "Accept: text/html"
.
这是一个演示问题的小脚本,它调用一个 public echo service 来显示发送的请求 headers:
#!/bin/bash
COMMON_ARGS="--http1.1 -H \"Accept: text/html\""
URL="http://scooterlabs.com/echo"
RETVAL=$(curl -s $COMMON_ARGS $URL | grep Accept)
echo "1 $RETVAL"
RETVAL=$(curl -s --http1.1 -H "Accept: text/html" $URL | grep Accept)
echo "2 $RETVAL"
输出:
1 [Accept] => */*
2 [Accept] => text/html
所以我尝试通过变量提供 header 的第一次尝试不起作用(curl
发送默认 Accept: */*
),而第二次尝试,我手动添加 header,有效。使用单引号和引号转义都没有帮助。
更新: 当我偶然发现 shell 的解析器在它之前执行的 BashFaq/050 just before submitting the question. The problem is word splitting 时,我在这里学到了至少一部分课程调用给定的命令。正确的方法是将参数作为数组提供(旧的 bash
es 可能不支持这个):
COMMON_ARGS=(--http1.1 -H "Accept: text/html")
RETVAL=$(curl -s "${COMMON_ARGS[@]}" $URL | grep Accept)
echo "3 $RETVAL"
输出:
3 [Accept] => text/html
但还有一件事我想不通:如果默认情况下分词作用于 a space, a tab, and a newline. 那么为什么这个变体不起作用 - 没有 space 可以错误地分词?
COMMON_ARGS="--http1.1 -H 'Accept:text/html'"
RETVAL=$(curl -s $COMMON_ARGS $URL | grep Accept)
echo "4 $RETVAL"
输出:
4 [Accept] => */*
there's no space to wrongly split?
但是在 curl 看到 header 之前,通常会在引号删除中删除单引号。通过将它们包含在双引号中,它们得以保留,但 curl 不知道如何处理它们。