Общий вопрос:
В Bash я знаю, что использовать переменную myvar
можно двумя способами:
# Define a variable:
bash$ myvar="two words"
# Method one to dereference:
bash$ echo $myvar
two words
# Method two to dereference:
bash$ echo "$myvar"
two words
В случае выше, поведение идентично. Это из-за того, как работает echo
. В других утилитах Unix слияние слов и двойных кавычек будет иметь огромное значение:
bash$ myfile="Cool Song.mp3"
bash$ rm "$myfile" # Deletes "Cool Song.mp3".
bash$ rm $myfile # Tries to delete "Cool" and "Song.mp3".
Мне интересно, каково более глубокое значение этого различия. Самое главное, как я могу точно увидеть, что будет передано команде, чтобы я мог видеть, правильно ли она заключена в кавычки?
Конкретный нечетный пример:
Я просто напишу код с наблюдаемым поведением:
bash$ mydate="--date=format:\"%Y-%m-%d T%H\""
bash$ git log "$mydate" # This works great.
bash$ git log $mydate
fatal: ambiguous argument 'T%H"': unknown revision or path not in the working tree.
Зачем мне двойные кавычки? Что именно видит git-log после разыменования переменной без двойных кавычек?
Но теперь посмотрим на это:
bash$ nospace="--date=format:\"%Y-%m-%d\""
bash$ git log $nospace # Now THIS works great.
bash$ git log "$nospace" # This kind of works, here is a snippet:
# From git-log output:
Date: "2018-04-12"
Фу, почему печатный вывод теперь содержит двойные кавычки? Похоже, что если двойные кавычки не нужны, они не удаляются, они интерпретируются как буквальные символы кавычек тогда и только тогда, когда они не нужны.
Что такое Git в качестве аргумента? Хотел бы я знать, как это выяснить.
Чтобы сделать вещи более сложными, я написал скрипт на Python с использованием argparse
который просто печатает все аргументы (как их интерпретировал Bash, так и с литералами в двойных кавычках, где Bash считает их частью аргумента, и со словами, сгруппированными или не сгруппированными как Bash считает нужным), а скрипт Python argparse
ведет себя очень рационально. К сожалению, я думаю, что argparse
может молча исправлять известную проблему с Bash и, таким образом, скрывать запутанные вещи, которые Bash передает ему. Это всего лишь предположение, я понятия не имею. Может быть, git-log тайно испортит то, что Bash передает ему.
Или, может быть, я просто не знаю, что происходит вообще.
Благодарю.
Отредактировано Редактировать: Позвольте мне сказать это сейчас, прежде чем есть какие-либо ответы: я знаю, что я могу, возможно, использовать одинарные кавычки вокруг всего этого, а затем не избежать двойных кавычек. Это на самом деле работает несколько лучше для моей первоначальной проблемы с использованием git-log, но я протестировал его в некоторых других контекстах, и это примерно так же непредсказуемо и ненадежно. Что-то странное происходит в кавычках внутри переменных. Я даже не собираюсь публиковать все странные вещи, которые произошли с одинарными кавычками.
Редактировать 2 - Это также не работает: у меня только что была эта замечательная идея, но она не работает вообще:
bash$ mydate="--date=format:%Y-%m-%d\ T%H"
bash$ git log "$mydate"
# Git log output has this:
Date: 2018-04-12\ T23
Таким образом, он не имеет кавычек, заключающих его, но имеет буквенный символ обратной косой черты в строке даты. Кроме того, git log $mydate
без ошибок в кавычках с обратным слешем в переменной.