Читаемые комментарии по отдельным строкам в многострочной команде bash с конвейерами?

14

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

Например, учитывая эту некомментированную многострочную команду (украденную у @DigitalRoss для ясности):

echo abc |
     tr a-z A-Z |
     sort |
     uniq

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

# Perform critical system task.
# NOTE - An example of what does *not* work.
echo abc |
    # Convert lowercase to uppercase.
     tr a-z A-Z |

     # Sort the results.
     sort |

     # Only show unique lines.
     uniq

Существующие связанные ответы кажутся мне неудовлетворительными , а именно:

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

Во-вторых, ответ @Gilles здесь (который использует :) также, похоже, не работает с конвейерной обработкой, потому что он изменяет поток конвейера:

$ echo "abc" | :
$

( ПРИМЕЧАНИЕ . Если есть эквивалент для :того, чтобы передать выходные данные без изменений, это было бы эстетически приемлемо, но я не смог найти его. Я мог бы написать собственный, но это уменьшило бы переносимость.)

Наконец, последняя часть ответа DigitalRoss о StackOverflow хорошо подходит для добавления комментариев в той же строке, но я настоятельно предпочитаю комментарии в отдельных строках. В противном случае, когда строки имеют различную длину, читаемость снижается:

echo abc |         # normal comment OK here`
     /usr/local/bin/really/long/path/ridiculously-long-filename.sh |  # another normal comment OK here
     sort |        # the pipelines are automatically continued
     uniq          # final comment

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

Ройс Уильямс
источник
1
Примечание о ваших комментариях: меня учили писать комментарии, поясняющие раздел или единицу работы. Если опытный программист пишет интеллектуальные комментарии, описывающие то, что он делает, то, вероятно, любой, кто придет вместе со сценарием, всегда может использовать справочные страницы, если они не понимают деталей использования. Никогда не следует писать комментарии, как i++; // increment i by one. Я предлагаю вам прочитать "Элементы стиля программирования"
BSD
Я думаю, что я собираюсь удалить последнее редактирование. Для вопроса необычно содержать вопрос, опровержения ответов и сам ответ, но часть, которая объясняет, почему другие ответы не работают, здесь необходима. Ответ rozcietrzewiacz и ваш комментарий вместе объясняют проблему, хотя (лично я бы опубликовал отдельный ответ и принял его, так как проблема довольно сильно отличалась от того, что он описал, но это работает)
Майкл Мрозек
Понял - спасибо за отзыв; урок выучен!
Ройс Уильямс

Ответы:

14

Как насчет этого?

echo abc | \
# Convert lowercase to uppercase.
tr a-z A-Z | \

# Sort the results.
sort | \

# Only show unique lines.
uniq

(Обратная черта должна использоваться как последний символ в этих строках.) Я не уверен в переносимости этого подхода, но он точно работает с текущей bash.

rozcietrzewiacz
источник
Ага! (facepalm) Я преобразовал идиому, которую я фактически использовал, отправляя вопрос, не понимая этого! Я помещал канал в начало каждой строки, и я с радостью перестал это делать, поскольку теперь я знаю, что этот метод хорошо работает на всех системах, к которым я могу подключиться, как в bash, так и в sh. Благодарность!
Ройс Уильямс
Не разрушат ли эти комментарии продолжение строки?
Стюарт П. Бентли
Пока перед каждым комментарием есть пустая строка, он работает нормально.
Ройс Уильямс