Обработка кавычек в переменных внутри командной подстановки

#bash #curl #command-substitution

#bash #curl #команда-подстановка

Вопрос:

Я хочу собрать curl вызов с двумя переменными (одна для общих аргументов и одна для URL-адреса) и захватить выходные данные с помощью подстановки команд. Это прерывается, когда я добавляю параметры, которые нуждаются в кавычках, например, скажем -H "Accept: text/html" .

Вот небольшой скрипт для демонстрации проблемы, который вызывает общедоступную службу echo для отображения заголовков отправленных запросов:

 #!/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
 

Итак, первая попытка, когда я пытаюсь передать заголовок через переменную, не работает ( curl отправляет значение по умолчанию Accept: */* ), тогда как вторая попытка, когда я вручную добавил заголовок, работает. Ни использование одинарных кавычек, ни экранирование кавычек не помогли.


Обновление: я выучил хотя бы часть своего урока здесь, когда наткнулся на BashFAQ / 050 непосредственно перед отправкой вопроса. Проблема заключается в разделении слов, выполняемом синтаксическим анализатором оболочки перед вызовом данной команды. Правильный способ сделать это в моем случае — предоставить параметры в виде массива (более старые bash версии могут не поддерживать это):

 COMMON_ARGS=(--http1.1 -H "Accept: text/html")
RETVAL=$(curl -s "${COMMON_ARGS[@]}" $URL | grep Accept)
echo "3 $RETVAL"
 

Вывод:

 3             [Accept] => text/html
 

Но есть еще одна вещь, которую я не мог понять: если разделение слов по умолчанию действует на пробел, табуляцию и перевод строки.тогда почему этот вариант не работает — нет места для неправильного разделения?

 COMMON_ARGS="--http1.1 -H 'Accept:text/html'"
RETVAL=$(curl -s $COMMON_ARGS $URL | grep Accept)
echo "4 $RETVAL"
 

Вывод:

 4             [Accept] => */*
 

Комментарии:

1. Но есть одинарные кавычки, которые обычно удаляются при удалении кавычек до того, как curl увидит заголовок. При включении их в двойные кавычки они сохраняются, но curl не знает, что с ними делать.

2. @choroba: в этом есть большой смысл. спасибо, пожалуйста, опубликуйте этот комментарий в качестве ответа!

3. Хм. Поскольку вы заметили BashFAQ # 50 и внесли изменения в вопрос, это делает его не таким дублирующим многие другие вопросы, которые у нас есть по поводу той же проблемы. Возможно, заголовок следует отредактировать, чтобы различать?

4. @CharlesDuffy я прочитал не только один из этих вопросов, но недостающий бит информации не был передан в ответах… подумал, что это может помочь другим!

Ответ №1:

нет места для неправильного разделения?

Но есть одинарные кавычки, которые обычно удаляются при удалении кавычек до того, как curl увидит заголовок. При включении их в двойные кавычки они сохраняются, но curl не знает, что с ними делать.