Będę trzymać się funkcji skryptów. Bogate funkcje interaktywne (edycja wiersza poleceń, uzupełnianie, monity itp.) Bywają bardzo różne, osiągając podobne efekty w całkowicie niezgodny sposób. Jakie funkcje są w Zsh i brakuje w bash, lub odwrotnie? daje kilka wskazówek na temat interaktywnego użytkowania.
Najbliższą rzeczą do uderzenia byłoby ATT ksh93 lub mksh (skorupa Korna i klon). Zsh ma również podzbiór funkcji, ale trzeba go uruchomić w trybie emulacji ksh, a nie w trybie macierzystym zsh.
Nie wymienię funkcji POSIX (które są dostępne w żadnej nowoczesnej shpowłoce), ani stosunkowo mało znanych funkcji, ani też, jak wspomniano powyżej, funkcji interaktywnych. Obserwacje obowiązują od wersji bash 4.2, ksh 93u i mksh 40.9.20120630, jak stwierdzono w wheezy Debiana.
$'…'(dosłowne ciągi z interpolacją odwrotnego ukośnika) jest dostępny w ksh93 i mksh. `$„… ”(Przetłumaczone ciągi) jest specyficzne dla bash.
Mksh i ksh93 muszą ;&przejść przez caseinstrukcję, ale nie ;;&testować kolejnych przypadków. Mksh ma ;|na to, a najnowszy mksh pozwala ;;&na kompatybilność.
((…))wyrażenia arytmetyczne i [[ … ]]testy są cechami ksh. Niektóre operatory warunkowe są różne, patrz „wyrażenia warunkowe” poniżej.
Zarówno Ksh, jak i bash mają koprocesy, ale działają inaczej.
Mksh i ksh93 obsługują function name {…}składnię definicji funkcji oprócz standardu name () {…}, ale używając functionw ksh zmian zasad zakresu, więc trzymaj się, name () …aby zachować kompatybilność. Reguły dotyczące dozwolonych znaków w nazwach funkcji są różne; trzymać się alfanumerycznych i _.
Ksh93 i mksh obsługują rozszerzenie nawiasu klamrowego {foo,bar}. Ksh93 obsługuje zakresy liczbowe, {1..42}ale mksh nie.
Ksh93 i mksh wsparcie podciąg z ekstrakcji ${VAR:offset}i ${VAR:offset:length}, ale nie przypadek składana jak ${VAR^}, ${VAR,}itd można zrobić konwersję z liter typeset -li typeset -uzarówno bash i ksh.
Obsługują zamianę na ${VAR/PATTERN/STRING}lub ${VAR/PATTERN//STRING}. Reguły cytowania dla STRING są nieco inne, więc unikaj odwrotnych ukośników (i być może innych znaków) w STRING (zbuduj zmienną i użyj ${VAR/PATTERN/$REPLACEMENT}zamiast tego, jeśli zamiennik zawiera znaki cytowania).
Rozszerzanie tablicy ( ${ARRAY[KEY]}, "${ARRAY[@]}", ${#ARRAY[@]}, ${!ARRAY[@]}) działa w bash jak w KSH.
${!VAR}rozwijanie do ${OTHERVAR}momentu, w którym wartość VARis OTHERVAR(odwołanie do zmiennej pośredniej) jest specyficzna dla bash (ksh robi coś innego z ${!VAR}). Aby uzyskać to podwójne rozszerzenie w ksh, musisz zamiast tego użyć odwołania do nazwy ( typeset -n VAR=OTHERVAR; echo "$VAR"). ${!PREFIX*}działa tak samo.
Zmiana procesu <(…)i >(…)jest obsługiwana w ksh93 ale nie mksh.
Rozszerzone wzorce globu ksh, które należy shopt -s extglobaktywować w bash, są zawsze dostępne w ksh93 i mksh.
Mksh nie obsługuje takich klas postaci jak [[:alpha:]].
Bash i ksh93 definiują pseudopliki i , ale mksh nie./dev/tcp/HOST/PORT/dev/udp/HOST/PORT
Rozwijanie symboli wieloznacznych w przekierowaniu w skryptach (tak jak w var="*.txt"; echo hello >$apisaniu do a.txttego, czy ta nazwa pliku jest jedynym dopasowaniem do wzorca) jest funkcją specyficzną dla bash (inne powłoki nigdy tego nie robią w skryptach).
<<< ciągi tutaj działają w ksh jak w bash.
Skrót >&do błędów składniowych przekierowania jest także obsługiwany przez mksh, ale nie przez ksh93.
[[ … ]] składnia podwójnego nawiasu
Składnia podwójnego nawiasu od ksh jest obsługiwana zarówno przez ATT ksh93, jak i mksh jak w bash.
Operatorzy plików
Ksh93, mksh i bash obsługują te same rozszerzenia POSIX, w tym -ajako przestarzały synonim -e, -k(sticky), -G(własność egid), -O(właściciel przez euid), -ef(ten sam plik), -nt(nowszy niż), -ot(starszy niż).
-N FILE (zmodyfikowany od ostatniego odczytu) nie jest obsługiwany przez mksh.
Mksh nie ma operatora dopasowującego wyrażenia regularne =~. Ksh93 ma ten operator i wykonuje to samo dopasowanie, co w bash, ale nie ma odpowiednika BASH_REMATCHdo pobierania dopasowanych grup później.
Operatory strunowe
Ksh93 i mksh obsługują te same operatory porównywania ciągów <oraz >jako bash i ==synonim =. Mksh nie używa ustawień regionalnych do określenia porządku leksykograficznego, porównuje ciągi jako ciągi bajtów.
Inni operatorzy
-v VARtestowanie, czy zmienna jest zdefiniowana, jest specyficzne dla bash. Możesz użyć dowolnej powłoki POSIX [ -z "${VAR+1}" ].
Zestaw znaków dozwolonych w nazwach aliasów nie jest taki sam we wszystkich powłokach. Myślę, że jest tak samo jak w przypadku funkcji (patrz wyżej).
Ksh93 ma wbudowaną funkcję o nazwie builtin, ale nie wykonuje nazwy jako wbudowanej komendy. Służy commanddo pomijania aliasów i funkcji; wywoła to wbudowane, jeśli takie istnieje, w przeciwnym razie zewnętrzne polecenie (możesz tego uniknąć za pomocą PATH= command error_out_if_this_is_not_a_builtin).
Jest to specyficzne dla bash. Można uzyskać podobny efekt .sh.fun, .sh.filea .sh.linenow ksh93. W mksh wreszcie jest LINENO.
declarejest specyficzną dla bash nazwą ksh typeset. Użyj typeset: działa również w bash.
Mksh definiuje się localjako alias dla typeset. W ksh93 musisz użyć typeset(lub zdefiniować alias).
Mksh nie ma tablic asocjacyjnych (są one przeznaczone na jeszcze niepublikowaną wersję).
Nie sądzę, że typeset -tw ksh istnieje dokładny odpowiednik bash (funkcja śledzenia).
Ksh93 nie ma -e.
Ksh93 i mksh przetwarzają opcje -ei -njak w bash. Mksh również rozumie -E, ksh93 nie traktuje tego jako opcji. Rozwinięcie ukośnika odwrotnego jest domyślnie wyłączone w ksh93, domyślnie włączone w mksh.
Ksh nie zapewnia sposobu na wyłączenie wbudowanych poleceń. Aby uniknąć wbudowania, sprawdź ścieżkę zewnętrznego polecenia i wywołaj je jawnie.
Ksh93 ma, -aale nie ma -l. Mksh nie ma.
Ani ksh93, ani mksh nie ma export -n. Użyj typeset +x foozamiast tego działa w bash i ksh.
Ksh nie eksportuje funkcji przez środowisko.
let jest taki sam w bash i ksh.
Jest to funkcja specyficzna dla bash. Możesz użyć while readpętli lub podstawienia poleceń, aby odczytać plik i podzielić go na tablicę wierszy. Zadbaj o IFSi globbing. Oto odpowiednik mapfile -t lines </path/to/file:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printfjest bardzo podobny. Myślę, że ksh93 obsługuje wszystkie dyrektywy formatujące bash. mksh nie obsługuje %qlub %(DATE_FORMAT)T; w niektórych instalacjach printfnie jest wbudowany w mksh i zamiast tego wywołuje zewnętrzne polecenie.
printf -v VAR jest specyficzny dla bash, ksh zawsze drukuje na standardowe wyjście.
Kilka opcji jest specyficznych dla bash, w tym wszystkie dotyczące readline. Opcje -r, -d, -n, -N, -t, -usą identyczne w bash, ksh93 i mksh.
Możesz zadeklarować zmienną jako tylko do odczytu w Ksh93 i mksh z tą samą składnią. Jeśli zmienna jest tablicą, musisz ją najpierw przypisać, a następnie ustawić jako tylko do odczytu za pomocą readonly VAR. Funkcje nie mogą być ustawione tylko do odczytu w ksh.
Wszystkie opcje seti set -osą funkcjami POSIX lub ksh.
shoptjest specyficzny dla bash. Zresztą wiele opcji dotyczy użytkowania interaktywnego. Aby zapoznać się z efektami globowania i innymi funkcjami włączonymi przez niektóre opcje, zobacz sekcję „Opcje” poniżej.
Ten wariant .istnieje również w ksh. W bash i mksh sourceprzeszukuje bieżący katalog po PATH, ale w ksh93 jest to dokładny odpowiednik ..
DEBUGPseudo-sygnał nie jest realizowany w mksh. W ksh93 istnieje inny sposób zgłaszania informacji, szczegółowe informacje można znaleźć w instrukcji obsługi.
W ksh typejest aliasem dla whence -v. W mksh type -pnie drukuje ścieżki do pliku wykonywalnego, ale komunikat czytelny dla człowieka; musisz użyć whence -p COMMANDzamiast tego.
Opcje
shopt -s dotglob - nie ignoruj plików kropek podczas globowania
Aby emulować dotglobopcję w ksh93, możesz ustawić FIGNORE='@(.|..)'. Nie sądzę, że coś takiego jest w mksh.
Ta extglobopcja jest zawsze włączona w ksh.
shopt -s failglob - błąd, jeśli wzór globu nic nie pasuje
Nie sądzę, że istnieje to zarówno w mksh, jak i ksh93. Robi to w Zsh (zachowanie domyślne, chyba że null_globlub csh_null_globsą ustawione).
Ksh93 ma globalne rekurencyjne z **/, włączone z set -G. Mksh nie ma rekurencyjnego globowania.
shopt -s lastpipe - uruchom ostatnie polecenie potoku w powłoce nadrzędnej
Ksh93 zawsze uruchamia ostatnie polecenie potoku w powłoce nadrzędnej, która w bash wymaga ustawienia lastpipeopcji. Mksh zawsze uruchamia ostatnie polecenie potoku w podpowłoce.
shopt -s nocaseglob, shopt -s nocasematch- wzorce bez rozróżniania wielkości liter
Mksh nie ma dopasowywania wzorca bez rozróżniania wielkości liter. Ksh93 obsługuje go na zasadzie wzorca po wzorze: przedrostek wzorca za pomocą ~(i).
shopt -s nullglob - rozwiń wzorce, które nie pasują do żadnego pliku, na pustą listę
Mksh tego nie ma. Ksh93 obsługuje go na zasadzie wzorca po wzorze: przedrostek wzorca za pomocą ~(N).
Oczywiście większość BASH_xxxzmiennych nie istnieje w ksh. $BASHPIDmoże być emulowany kosztownym, ale przenośnym sh -c 'echo $PPID', i został niedawno dodany do mksh. BASH_LINEjest .sh.linenow ksh93 i LINENOmksh. BASH_SUBSHELLjest .sh.subshellw ksh93.
Zarówno Mksh, jak i ksh93 pobierają plik podany ENVpodczas uruchamiania.
EUIDi UIDnie istnieją w ksh93. Mksh nazywa je USER_IDi KSH_UID; nie ma GROUPS.
FUNCNAMEi FUNCNESTnie istnieją w ksh. Ksh93 ma .sh.funi .sh.level. Funkcje zadeklarowane za pomocą function foo { …; }(bez nawiasów!) Mają swoje własne nazwy w $0.
GLOBIGNOREistnieje w ksh93, ale z inną nazwą i składnią: nazywa się FIGNOREi jest to pojedynczy wzorzec, a nie lista oddzielona dwukropkami. Użyj @(…|…)wzoru. Ksh FIGNOREpodbija bash z zupełnie inną składnią.
Ksh93 i mksh mają nic podobnego HOSTTYPE, MACHTYPEi OSTYPE. Ani SHELLOPTSlub TIMEFORMAT.
Mksh ma PIPESTATUS, ale ksh93 nie.
Mksh i ksh93 mają RANDOM.