Способ создания многострочных комментариев в Bash?


226

Недавно я начал изучать сценарий оболочки, и я хотел бы иметь возможность закомментировать ряд строк в сценарии оболочки. Я имею в виду, как в случае с C / Java:

/* comment1
   comment2 
   comment3
*/`

Как я мог это сделать?


2
Вы можете использовать хеш как: # это комментарий.
Мохаммад Тайяб

1
Я знаю, но это немного хлопотно для мультилинии.
Энес Малик Турхан

2
Следует отметить, что приведенные ниже ответы требуют, чтобы они :были в первом столбце (без начальных пробелов) в строке.
ти

Ответы:


394

Используйте, : 'чтобы открыть и 'закрыть.

Например:

: '
This is a
very neat comment
in bash
'

27
:( а также добавляет большое количество не читаемых способностей и потенциальных источников ошибок. ИМХО лучше просто использовать несколько #s и никогда этого ...
jm666

51
@ jm666 ИМХО Никогда не стоит использовать это слово никогда, когда вы не знаете всех вариантов использования.
зима

19
объяснить: :это сокращение для trueи trueне обрабатывает никаких параметров. (справочная страница:SYNOPSIS true [ignored command line arguments]
phil294

46
Пространство между :и 'важно
Becko

23
Я немного изменил это для блоков кода, чтобы я мог легко включить или выключить код. Мое изменение заключается в использовании # 'в последней строке вместо одинарной кавычки. Таким образом, я могу поставить один #в первой строке, чтобы активировать блок кода. Удалите #первую строку, чтобы деактивировать код.
JohnMudd

131

Многострочный комментарий в bash

: <<'END_COMMENT'
This is a heredoc (<<) redirected to a NOP command (:).
The single quotes around END_COMMENT are important,
because it disables variable resolving and command resolving
within these lines.  Without the single-quotes around END_COMMENT,
the following two $() `` commands would get executed:
$(gibberish command)
`rm -fr mydir`
comment1
comment2 
comment3
END_COMMENT

4
Это работает, в настоящее время принятого ответа нет (для меня).
Фрик

5
Вероятно, стоит отметить, что это не комментарий как таковой. Это heredoc, который перенаправляется на команду NOP в виде многострочной строки. Одиночная кавычка важна для отключения разрешения переменных и команд.
Nux

1
@Freek нужно добавить пробел
лабиринты

Я проверил это в простом скрипте bash, который запускается через строку shebang, #! / Bin / bash в Debian, и это не удалось. Я пробую каждый ответ на этой странице, и все они терпели неудачу, пока я не добрался до следующего. Так как они потерпели неудачу, я голосую против них, и голосую за тот, который действительно работает должным образом.
PyTis

1
Хорошие тесты в вашем примере. Ведущий :не нужен. Просто начни с <<.
Висбуки

34

Я обновляю этот пост на основе комментариев и других ответов, поэтому комментарии до 22 мая 2020 года могут больше не применяться.

Bash не предоставляет встроенный синтаксис для многострочного комментария, но есть хаки, использующие существующий синтаксис bash, который «работает сейчас».

Лично я думаю, что самый простой (то есть наименее шумный, наименее странный, самый простой в наборе, наиболее явный) - это использовать цитируемый HEREDOC, но сделать очевидным, что вы делаете, и везде использовать один и тот же маркер HEREDOC:

<<'### BLOCK COMMENT'
line 1
line 2

line 3
line 4
### BLOCK COMMENT

Одиночные кавычки маркера HEREDOC позволяют избежать некоторых побочных эффектов синтаксического анализа оболочки, таких как странные ситуации, которые могут вызвать сбой или вывод, и даже анализ самого маркера. Таким образом, одинарные кавычки дают вам больше свободы для маркера комментариев открытия-закрытия. Например, следующее использует тройной хеш, который предлагает многострочный комментарий в bash. Это может привести к сбою сценария, если одинарные кавычки отсутствуют. Даже если вы удалите ###, FOO{}сценарий будет аварийно завершен (или приведет к неправильной замене, если нет set -e), если бы не одиночные кавычки:

set -e

<<'### BLOCK COMMENT'
something something ${FOO{}} something
more comment
### BLOCK COMMENT

ls

Вы могли бы, конечно, просто использовать

set -e

<<'###'
something something ${FOO{}} something
more comment
###

ls

но цель этого определенно менее ясна для читателя, незнакомого с этим обманом.

В настоящее время любой хороший редактор позволяет вам нажать ctrl- / или подобный, чтобы отменить / прокомментировать выбор. Все определенно понимают это:

# something something ${FOO{}} something
# more comment
# yet another line of comment

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

Конечно, есть и другие методы, но, похоже, не существует «обычного» способа сделать это. Было бы хорошо, если бы ###>и ###<можно было добавить к bash, чтобы указать начало и конец блока комментариев, кажется, что это может быть довольно просто.


1
Ах, это легко / чисто достаточно запомнить!
Тамме Говда

1
Как отмечено в предыдущем ответе, помимо обратных кавычек, последовательность $ (...) также будет расширена, поскольку обе формы являются подстановкой команд.
Perl Ancar

«Оба взломаны, поэтому они могут нарушать сценарии в будущем». Не могли бы вы расширить это? Хотя взломы семантически, синтаксически они действительны и не должны сломаться в будущем, если только bash не решит сходить с ума и не сломает наследственность.
Perl Ancar

@perlancar Если мы согласны с тем, что хаки - это решения, использующие функцию языка / библиотеки, которая совершенно не связана с проблемой (например, использование heredoc для комментария или использование параметра в команде типа «ничего не делать» true), то даже если они не не рискует нарушить (подход heredoc не делает, но версия с двоеточием делает это), 1) хаки по-прежнему запутывают намерение: без первой строки, намекающей на многострочный комментарий, большинство поцарапало бы голову, задаваясь вопросом, что делает этот код; и 2) иметь неожиданные темные углы (например, двойная кавычка, кавычка маркера heredoc в некоторых случаях и т. д.).
Оливер

@Oliver: Если без кавычек, переменные могут иметь неприятные побочные эффекты. Представьте, что вы включили в свой heredoc комментарий, например, ${FOO:=bar}или ${FOO{}}. Первый может иметь побочный эффект для создания и установки переменной FOO, второй вызовет ошибку неправильной замены ; Оба эффекта вы не ожидаете от реального комментария.
user1934428

24

Прочитав другие ответы здесь, я придумал ниже, что IMHO дает понять, что это комментарий. Особенно подходит для использования в скрипте:

<< ////

Usage:
This script launches a spaceship to the moon. It's doing so by 
leveraging the power of the Fifth Element, AKA Leeloo.
Will only work if you're Bruce Willis or a relative of Milla Jovovich.

////

Как программист, последовательность косых черт сразу же записывается в моем мозгу как комментарий (хотя косые черты обычно используются для строчных комментариев).

Конечно, "////"это просто строка; количество косых черт в префиксе и суффиксе должно быть одинаковым.


3
Я почти пропустилUsage:
РНК

Отличное дополнение к ответу выше. Честно говоря, я думаю, что вы могли бы отредактировать приведенный выше ответ и добавить его вместо того, чтобы отвечать отдельно.
PyTis

Есть несколько «выше» ответов (в зависимости от вашего порядка сортировки). И, отвечая отдельно, я хотел объяснить обоснование выбранной строки.
noamtm

<< EOF ... EOF
L Минчжи

5

что вы думаете об этом?

function giveitauniquename()
{
  so this is a comment
  echo "there's no need to further escape apostrophes/etc if you are commenting your code this way"
  the drawback is it will be stored in memory as a function as long as your script runs unless you explicitly unset it
  only valid-ish bash allowed inside for instance these would not work without the "pound" signs:
  1, for #((
  2, this #wouldn't work either
  function giveitadifferentuniquename()
  {
    echo nestable
  }
}

привет, не был задуман как вопрос, а не как ответ на первоначальный вопрос
Imre

Не хорошо ИМО. Требуется, чтобы комментарий был анализируемым как шелл-код, что довольно ограничительно.
user1934428

3

Вот как я делаю многострочные комментарии в bash.

У этого механизма есть два преимущества, которые я ценю. Во-первых, комментарии могут быть вложенными. Другое - блоки можно включить, просто закомментировав начальную строку.

#!/bin/bash
# : <<'####.block.A'
echo "foo {" 1>&2
fn data1
echo "foo }" 1>&2
: <<'####.block.B'
fn data2 || exit
exit 1
####.block.B
echo "can't happen" 1>&2
####.block.A

В приведенном выше примере блок «B» закомментирован, но части блока «A», которые не являются блоком «B», не закомментированы.

Выполнение этого примера приведет к следующему выводу:

foo {
./example: line 5: fn: command not found
foo }
can't happen

3

Я попробовал выбранный ответ, но обнаружил, что при запуске сценария оболочки, имеющего его, все это выводилось на экран (аналогично тому, как на ноутбуках jupyter все выводилось в '''xx'''кавычках), и в конце появлялось сообщение об ошибке. Он ничего не делал, но: страшно . Тогда я понял, редактируя его, что одинарные кавычки могут занимать несколько строк. Итак ... давайте просто назначим блок переменной.

x='
echo "these lines will all become comments."
echo "just make sure you don_t use single-quotes!"

ls -l
date

'

Просто нет необходимости присваивать его переменной, что является побочным эффектом, который мы не ожидаем от «комментария». Замените на x=a, : и вы получите тот же эффект без побочных эффектов. Единственным недостатком является то, что комментарий не должен содержать ни одной кавычки. Вот почему я предпочитаю использовать процитированный heredoc: так комментатор может выбрать подходящую строку завершения, как ему нравится.
user1934428

2

Простое решение, не слишком умное:

Временно заблокировать часть скрипта:

if false; then
    while you respect syntax a bit, please
    do write here (almost) whatever you want.
    but when you are
    done # write
fi

Немного сложная версия:

time_of_debug=false # Let's set this variable at the beginning of a script

if $time_of_debug; then # in a middle of the script  
    echo I keep this code aside until there is the time of debug!
fi

-2

# Мне нравится лень и простота. Я бы использовал # с забавным обходным решением:

1 НАЖМИТЕ:] find ctrl + F или cmd + F или что-то еще [чтобы активировать функцию поиска

2 используйте регулярное выражение в поле поиска, например: (^.+)

3 заменить на: # $1или, если вы предпочитаете#$1


# Примечание: у вас может не быть трех шагов в вашем редакторе. В этом случае используйте онлайн-инструмент для регулярных выражений (не могу предложить его здесь по соображениям политики):

  1. Выберите, скопируйте текст, где бы вы ни находились, и вставьте его в онлайн-инструмент регулярных выражений.
  2. Использовать (^.+)как регулярное выражение и / #$1или #\1как шаблоны замещения
  3. Выберите, скопируйте текст и вставьте его туда, где вы начали

# Наслаждайтесь вашими хэшами!


В наши дни многие редакторы имеют горячую клавишу, ctrl+/которая включает или выключает комментарии, даже для нескольких строк. Он также может изменить символ комментария в зависимости от того, какой язык вы используете.
ninMonkey
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.