2013-11-30 1 views
4

У меня есть функция в Баш скрипт, который выглядит следующим образом (упрощенный):Как (не) передать пустые кавычки переменные как аргументы команды

# Usage: f URL [PARAMETER]... 
f() { 
    local URL="$1"; shift 

    local PARAMS 
    for arg in "[email protected]"; do 
     PARAMS="${PARAMS}&${arg}" 
    done 
    PARAMS="${PARAMS#'&'}" 

    local DATA_OPTION 
    [ -z "${PARAMS}" ] || DATA_OPTION='--data' 

    curl -o - "${DATA_OPTION}" "${PARAMS}" "${URL}" 
} 

Это можно назвать как f http://example.com/resource или f http://example.com/resource p1=v1 p2=v2. Проблема в том, что DATA_OPTION и PARAMS пустые. В этом случае, Bash проходит две пустых аргументы скручиваться, которые затем признаются в качестве URL-адреса с помощью завитка и производят следующее уродливое сообщение:

curl: (3) <url> malformed 
curl: (3) <url> malformed 

я временно решить проблему, используя, если/другое, так что DATA_OPTION и PARAMS являются не прошли вообще:

[..] 

    if [ -z "${PARAMS}" ]; then 
     curl -o - --data "${PARAMS}" "${URL}" 
    else 
     curl -o - "${URL}" 
    fi 
} 

, но это кажется уродливым для меня. Есть ли более элегантное решение? Обратите внимание, что котировки вокруг PARAMS необходимы, потому что некоторые значения параметров могут содержать пробелы.

ответ

7

Вы действительно можете решить эту проблему чисто с опцией «использовать другое значение» (:+) в разложении параметра:

curl -o - ${PARAMS:+"--data" "$PARAMS"} "${URL}" 

Если PARAMS пуст или не определен, то вся ${PARAMS:+"--data" "$PARAMS"} вещи оценивается в пустую строку, и поскольку это не двойное цитирование, разбиение слов полностью удаляет его. С другой стороны, если PARAMS не является пустым, он эффективно заменяется на "--data" "$PARAMS", что и есть то, что вы хотите.

+0

Зачем указывать '-data' там, почему бы просто не просто $ $ PARAMMS: + данные Data $ PARAMS"} ' – janos

+1

@janos: либо будет работать, но я предпочитаю цитированную версию по двум причинам: Во-первых, при написании сценариев оболочки более безопасно обычно цитировать вещи, если есть причина не для того, чтобы попытаться вспомнить, когда вы можете уйти без кавычек. Во-вторых, при чтении скрипта с чем-то вроде этого гораздо проще сказать, где заканчивается опция расширения параметра (': +'), и аргумент ('--data') начинается, если между ними есть цитата (пространство также работа, но см. первую причину). –

1

Я думаю, что это хорошее сочетание ленивых и элегантно:

curl -o - --data "&$PARAMS" "$URL" 

Это верно, есть бесполезная & там. Дело в том, что это никому не повредит, это коротко, и он должен работать для обоих ваших случаев, есть ли у вас что-нибудь в PARAMS или нет.

Смежные вопросы