Это вопрос о том, как Bash обрабатывает группирование слов и расширение переменных. Я продемонстрирую вопрос на очень конкретном примере:

bash$ git log --format=fuller --date=format:"%Y-%m-%d T%H"    # This works.

# Sample output:
commit aba22155684
Author:     SerMetAla
AuthorDate: 2018-04-12 T23
Commit:     SerMetAla
CommitDate: 2018-04-12 T23

    Here is the commit message.

Я хотел бы, чтобы это работало:

bash$ git log "$myformat"    # It should print the same stuff.

Я не знаю, как это сделать, используя только одну переменную Bash. Вот рабочий пример с ДВУМЯ переменными:

# Define the two variables:
bash$ mypref="--format=fuller"
bash$ mydate="--date=format:%Y-%m-%d T%H"    # Note: No " after the colon.

# Now use it:
bash$ git log "$mypref" "$mydate"    # It works.

Проблема в следующем: как я могу заставить это работать только с одной переменной Bash? Является ли это возможным?

Главная проблема:

git log --format=fuller --date=format:"%Y-%m-%d T%H"
                       |                       ^ This space is inside one argument.
                       |
                       ^ This space separates two arguments.

Я хотел бы использовать обычную строковую переменную. Я не хочу использовать переменную массива, я не хочу использовать $'...' Я не хочу использовать функцию, я не хочу использовать псевдоним. Когда строка является неизменной, и когда она не находится в начале команды, создается впечатление, что она должна быть переменной Bash.

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

2 ответа2

1

Это общий FAQ. https://mywiki.wooledge.org/BashFAQ/050

Вкратце, способ решить эту проблему - поместить аргументы в массив.

myformat=("$mypref" "$mydate")
git log "${myformat[@]}"

В качестве очень грубого обходного пути вы также можете использовать printf со спецификатором формата цитирования:

printf -v myformat '%q %q' "$mypref" "$mydate"
git log $myformat
1

Я не хочу использовать переменную массива

Вы отказываетесь от подходящего инструмента для работы. Ну, вы можете попробовать с eval:

$> foo='a "b c"'
$> printf "%s\n" $foo
a
"b
c"
$> eval printf '"%s\n"' $foo
a
b c
$>

В вашем случае это будет выглядеть так:

myformat='--format=fuller --date=format:"%Y-%m-%d T%H"'
eval git log $myformat

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .