Jak utworzyć wieloliniowe komentarze w Bash?

225

Niedawno zacząłem studiować skrypt powłoki i chciałbym móc komentować zestaw wierszy w skrypcie powłoki. Mam na myśli, że tak jest w przypadku C / Java:

/* comment1
   comment2 
   comment3
*/`

Jak mogłem to zrobić?

Enes Malik Turhan
źródło
2
Możesz użyć skrótu: # to jest komentarz.
Mohammad Tayyab
1
Wiem, ale dla multilinii jest to trochę kłopotliwe.
Enes Malik Turhan
2
Należy zauważyć, że poniższe odpowiedzi wymagają, aby :znajdować się w pierwszej kolumnie (bez spacji wiodących) w wierszu.
ty

Odpowiedzi:

393

Użyj, : 'aby otworzyć i 'zamknąć.

Na przykład:

: '
This is a
very neat comment
in bash
'
Vegas
źródło
27
:( a także dodaje dużą liczbę możliwości braku możliwości odczytu i potencjalnego źródła błędów. IMHO lepiej po prostu użyć wielu #s, a nigdy tego ...
jm666
51
@ jm666 IMHO Nigdy nie warto używać tego słowa nigdy, gdy nie masz pojęcia o wszystkich przypadkach użycia.
Zima
19
wyjaśnić: :jest skrótem truei truenie przetwarza żadnych parametrów. (strona podręcznika:SYNOPSIS true [ignored command line arguments]
phil294
46
Przestrzeń między :i 'jest ważna
becko
23
Zmodyfikowałem to nieco dla bloków kodu, dzięki czemu mogę łatwo włączyć lub wyłączyć kod. Moją zmianą jest użycie # 'w ostatnim wierszu zamiast pojedynczego cudzysłowu. W ten sposób mogę umieścić pojedynczy #wiersz w pierwszym wierszu, aby aktywować blok kodu. Usuń #pierwszy wiersz, aby dezaktywować kod.
JohnMudd,
131

Komentarz wieloliniowy w 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
David Okwii
źródło
4
To działa, obecnie zaakceptowana odpowiedź nie (dla mnie).
Freek
5
Prawdopodobnie warto zauważyć, że nie jest to komentarz jako taki. Jest to heredok przekierowany do komendy NOP jako ciąg wieloliniowy. Pojedynczy cytat jest ważny, aby wyłączyć rozwiązywanie zmiennych i poleceń.
Nux
1
@ Freek trzeba dodać spację
labirynty
Przetestowałem to w prostym skrypcie bash, który działa w linii shebang, #! / Bin / bash w Debianie i nie powiodło się. Próbuję każdej odpowiedzi na tej stronie i wszystkie one zawiodły, dopóki nie dotarłem do poniższej. Ponieważ ponieśli porażkę, głosuję w ich głosie w dół i głosuję w górę na ten, który faktycznie działa poprawnie.
PyTis,
1
Dobre testy w twoim przykładzie. Prowadzenie :nie jest konieczne. Po prostu zacznij od <<.
wisbucky,
34

Aktualizuję ten post na podstawie komentarzy i innych odpowiedzi, więc komentarze sprzed 22 maja 2020 roku mogą już nie mieć zastosowania.

Bash nie zapewnia wbudowanej składni komentarzy wieloliniowych, ale istnieją hacki wykorzystujące istniejącą składnię bash, która „działa teraz”.

Osobiście uważam, że najprostszym (tj. Najmniej hałaśliwym, najmniej dziwnym, najłatwiejszym do pisania, najbardziej wyraźnym) jest użycie cytowanego HEREDOC, ale wyraź to, co robisz, i używaj tego samego markera HEREDOC wszędzie:

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

line 3
line 4
### BLOCK COMMENT

Pojedynczy cytat znacznika HEREDOC pozwala uniknąć niektórych skutków ubocznych analizy powłoki, takich jak dziwne zmiany, które spowodowałyby awarię lub wynik, a nawet analizę samego markera. Tak więc pojedyncze cudzysłowy dają więcej swobody na znaczniku komentarza „otwórz i zamknij”. Na przykład poniżej używa potrójnego skrótu, który sugeruje wieloliniowy komentarz w bash. Spowodowałoby to awarię skryptu, gdyby pojedyncze cytaty były nieobecne. Nawet jeśli usuniesz ###, FOO{}spowoduje to awarię skryptu (lub spowoduje wydrukowanie złej substytucji, jeśli nie set -e), gdyby nie pojedyncze cytaty:

set -e

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

ls

Oczywiście możesz po prostu użyć

set -e

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

ls

ale cel tego jest zdecydowanie mniej jasny dla czytelnika niezaznajomionego z tą sztuczką.

Obecnie każdy dobry edytor pozwala nacisnąć Ctrl- / lub podobny, aby anulować / skomentować wybór. Wszyscy na pewno to rozumieją:

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

chociaż wprawdzie nie jest to tak wygodne jak powyższy komentarz blokowy, jeśli chcesz ponownie wypełnić akapity.

Z pewnością istnieją inne techniki, ale wydaje się, że nie ma „konwencjonalnego” sposobu na zrobienie tego. Byłoby miło, gdyby ###>i ###<mógł zostać dodany do bash, aby wskazać początek i koniec bloku komentarza, wydaje się, że może być całkiem prosty.

Oliver
źródło
1
Ach, ten jest łatwy / czysty, aby zapamiętać!
Thamme Gowda
1
Jak zaznaczono w poprzedniej odpowiedzi, oprócz cudzysłowów, sekwencja $ (...) również zostanie rozwinięta, ponieważ obie formy zastępują polecenia.
Perl Ancar 15.01.2019
„Oba są hackami, aby w przyszłości mogły łamać skrypty”. Czy możesz to rozwinąć? Chociaż hakują semantycznie, pod względem składniowym są poprawne i nie powinny się w przyszłości łamać, chyba że bash zdecyduje się na szał i złamie heredoki.
Perl Ancar 15.01.2019
@perlancar Jeśli zgadzamy się, że hacki są rozwiązaniami, które wykorzystują funkcję języka / lib, która jest całkowicie niezwiązana z problemem (jak użycie heredoc do komentarza lub użycie parametru w poleceniu „nic nie rób” true), to nawet jeśli nie nie ryzykuje złamania (podejście heredoc nie, ale wersja dwukropka robi), 1) włamania wciąż zaciemniają zamiar: bez pierwszej linii sugerującej komentarz wielowierszowy, większość drapałaby się po głowie zastanawiając się, co robi ten kod; i 2) mają nieoczekiwane ciemne rogi (np. konieczność podwojenia cudzysłowu, w niektórych przypadkach cytowanie markera heredoc itp.).
Oliver
@Oliver: Jeśli nie są cytowane, zmienne mogą mieć nieprzyjemne skutki uboczne. Wyobraź sobie, że umieściłeś w swoim heredoc- komentarzu ciąg taki jak ${FOO:=bar}lub ${FOO{}}. Pierwszy może wywoływać efekt uboczny tworzenia i ustawiania zmiennej FOO, drugi wywoła zły błąd podstawienia ; oba efekty, których nie można oczekiwać od prawdziwego komentarza.
user1934428
24

Po przeczytaniu innych odpowiedzi tutaj wymyśliłem poniżej, co według IMHO jest naprawdę jasne, że to komentarz. Szczególnie nadaje się do informacji o użyciu w skrypcie:

<< ////

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.

////

Jako programista sekwencja ukośników natychmiast rejestruje się w moim mózgu jako komentarz (nawet jeśli ukośniki są zwykle używane w komentarzach liniowych).

Oczywiście "////"to tylko struna; liczba ukośników w prefiksie i sufiksie musi być równa.

noamtm
źródło
3
Prawie mi brakowałoUsage:
RNA,
Świetny dodatek do powyższej odpowiedzi. Szczerze mówiąc, myślę, że mogłeś zredagować powyższą odpowiedź i dodać ją, zamiast odpowiadać osobno.
PyTis,
Istnieje kilka „powyższych” odpowiedzi (w zależności od kolejności sortowania). Odpowiadając osobno, chciałem wyjaśnić uzasadnienie wybranego przeze mnie łańcucha.
noamtm
<< EOF ... EOF
l mingzhi,
5

jakie jest twoje zdanie na ten temat?

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
źródło
cześć, nie było zamierzone jako pytanie, a nie odpowiedź na pierwotne pytanie
Imre
Nie dobre IMO. Wymaga to parsowania komentarza jako kodu powłoki, co jest dość restrykcyjne.
user1934428
3

Oto jak robię komentarze wieloliniowe w bash.

Ten mechanizm ma dwie zalety, które doceniam. Jednym z nich jest to, że komentarze można zagnieżdżać. Drugim jest to, że bloki można włączyć, po prostu komentując linię inicjującą.

#!/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

W powyższym przykładzie blok „B” jest komentowany, ale części bloku „A”, które nie są blokiem „B”, nie są komentowane.

Uruchomienie tego przykładu spowoduje wygenerowanie tego wyniku:

foo {
./example: line 5: fn: command not found
foo }
can't happen
Bugi
źródło
3

Wypróbowałem wybraną odpowiedź, ale okazało się, że kiedy uruchomiłem skrypt powłoki, wszystko było drukowane na ekranie (podobnie jak w notatnikach jupyter drukuje wszystko w '''xx'''cudzysłowie) i na końcu pojawił się komunikat o błędzie. Nie robił nic, ale: przerażający . Podczas edycji zdałem sobie sprawę, że pojedyncze cudzysłowy mogą obejmować wiele wierszy. Więc .. po prostu przypiszmy blok do zmiennej.

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

ls -l
date

'
Nikhil VJ
źródło
Po prostu nie trzeba przypisywać jej do zmiennej, co jest efektem ubocznym, którego nie spodziewalibyśmy się po „komentarzu”. Zamień na x=a, : a uzyskasz ten sam efekt bez efektu ubocznego. Jedyną wadą jest to, że komentarz nie może zawierać ani jednego cytatu. Dlatego wolę używać cytowanego heredoc: Dzięki temu komentator może wybrać odpowiedni ciąg terminacji, jak mu się podoba.
user1934428
2

Proste rozwiązanie, mało inteligentne:

Tymczasowo zablokuj część skryptu:

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

Trochę wyrafinowana wersja:

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
kserostomus
źródło
-2

# Lubię lenistwo i prostotę. Użyłbym # ze śmiesznym obejściem:

1 NACIŚNIJ:] znajdź ctrl + F lub cmd + F lub cokolwiek [, aby uruchomić funkcję wyszukiwania

2 użyj wyrażenia regularnego w polu wyszukiwania, np .: (^.+)

3 zamień na: # $1lub jeśli wolisz#$1


# Uwaga: możesz nie mieć trzech kroków w swoim edytorze. W takim przypadku skorzystaj z internetowego narzędzia do wyrażania regularnego (nie możesz zasugerować go tutaj ze względów politycznych):

  1. Wybierz, skopiuj tekst gdziekolwiek jesteś i wklej go w internetowym narzędziu regex
  2. Użyj (^.+)jako wyrażeń regularnych i / #$1lub #\1jako wzorców podstawienia
  3. Wybierz, skopiuj tekst i wklej go z powrotem w miejscu rozpoczęcia

# Baw się dobrze!

AMDP
źródło
Obecnie wielu redaktorów ma klawisz skrótu, ctrl+/który włącza lub wyłącza komentarze, nawet dla wielu wierszy. Jest również w stanie zmienić znak komentarza w zależności od używanego języka.
ninMonkey