Wyświetlanie komentarzy użytkowania w funkcjach przeznaczonych do użycia interaktywnego

11

Mam wiele zdefiniowanych funkcji .bashrc, które mają być interaktywnie używane w terminalu. Zazwyczaj poprzedzałem je komentarzem opisującym jego zamierzone użycie:

# Usage: foo [bar]
# Foo's a bar into a baz
foo() {
  ...
}

Jest to dobre, jeśli przeglądasz kod źródłowy, ale dobrze jest uruchomić typew terminalu, aby szybko przypomnieć o tym, co robi ta funkcja. Jednak (co zrozumiałe) nie obejmuje komentarzy:

$ type foo
foo is a function
foo ()
{
    ...
}

Co sprawiło, że pomyślałem: „czy nie byłoby miło, gdyby tego rodzaju komentarze trwały, aby typemogły zostać wyświetlone?” I w duchu Pythona docstrings wymyśliłem to:

foo() {
  : Usage: foo [bar]
  : "Foo's a bar into a baz"
  ...
}

$ type foo
foo is a function
foo ()
{
    : Usage: foo [bar];
    : "Foo's a bar into a baz";
    ...
}

Teraz użycie jest uwzględnione w danych typewyjściowych! Oczywiście, jak widać, cytowanie staje się problemem, który może być podatny na błędy, ale jest przyjemniejszy dla użytkownika, gdy działa.

Moje pytanie brzmi: czy to okropny pomysł? Czy są lepsze alternatywy (takie jak funkcje a man/ infofor) dla zapewnienia użytkownikom funkcji Bash dodatkowego kontekstu?

Idealnie nadal chciałbym, aby instrukcje użycia znajdowały się w pobliżu definicji funkcji, aby ludzie przeglądający kod źródłowy również skorzystali, ale jeśli istnieje „właściwy” sposób na zrobienie tego, jestem otwarty na alternatywy.

Edytuj to wszystkie dość proste funkcje w stylu pomocnika, a ja po prostu chcę interaktywnie uzyskać dodatkowy kontekst. Z pewnością w przypadku bardziej złożonych skryptów, które analizują flagi, dodałbym --helpopcję, ale dla nich byłoby trochę uciążliwe dodawanie flag pomocy do wszystkiego. Być może to tylko koszt, który powinienem zaakceptować, ale ten :hack wydaje się działać całkiem dobrze, nie czyniąc źródła o wiele trudniejszym do odczytania naszej edycji.

dimo414
źródło

Odpowiedzi:

8

Nie sądzę, że jest tylko jeden dobry sposób, aby to zrobić.

Wiele funkcji, skryptów i innych plików wykonywalnych zawiera komunikat pomocy, jeśli użytkownik udostępnia -hlub --helpjako opcję:

$ foo() {
[[ "$1" =~ (-h|--help) ]] && { cat <<EOF
Usage: foo [bar]
Foo's a bar into a baz
EOF
return;
}
: ...other stuff...
}

Na przykład:

$ foo -h
Usage: foo [bar]
Foo's a bar into a baz

$ foo --help
Usage: foo [bar]
Foo's a bar into a baz
John1024
źródło
Tak, powinienem o tym wspomnieć. Są to proste funkcje i staram się unikać ich nadmiernej złożoności. Dla poleceń, które zasługują na parsowanie flag, z pewnością dodam --helpopcję.
dimo414,
W programowaniu spójność jest zaletą. Zależy to również od tego, co rozumiesz przez „kompleks”.
John1024,
I twoje podejście jest sprytne i dobre (a twoje pytanie ma już moje +1).
John1024,
1
Dzięki; twoja implementacja --helpjest również nieinwazyjna, co moim zdaniem jest moim głównym kryterium w tym przypadku. Mogę skończyć z tą :sztuczką, ponieważ bardziej pasuje ona do mojego przypadku użycia, ale doceniam, że zauważyłeś, że nie jest trudno ją wspierać --helpi że większość użytkowników będzie tego oczekiwać.
dimo414,
1
+1. Zamierzałem odpowiedzieć „użyj getopts”, ale działa to wystarczająco dobrze, jeśli nie ma innych opcji. jeśli funkcja ma inne opcje, użyj getopts.
cas
0

Nigdy do końca nie przekonałem się, aby pogrążyć się i używać :poleceń jako komentarzy pseduo. W szczególności zawsze martwiłem się tym, że „komentarze” są w rzeczywistości argumentami, które podlegają ocenie i mogą potencjalnie mieć skutki uboczne (lub po prostu popsuć rzeczy, takie jak błąd '). Wciąż podoba mi się prostota tego pomysłu, ale nigdy nie uznałem tego kompromisu za całkiem uzasadniony.

Moje wahanie z dostarczeniem tekstu użycia za pomocą --helpflagi lub podobnego zawsze było cruft, który się z tym wiąże. Gdy tylko zaczniesz akceptować flagi, szybko zaczniesz analizować argumenty, co zwykle (w Bash) wymaga całkiem sporej liczby szablonów .

Aby częściowo wypełnić tę lukę, zebrałem razem małe narzędzie, które owija się getoptsw celu zmniejszenia tej płyty kotłowej. Nadal zajmuje kilka linii, więc nie używałbym jej w innych drobnych funkcjach, ale jest o wiele bardziej zwięzły niż getoptsbezpośrednie. Oto przykład użycia z -hflagą ( getoptsobsługuje tylko opcje jednoliterowe):

foo() {
  local _usage='foo [-a] [-b] [-f val] [-v val] [args ...]'
  eval "$(parse_opts 'f:v:abh')"
  if (( h )); then
    echo "Usage: $_usage"
    return 0
  fi
  echo "f=$f v=$v a=$a b=$b -- $#: $*"
}
dimo414
źródło