Команда bash multi line с комментариями после символа продолжения

Рассмотрим

echo \ # this is a comment
foo

Это дает:

$ sh foo.sh
 # this is a comment
foo.sh: line 2: foo: command not found

После некоторого поиска в Интернете я нашел решение от DigitalRoss на дочернем сайте Stack Overflow. Таким образом, можно сделать

echo `: this is a comment` \
foo

или, альтернативно,

echo $(: this is a comment) \
foo

Однако DigitalRoss не объяснил, почему эти решения работают. Я был бы признателен за объяснение. Он ответил с комментарием:

  

Раньше была команда goto, которая разветвлялась на метки   указанном как : здесь. goto исчез, но вы все равно можете использовать   : whatever синтаксис ... : является теперь просмотрите комментарий.

Но я хотел бы получить более подробную информацию и контекст, включая обсуждение переносимости.

Конечно, если у кого-то есть другие решения, это тоже хорошо.

См. также более ранний вопрос Как комментировать мульти -line команды в сценариях оболочки? .


Возьмите домашнее сообщение из приведенного ниже обсуждения. `: this is a comment` - это просто замена команды. Вывод : this is a comment ничего, и что помещается вместо `: this is a comment`.

Лучший выбор заключается в следующем:

echo `# this is a comment` \
foo
27 голосов | спросил Faheem Mitha 21 PM00000070000002131 2011, 19:14:21

2 ответа


5

Вы можете добиться этого, используя массивы Bash, например.

#!/bin/bash
CMD=(
  echo  # this is a comment
  foo
  )

"${CMD[@]}"

Это определяет массив, $CMD, а затем расширяет его. После разрастания результирующая строка оценивается, поэтому в этом случае выполняется echo foo.

Текст между ( и ) определяет массив и подчиняется обычному синтаксису bash, поэтому все в строке после # игнорируется.

Примечание о сохранении процитированных пробелов

${CMD[@]} расширяется до строки single , которая является конкатенацией всех элементов, разделенных пробелом , После расширения Bash затем будет разбирать строку в токенах обычным способом (cf $ IFS ) , что часто не то, что мы хотим.

В отличие от этого, если разложение заключено в двойные кавычки, то есть "${CMD[@]}", то каждый элемент массива сохраняется. Рассмотрим разницу между hello world second item и "hello world" "second item".

Иллюстративный пример:

# LIST=("hello world" "second item")

# for ITEM in ${LIST[@]}; do echo $ITEM; done
hello
world
second
item

# for ITEM in "${LIST[@]}"; do echo $ITEM; done
hello world
second item
ответил RobM 5 PMpSun, 05 Apr 2015 19:45:10 +030045Sunday 2015, 19:45:10
4

Не выполняйте $(: comment). Это не комментарий - это подоболочка - еще один новый процесс оболочки для большинства оболочек. Ваша цель состоит в том, чтобы сделать меньше с вашим входом, а не больше, что это будет делать, даже если это бессмысленно.

Вместо этого вы можете сделать ...

printf '<%s>\n' some args here ${-##*"${--

                my long comment block

                }"}  and "more ${-##*"${--

                and another one in the
                middle of the quoted string
                there shouldn\'t b\e any special &
                (character) `echo issues here i hope >&2`
                basically anything that isn\'t a close \}
                $(echo the shell is looking for one >&2)
                }$(echo "}'"\" need backslash escaping >&2
                                )${-##*${--

                nesting is cool though

             }}"}here too"

 }'" need backslash escaping
<some>
<args>
<here>
<and>
<more here too>

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

Здесь:

bash -x <<""
printf %s\\n '${-##*"'${-- a set param doesn\'t expand to this optional text }'"}'

 + printf '%s\n' '${-##*"hxB"}'
${-##*"hxB"}

См? Так что он просто расширен дважды. Как только оболочка обнаружит, что параметр установлен, все в необязательном поле расширения отбрасывается, в значительной степени, и оно расширяется до целого значения, которое удаляется из самого себя и, таким образом, ни к чему вообще. В большинстве оболочек вам не нужно даже избегать кавычек, но требуется bash.

Еще лучше:

COMMENT=
echo      ${COMMENT-"
           this will work the same way
           but the stripping isn\'t
           necessary because, while
           the variable is set, it is also
           empty, and so it will expand to
           its value - which is nothing
           "} this you\'ll see

this you'll see
ответил mikeserv 4 Jam1000000amMon, 04 Jan 2016 05:01:38 +030016 2016, 05:01:38

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132