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 sh
powł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 case
instrukcję, 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 function
w 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 -l
i typeset -u
zaró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ść VAR
is 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 extglob
aktywować 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 >$a
pisaniu do a.txt
tego, 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 -a
jako 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_REMATCH
do 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 VAR
testowanie, 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 command
do 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.file
a .sh.lineno
w ksh93. W mksh wreszcie jest LINENO
.
declare
jest specyficzną dla bash nazwą ksh typeset
. Użyj typeset
: działa również w bash.
Mksh definiuje się local
jako 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 -t
w ksh istnieje dokładny odpowiednik bash (funkcja śledzenia).
Ksh93 nie ma -e
.
Ksh93 i mksh przetwarzają opcje -e
i -n
jak 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, -a
ale nie ma -l
. Mksh nie ma.
Ani ksh93, ani mksh nie ma export -n
. Użyj typeset +x foo
zamiast 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 read
pętli lub podstawienia poleceń, aby odczytać plik i podzielić go na tablicę wierszy. Zadbaj o IFS
i globbing. Oto odpowiednik mapfile -t lines </path/to/file
:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printf
jest bardzo podobny. Myślę, że ksh93 obsługuje wszystkie dyrektywy formatujące bash. mksh nie obsługuje %q
lub %(DATE_FORMAT)T
; w niektórych instalacjach printf
nie 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
, -u
są 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 set
i set -o
są funkcjami POSIX lub ksh.
shopt
jest 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 source
przeszukuje bieżący katalog po PATH
, ale w ksh93 jest to dokładny odpowiednik .
.
DEBUG
Pseudo-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 type
jest aliasem dla whence -v
. W mksh type -p
nie drukuje ścieżki do pliku wykonywalnego, ale komunikat czytelny dla człowieka; musisz użyć whence -p COMMAND
zamiast tego.
Opcje
shopt -s dotglob
- nie ignoruj plików kropek podczas globowania
Aby emulować dotglob
opcję w ksh93, możesz ustawić FIGNORE='@(.|..)'
. Nie sądzę, że coś takiego jest w mksh.
Ta extglob
opcja 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_glob
lub csh_null_glob
są 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 lastpipe
opcji. 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_xxx
zmiennych nie istnieje w ksh. $BASHPID
może być emulowany kosztownym, ale przenośnym sh -c 'echo $PPID'
, i został niedawno dodany do mksh. BASH_LINE
jest .sh.lineno
w ksh93 i LINENO
mksh. BASH_SUBSHELL
jest .sh.subshell
w ksh93.
Zarówno Mksh, jak i ksh93 pobierają plik podany ENV
podczas uruchamiania.
EUID
i UID
nie istnieją w ksh93. Mksh nazywa je USER_ID
i KSH_UID
; nie ma GROUPS
.
FUNCNAME
i FUNCNEST
nie istnieją w ksh. Ksh93 ma .sh.fun
i .sh.level
. Funkcje zadeklarowane za pomocą function foo { …; }
(bez nawiasów!) Mają swoje własne nazwy w $0
.
GLOBIGNORE
istnieje w ksh93, ale z inną nazwą i składnią: nazywa się FIGNORE
i jest to pojedynczy wzorzec, a nie lista oddzielona dwukropkami. Użyj @(…|…)
wzoru. Ksh FIGNORE
podbija bash z zupełnie inną składnią.
Ksh93 i mksh mają nic podobnego HOSTTYPE
, MACHTYPE
i OSTYPE
. Ani SHELLOPTS
lub TIMEFORMAT
.
Mksh ma PIPESTATUS
, ale ksh93 nie.
Mksh i ksh93 mają RANDOM
.