Jakie są praktyczne różnice między Bash i Zsh?

Po wiadomościach, że Catalina domyślnie ustawi Zsh zamiast Bash , znalezienie wielu wyników mówiących o przełączniku i że może powodować problemy ze skryptami powłoki, ale nie jestem wystarczająco zaznajomiony z Zsh, aby wiedzieć, jakie mogą być te problemy.

Moje skrypty powłoki naprawdę nie są to skomplikowane, ale używałem Bash tylko na macOS i Linuksie – zero doświadczenia z Zsh. Czy ktoś może podać proste, praktyczne porównanie lub konkretne przeszkody, które będę musiał znać, abym mógł zacząć pracować nad przygotowaniem się na nowa powłoka, gdy Catalina zostanie wydana?

Komentarze

  • Całe to zamieszanie, które czytałeś, to wiele do zrobienia z niczym. System operacyjny przypisuje ” domyślna ” powłoka podczas tworzenia nowych użytkowników, nie ma powodu. Bash isn ' t iść odejść i możesz użyć tego jako swojej powłoki lub dowolnej innej powłoki c aktualnie oferowane.
  • Mówienie jak ktoś, kto ' używał obu i wylądował na bash – jedyną rzeczą, która sprawiła, że byłem naprawdę bardzo niezadowolony z zsh, była jego decyzja złamać zgodność z POSIX, gdy standard kanonizuje wprawdzie złe decyzje projektowe w sposób, który ułatwiał rozmyślanie o poprawności podczas pisania skryptów, które musiały być kompatybilne z innymi, ściśle zgodnymi z POSIX powłokami supersetowymi. Niestety, ta ” jedyna rzecz ” może być całkiem duża. Mimo to, ksh93 nie ' nie odchodzi, a każdy, kto poważnie myśli o bashu, i tak nie użyłby ' starszej wersji 3.x dostarczanej przez Apple.
  • W ramach kontynuacji – zainstalowałem Catalinę wczoraj, przełączyłem się na zsh, zaimportowałem bash_history i skopiowałem niektóre z moich preferowanych aliasów z bash_profile. Wygląda na to, że nic się nie zepsuło. Doceń wszystkie informacje dostarczone przez wszystkich tutaj i miejmy nadzieję, że pomoże to również innym.
  • @CharlesDuffy: Dobry komentarz. WRT jest ” poważnym ” i używa bash version 3.2.57(1): czy wiesz, czy Apple używa bash na cokolwiek ” ważne ” w systemie?

Odpowiedź

Po pierwsze, kilka ważnych rzeczy:

  1. Bash nie odchodzi . Jeśli już „używasz basha, nic się dla ciebie nie zmieni. Jedyną zmianą jest to, że zsh będzie domyślną powłoką logowania dla nowych kont, a nawet wtedy możesz zamiast tego wybrać bash.
  2. Nie dotyczy to skryptów . Jakie zmiany to powłoka do użytku interaktywnego, tj. Powłoka w terminalach (a także kilka innych rzeczy, które używają powłoki logowania, takich jak crontab). Jeśli masz skrypt w pliku z uprawnieniami do wykonywania, zaczynając od linii shebang , na przykład #!/bin/bash lub #!/bin/sh lub #!/usr/bin/env bash, będzie działać dokładnie tak, jak poprzednio.
  3. Składnia Zsh nie jest w pełni zgodna z bash , ale już blisko. Wiele kodu będzie nadal działać, na przykład typowe aliasy i funkcje. Główne różnice dotyczą interaktywnych funkcji konfiguracyjnych.

Zakładając, że „rozważasz zmianę do zsh, co było możliwe od lat, oto główne różnice, które napotkasz. To nie jest wyczerpująca lista!

Główne różnice w zastosowaniu interaktywnym

Pliki konfiguracyjne : odczyty bash (głównie) .bashrc w powłokach interaktywnych bez logowania (ale macOS domyślnie uruchamia powłokę logowania w terminalach), .profile lub w powłokach logowania i .inputrc. Zsh czyta (głównie) .zshrc (we wszystkich powłokach interaktywnych) i .zprofile (w powłokach logowania). Oznacza to, że żadne z Twoich dostosowań basha nie będzie miało zastosowania: „będziesz musiał je przenieść. Nie możesz” po prostu skopiować plików, ponieważ wiele rzeczy będzie wymagało poprawienia.

Klawisze używają zupełnie innej składni. Bash używa .inputrc i bind wbudowanego do powiązania kluczy z polecenia readline . Zsh używa bindkey wbudowanego do wiązania klawiszy z widżetami zle . Większość poleceń readline ma odpowiednik zsh, ale nie zawsze jest to idealny odpowiednik.

Mówiąc o przypisaniach klawiszy, jeśli używasz Vi (m) jako edytora w terminalu, ale nie jako trybu linii poleceń w powłoce, zauważysz, że domyślnym trybem edycji zsh jest vi, jeśli EDITOR lub VISUAL jest ustawione na vi lub vim . bindkey -e przełącza się na tryb emacs.

Monituj : bash ustawia podpowiedź (głównie) z PS1 , który zawiera odwrotny ukośnik oznacza . Zsh ustawia znak zachęty głównie z PS1 , który zawiera procent zmiany znaczenia . Funkcjonalność bash” s PROMPT_COMMAND jest dostępna w zsh przez precmd i preexec funkcje podpięcia . Zsh ma więcej wygodnych mechanizmów do tworzenia wymyślnych podpowiedzi, w tym mechanizm motywu podpowiedzi .

Podstawowy historia wiersza poleceń mechanizmy (nawigacja za pomocą W górę / W dół , wyszukiwanie za pomocą Ctrl + R , rozszerzenie historii z !! i przyjaciółmi, przywołanie ostatniego argumentu za pomocą Alt + . lub $_) działają w ten sam sposób, ale istnieje wiele różnic w szczegółach, zbyt wiele, aby je tutaj wymienić. Możesz skopiować .bash_history do .zsh_history, jeśli nie zmieniłeś opcji powłoki, która zmienia format pliku.

Ukończenie : obie powłoki domyślnie ustawiają się w podstawowym trybie uzupełniania, który w większości uzupełnia nazwy poleceń i plików, i przełączają się na tryb fantazyjny przez włączając bash_completion na bash lub uruchamiając compinit w zsh. Znajdziesz kilka poleceń, które lepiej radzą sobie z bashem, a inne lepiej. Zsh jest zwykle bardziej precyzyjne, ale czasami poddaje się, gdy bash robi coś, co nie jest poprawne, ale jest sensowne. Aby określić możliwe uzupełnienia polecenia, zsh ma trzy mechanizmy:

Wiele ustawień basha shopt ma odpowiadające im setopt w zsh.

Zsh doe sn „t traktuj # jako komentarz, który domyślnie zaczyna się w wierszu poleceń, tylko w skryptach (w tym .zshrc i tym podobnych). Aby włączyć interaktywne komentarze, uruchom setopt interactive_comments .

Główne różnice dotyczące skryptów

(i oczywiście dla zaawansowanych użytkowników z wiersza poleceń)

W bashu $foo przyjmuje wartość foo dzieli go na białe znaki, a dla każdej części oddzielonej białymi znakami, jeśli zawiera znaki wieloznaczne i pasuje do istniejącego pliku, zastępuje wzorzec listą dopasowań. Aby po prostu uzyskać wartość foo, potrzebujesz "$foo". To samo dotyczy podstawiania poleceń $(foo). W zsh $foo to wartość foo, a $(foo) to wynik foo minus ostatnie znaki nowej linii, z dwoma wyjątkami. Jeśli słowo staje się puste z powodu rozwijania pustych zmiennych niecytowanych, jest usuwane (np. a=; b=; printf "%s\n" one "$a$b" three $a$b five wyświetla one, pusty wiersz, three, five). Wynik podstawienia niecytowanego polecenia jest dzielony na białe znaki, ale fragmenty nie są dopasowywane za pomocą symboli wieloznacznych.

Bash tablice są indeksowane od 0 do (length-1). Tablice Zsh są indeksowane od 1 do długości. Z a=(one two three), w bash, ${a[1]} to two, ale w zsh to „s one. W bash, jeśli odwołasz się tylko do zmiennej tablicowej bez nawiasów klamrowych, otrzymasz pierwszy element, np. $a to i $a[1] to one[1].W zsh, $a rozwija się do listy niepustych elementów, a $a[1] rozwija się do pierwszego elementu. Podobnie, w bash, długość tablicy wynosi ${#a}; działa to również w zsh, ale możesz napisać to prościej jako $#a. Możesz ustawić indeksowanie 0 jako domyślne za pomocą setopt ksh_arrays ; włącza to również wymóg używania nawiasów klamrowych do odwoływania się do elementu tablicy.

Bash ma dodatkowe wzorce symboli wieloznacznych , takie jak @(foo|bar), aby dopasować foo lub bar, które są włączone tylko z shopt -s extglob. W zsh możesz włączyć te wzorce za pomocą setopt ksh_glob, ale jest też prostsza metoda natywna składnia , taka jak (foo|bar), z których niektóre wymagają setopt extended_glob (nie umieść to w swoim .zshrc i jest domyślnie włączone w funkcjach uzupełniania). **/ dla cyklicznego przechodzenia do katalogu jest zawsze włączone w zsh.

Domyślnie w bash, jeśli wzorzec wieloznaczny nie pasuje do żadnego pliku, pozostaje niezmieniony. Domyślnie w zsh pojawi się błąd, który jest zwykle najbezpieczniejszym ustawieniem. Jeśli chcesz przekazać parametr wieloznaczny do polecenia, użyj cudzysłowów. Możesz przełączyć się na zachowanie bash za pomocą setopt no_nomatch . Zamiast pasujących wzorców symboli wieloznacznych możesz rozwinąć je do pustej listy za pomocą setopt null_glob .

W bashu prawa strona potoku działa w podpowłoce. W zsh działa w powłoce nadrzędnej, więc możesz napisać takie rzeczy jak somecommand | read output.

Kilka fajnych funkcji zsh

Oto kilka fajnych funkcji zsh, których bash nie ma ( przynajmniej nie bez poważnego smaru do łokci). Ponownie, to tylko wybór tych, które uważam za najbardziej przydatne.

Kwalifikatory Glob umożliwia dopasowywanie plików na podstawie metadanych, takich jak ich sygnatura czasowa, rozmiar itp. Pozwalają również na modyfikowanie wyników. Składnia jest dość zagadkowa, ale jest niezwykle wygodna. Oto kilka przykładów:

  • foo*(.): tylko zwykłe pliki pasujące do i dowiązania symboliczne do zwykłych plików, a nie katalogów i innych plików specjalnych.
  • foo*(*.): tylko wykonywalne zwykłe pliki pasujące do foo*.
  • foo*(-.): tylko zwykłe pliki pasujące do foo*, a nie dowiązania symboliczne i inne pliki specjalne.
  • foo*(-@): tylko wiszące dowiązania symboliczne pasujące do foo*.
  • foo*(om): pliki pasujące do foo*, posortowane według daty ostatniej modyfikacji, od najnowszych. Pamiętaj, że jeśli przekażesz to do ls, wykona własne sortowanie. Jest to szczególnie przydatne w…
  • foo*(om[1,10]): 10 najnowszych plikach pasujących do foo*, od najnowszych.
  • foo*(Lm+1): pliki pasujące do foo* o rozmiarze co najmniej 1 MB.
  • foo*(N): to samo co foo*, ale jeśli nie pasuje do żadnego pliku, tworzy pustą listę niezależnie ustawienia opcji null_glob (patrz wyżej).
  • *(D): dopasuj wszystkie pliki, w tym pliki z kropkami ( z wyjątkiem . i ..).
  • foo/bar/*(:t) (używając modyfikator historii ): pliki w foo/bar, ale tylko z podstawową nazwą pliku. Np. jeśli istnieje a foo/bar/qux.txt, jest rozwijany jako qux.txt.
  • foo/bar/*(.:r): weź zwykłe pliki pod foo/bar i usuń rozszerzenie. Na przykład. foo/bar/qux.txt jest rozwinięte jako foo/bar/qux.
  • foo*.odt(e\""REPLY=$REPLY:r.pdf"\"): weź listę plików pasujących do foo*.odt i zamień .odt na .pdf (niezależnie od tego, czy plik PDF plik istnieje).

Oto kilka przydatnych wzorców symboli wieloznacznych specyficznych dla zsh .

  • foo*.txt~foobar*: all .txt, których nazwa zaczyna się od foo, ale nie foobar.
  • image<->.jpg(n): wszystkie .jpg pliki, których nazwa podstawowa to image, po których następuje liczba, np.image3.jpg i image22.jpg, ale nie image-backup.jpg. Kwalifikator glob (n) powoduje, że pliki są wymienione w kolejności numerycznej, tj. image9.jpg występuje przed image10.jpg (możesz ustawić to jako domyślny nawet bez -n z setopt numeric_glob_sort ).

pliki masowej zmiany nazw , zsh zapewnia bardzo wygodny narzędzie: funkcja zmv . Sugerowane dla Twojego .zshrc:

autoload zmv alias zcp="zmv -C" zln="zmv -L" 

Przykład:

zmv "(*).jpeg" "$1.jpg" zmv "(*)-backup.(*)" "backups/$1.$2" 

Bash ma kilka sposobów stosowania przekształceń podczas pobierania wartości zmiennej . Zsh ma niektóre z tych samych i wiele innych .

Zsh ma kilka niewielkich wygodnych funkcji do zmiany katalogów . Włącz setopt auto_cd , aby przejść do katalogu po wpisaniu jego nazwy bez konieczności wpisywania cd (bash też to ma obecnie). Możesz użyć formularza dwuargumentowego do cd , aby przejść do katalogu, którego nazwa jest zbliżona do bieżącego katalogu . Na przykład, jeśli jesteś w /some/where/foo-old/deeply/nested/inside i chcesz przejść do /some/where/foo-new/deeply/nested/inside, po prostu wpisz cd old new.

Aby przypisać wartość zmiennej, musisz oczywiście napisać VARIABLE=VALUE. Aby edytować wartość zmiennej interaktywnie, po prostu uruchom vared VARIABLE .

Końcowa rada

Zsh jest wyposażony w interfejs konfiguracyjny, który obsługuje kilka najczęściej używanych ustawień, w tym gotowe przepisy na takie rzeczy, jak uzupełnianie bez rozróżniania wielkości liter. Aby (ponownie) uruchomić ten interfejs (pierwsza linia nie jest potrzebna, jeśli „używasz pliku konfiguracyjnego, który został edytowany przez zsh-newuser-install):

autoload -U zsh-newuser-install zsh-newuser-install 

Po wyjęciu z pudełka, bez żadnego pliku konfiguracyjnego, wiele przydatnych funkcji zsh jest wyłączonych w celu zapewnienia zgodności wstecznej z wersjami z lat 90-tych. zsh-newuser-install sugeruje zalecane funkcje do włączenia.

W sieci jest wiele struktur konfiguracyjnych zsh (wiele z nich to na Github ). Mogą być wygodnym sposobem na rozpoczęcie korzystania z zaawansowanych funkcji. Drugą stroną medalu jest to, że często uniemożliwiają ci robienie rzeczy tak, jak robi to autor, więc czasami uniemożliwiają ci robienie rzeczy tak, jak chcesz. Używaj ich na własne ryzyko.

Podręcznik zsh zawiera wiele informacji, ale często jest napisany w sposób zwięzły i trudny do zrozumienia oraz zawiera kilka przykładów. Nie wahaj się szukać wyjaśnień i przykładów w Internecie: jeśli używasz tylko części zsh, który jest łatwy do zrozumienia w instrukcji, możesz przegapić. Dwa dobre zasoby to lista mailingowa zsh-users i Unix Stack Exchange . obszerną kolekcję artykułów na temat przejścia na zsh na Macu można znaleźć na scriptingosx.com i Skrypt Ruby, który przyniesie ze sobą historię poleceń , można znaleźć na Github.

Komentarze

  • Teraz ' zastanawiam się, czy niesamowite ctrl-o działa na zsh. Oczywiście nie ' nie działa również w systemie Mac OS na bash, więc ' nie jest tak naprawdę związane z tą odpowiedzią lub witryną. Nie udało mi się ' znaleźć żadnych informacji o ctrl-o w zsh w szybkim wyszukiwaniu online, ale z drugiej strony informacje o ctrl-o w bash są również powszechnie niedokładne …
  • @Jasper Nie ' nie wiedziałem, że bash to ma. Przechodząc do opisu, Co robi to samo w zsh z domyślnymi przypisaniami klawiszy.
  • Cieszyłem się, że dołączyłeś ” kilka fajnych funkcji zsh ” i przeczytaj go z niepokojem, aby spróbować zrozumieć, dlaczego firma Apple mogła podjąć decyzję o przejściu z niezwykle popularnego Bash na znacznie mniej popularnego Zsh. Nie ' nie znalazłem w tym miejscu niczego, nawet choćby w niewielkim stopniu przekonującego, aby uzasadnić zmianę. Jest to oczywiście ' lista niewyczerpująca, ale czy pominęliście funkcje nagłówkowe Zsh, ponieważ ' mają być oczywiste? Czego tu brakuje?
  • @CodyGray Nie ' nie wiem, a Apple nie ' w przyzwyczajeniu usprawiedliwiania się. Mogło to mieć coś wspólnego z faktem, że gdyby sytuacja została odwrócona, nie byłoby ' sekcji „ładne funkcje basha”.Może tak być, ponieważ ostatnia bash inna niż GPLv3 bardzo się starzeje , podczas gdy zsh ma bardziej liberalną licencję.
  • Rozumiem, że licencja była zasadniczo jedynym powodem. ' jest również powodem, dla którego bash w systemie macOS jest nadal w wersji 3. Mówi się, że bash wygrał ' i oczekuje się, że zostanie usunięty, chyba że użytkownik końcowy zainstaluje go za pośrednictwem programu brew itp. Planowałem przejść na zsh raczej wcześniej niż później dla macOS, ale na razie trzymam się bash na Debianie.

Odpowiedź

Zmień teraz swoją powłokę i przetestuj – nie musisz czekać.

chsh -s /bin/zsh 

Ponadto, szacuję, że 95% użytkowników macOS nie używa wiersza poleceń, a kolejnych 95% nie będzie musiało nic zmieniać wszystko. (Założę się, że 10% z 1% osób, które wiedzą, że powłoki istnieją, musi zrobić coś innego niż przeniesienie kilku wierszy w swoich plikach .dot)

Twój monit ulegnie zmianie i jeśli zmienisz go w bash, sposób jego zmiany na zsh nie jest trudniejszy i nie mniej udokumentowany niż bash.

Nowsze muszle nigdy nie oderwałyby się od ziemi, gdyby zepsuły główne elementy lub spowodowały bolesny okres adaptacji. Jeśli chcesz bardziej fundamentalnej zmiany i naprawdę chcesz mieć muszlę, o której musisz pomyśleć i która wymaga przeszkolenia i zamiaru przyjęcia – wypróbuj rybę .

Komentarze

  • Mam konflikt z fish. Używam go już od dwóch lat, ale niekompatybilność jakiejś kopii / wklejonej jednej linijki jest męcząca. Z drugiej strony jest to bardzo przydatna powłoka (automatyczne sugestie bez < kbd > Tab < / kbd > są doskonałe)
  • Chciałem kochać ryby, nadal chcę kochać ryby, ale mam zbyt wiele konstrukcji muszli z dekady w ksh, aby kiedykolwiek naprawdę opuścić tę fałdę. Chętnie zostawię bash za sobą i osobiście w pełni obejmę zsh.
  • Jestem całkowicie rozczarowany rybami. Jest to po prostu kolejna powłoka podobna do Uniksa, z trochę mniejszą skorupą. (W końcu na stronie głównej jest napisane dosłownie ” Na koniec powłoka wiersza poleceń z lat 90. „). Jedyna nowa powłoka, która Widziałem w ostatnich latach, że rzeczywiście wprowadził coś nowego do tabeli (głównego nurtu), był PowerShell, który niestety był zbyt długo ograniczony do systemu Windows i nadal jest ograniczony do .NET. Wciąż nie ma tego wiele nowego w PowerShell, które nie ' nie zostało jeszcze zrobione, np. w DCL lub JCL, ale zostało to zrobione w (nieco) gustowny sposób.
  • @bmike Dlaczego więc po prostu nie użyć ksh? Apple dostarcza najnowszą wersję. Osobiście zdążyłem już dawno temu spasować bash i nie widzę powodu, by zacząć używać zsh teraz.
  • Ta odpowiedź nie ' nie opisuje jednak różnic między bash i zsh … i ja ' nie do końca wiem, dlaczego określam, że ” 95% użytkowników macOS nie ' t użyj wiersza poleceń ” jest istotne w przypadku pytania użytkownika, który oczywiście używa basha.

Odpowiedź

Moje skrypty powłoki naprawdę nie są tak skomplikowane

Czy twoje skrypty powłoki mają linie shebang (zaczynające się od #! /bin/bash lub podobnego)? Jeśli nie, być może nieumyślnie używasz funkcji bash, która uruchamia skrypty bez shebang za pomocą basha. Inne powłoki, takie jak dash czy zsh, pozostawiają to w gestii systemu operacyjnego, który zwykle używa /bin/sh. /bin/sh w systemie macOS jest i prawdopodobnie pozostanie, kopią /bin/bash, ale wykonuję bash z nazwą sh powoduje, że zachowuje się inaczej. Szczegóły to podręcznik Bash, 6.11 Tryb Bash POSIX . Kilka punktów:

  1. Bash zapewnia, że zmienna POSIXLY_CORRECT jest ustawiona.

Ta zmienna środowiskowa może wpływać na zachowanie wielu innych narzędzi, zwłaszcza jeśli masz zainstalowane narzędzia GNU.

  1. Zastępowanie procesów jest niedostępne.

Podstawienie procesu to składnia <(...) lub >(...).

  1. Funkcje wbudowane . i source nie przeszukują bieżącego katalogu pod kątem nazwy pliku argument, jeśli nie zostanie znaleziony przez wyszukanie PATH.

Więc jeśli twój skrypt . foo spodziewając się, że będzie źródłem pliku o nazwie foo w bieżącym katalogu, który nie działa. Zamiast tego należy wykonać . ./foo.

Jak możesz się domyślić z liczb, istnieje wiele drobnych różnic w zachowaniu basha w trybie POSIX. Najlepiej używaj shebang, jeśli zamierzasz używać basha w swoich skryptach.

Komentarze

  • Podczas sprawdzania wygląda na to, że większość skryptów powłoki, które napisałem e lub użyj jawnie state / bin / bash w shebang (bardzo niewielu z nich) lub state / bin / sh (prawie wszystkie z nich), aby przynajmniej nie powinno być problemu. Dzięki.
  • Myślę, że zastępowanie procesów jest teraz dostępne. Z powodzeniem wypróbowałem również na Catalinie. Zobacz: zsh.sourceforge.net/Intro/intro_7.html
  • @Siu nadal wygrał ' t pomoc dla skryptów, które używają /bin/sh lub /bin/bash w shebang. Zsh jest tylko domyślną powłoką interaktywną, nie ' nie zastąpił bash wszędzie
  • @muru Ach, rozumiem. Nie przeczytałem uważnie odpowiedzi i pomyślałem, że autor mówi o zastępowaniu procesów nie jest dostępne w zsh 😅

Odpowiedź

W duchu prostoty …

Czy każdy może podać proste, praktyczne porównanie lub konkretne przeszkody, które będę musiał znać, abym mógł zacząć pracować nad przygotowaniem się na nową powłokę po wydaniu Cataliny?

Jeśli myślisz o użyciu nowej domyślnej powłoki, rozważ:

  • Jeśli chcesz dać Zsh wir i poczuć niektóre różnice bez zmiany ustawień powłoki na swojej maszynie, możesz spróbować Powerline10k w kontenerze Dockera i sprawdzić, czy to twoja filiżanka herbaty.
  • Jeśli nie potrzebujesz wszystkich dzwonków i gwizdek i używać Bash tylko dla podstawowych skryptów, ustawienie powłoki jest dość łatwe, tak jak wyjaśniły to inne osoby. Jeśli zdecydujesz, że chcesz korzystać z funkcji w Bash 5 , jest to dość trywialna aktualizacja dla macOS .
  • Jeśli chcesz poprawić przenośność swoich skryptów, aby „z większym prawdopodobieństwem działały zgodnie z oczekiwaniami w obu powłokach, przetestuj je pod kątem zgodności z POSIX i usuń wszelkie „bashizmy”. Użyłem do tego ShellCheck i działa całkiem dobrze w przypadku mniej skomplikowanych skryptów.

Chociaż żadna konkretna ścieżka nie jest jasna te trzy podejścia powinny dać ci wystarczającą pewność siebie, aby podjąć świadomą decyzję bez nadmiernej inżynierii problemu lub przestrzeni do rozwiązania.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *