Почему трюки со строками комментариев для bash не работают с восклицательным знаком "!" - PullRequest
2 голосов
/ 11 февраля 2020

ref Встроенные комментарии для Bash?

Мы можем использовать эти уловки

echo abc `#put your comment here` \
     def `#another chance for a comment` \
     xyz etc

, но они не работают, если у нас есть восклицательный знак в комментарии

echo 1 `# 2 !3`
<error>
-bash: !3: event not found

если мы введем его напрямую, он не будет переведен в событие

# 2 !3
<that is OK>

Это говорит о том, что нам нужен другой символ # для его обхода.

echo 1 `# 2 #!3`
<that is OK>
1

или мы должны удвоить ведущий символ #?

echo 1 `# # 2 !3`
<that is OK>
1

1 Ответ

2 голосов
/ 15 февраля 2020
  1. # !xxx

    Это работает, как и ожидалось, потому что ! в комментарии.

  2. echo # !xxx

    Это также работает как ожидалось, потому что ! также находится в комментарии.

  3. echo `true # !xxx`

    Это также работает, потому что ! все еще находится в комментарии хотя это в контексте `...`.

  4. echo `# !xxx`

    Почему это не работает?
    Полагаю, есть небольшая ошибка когда Bash интерпретирует часть `...`. В `...`, Bash всегда предполагает (неправильно), что first WORD является именем КОМАНДЫ, поэтому он не думает, что ! находится в комментарии, и, таким образом, происходит расширение истории. То есть echo `# !xxx` - это как echo `COMMAND !xxx`.

  5. echo `# # !xxx`

    Почему это работает?
    Как объяснено в # 4 , первый # анализируется как КОМАНДА, поэтому он похож на echo `COMMAND # !xxx`, поэтому теперь ! в комментарии.

  6. echo `## !xxx`

    Этот двойной га sh тоже не работает.
    Как объяснено в # 4 и # 5 , здесь ## - это первое СЛОВО, и оно анализируется как имя КОМАНДЫ, поэтому оно также выглядит как echo `COMMAND !xxx`.

Обратите внимание, что в контексте `...` ошибка присутствует только в синтаксисе первого раунда парсер . То есть, хотя Bash первоначально анализирует # как имя КОМАНДЫ, он на самом деле не запускает его как команду с именем #.


ОБНОВЛЕНИЕ 2020-03- 04

Вышеприведенное объяснение оказалось НЕПРАВИЛЬНЫМ , хотя и объясняло все. Пожалуйста, смотрите обсуждение в bug- bash список рассылки .

Я бы процитировал объяснение Чета здесь для легкой ссылки:

> $ set -H
> $ true `# !xxx`
> bash: !xxx`: event not found

Хорошо, символ комментария к истории (#) не найден в начале слова, поэтому остальная часть строки обрабатывается для расширения истории.

$ true `# # !xxx`

Символ комментария к истории находится в начале расширение слова и истории пропускает остальную часть строки.

Расширение истории чтения строки очень мало знает о синтаксисе оболочки; в частности, он не знает обратных кавычек. Этого никогда не было.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...