W jakim stopniu inne powłoki zgodne z POSIX mogą funkcjonować jako rozsądne zamienniki bash? Nie muszą to być prawdziwe „zastępcze” zamienniki, ale wystarczająco blisko, aby pracować z większością skryptów i obsługiwać resztę z pewnymi modyfikacjami.
Chcę mieć wyraźne skrypty bash - skrypty startowe, skrypty klienta DHCP itp. - pracujące z minimalnymi modyfikacjami
Chcę, aby moja kolekcja bardziej wyspecjalizowanych skryptów powłoki nie wymagała zbyt wielu modyfikacji
Chcę mieć takie funkcje, jak manipulacja ciągiem znaków i wbudowane dopasowanie wzorca wyrażeń regularnych
Jedynymi poważnymi pretendentami, o których wiem, są zsh i mksh. Tak więc dla tych z was, którzy są dobrzy dla jednego lub obu z nich:
Jakie funkcje ma bash, odpowiednio, zsh i mksh?
Jakie funkcje współdzielą powłoki z bash, ale używają niekompatybilnej składni?
bash
, mksh i zsh mogłyby funkcjonować jak/bin/sh
z różnymi poziomami poprawności, ale niebash
.Odpowiedzi:
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.Składnia powłoki
Cytowanie
$'…'
(dosłowne ciągi z interpolacją odwrotnego ukośnika) jest dostępny w ksh93 i mksh. `$„… ”(Przetłumaczone ciągi) jest specyficzne dla bash.Konstrukcje warunkowe
Mksh i ksh93 muszą
;&
przejść przezcase
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.Koprocesy
Zarówno Ksh, jak i bash mają koprocesy, ale działają inaczej.
Funkcje
Mksh i ksh93 obsługują
function name {…}
składnię definicji funkcji oprócz standarduname () {…}
, ale używającfunction
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_
.Rozszerzenie klamry
Ksh93 i mksh obsługują rozszerzenie nawiasu klamrowego
{foo,bar}
. Ksh93 obsługuje zakresy liczbowe,{1..42}
ale mksh nie.Rozszerzenie parametrów
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 litertypeset -l
itypeset -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
isOTHERVAR
(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.Zastąpienie procesu
Zmiana procesu
<(…)
i>(…)
jest obsługiwana w ksh93 ale nie mksh.Wzory symboli wieloznacznych
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:]]
.Przekierowanie IO
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 doa.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.Wyrażenia warunkowe
[[ … ]]
składnia podwójnego nawiasuSkł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 odpowiednikaBASH_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}" ]
.Wbudowane
alias
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).
builtin
Ksh93 ma wbudowaną funkcję o nazwie
builtin
, ale nie wykonuje nazwy jako wbudowanej komendy. Służycommand
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
).caller
Jest to specyficzne dla bash. Można uzyskać podobny efekt
.sh.fun
,.sh.file
a.sh.lineno
w ksh93. W mksh wreszcie jestLINENO
.declare
,local
,typeset
declare
jest specyficzną dla bash nazwą kshtypeset
. Użyjtypeset
: działa również w bash.Mksh definiuje się
local
jako alias dlatypeset
. 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).cd
Ksh93 nie ma
-e
.echo
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.enable
Ksh nie zapewnia sposobu na wyłączenie wbudowanych poleceń. Aby uniknąć wbudowania, sprawdź ścieżkę zewnętrznego polecenia i wywołaj je jawnie.
exec
Ksh93 ma,
-a
ale nie ma-l
. Mksh nie ma.export
Ani ksh93, ani mksh nie ma
export -n
. Użyjtypeset +x foo
zamiast tego działa w bash i ksh.Ksh nie eksportuje funkcji przez środowisko.
let
let
jest taki sam w bash i ksh.mapfile
,readarray
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 oIFS
i globbing. Oto odpowiednikmapfile -t lines </path/to/file
:printf
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 instalacjachprintf
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.read
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.readonly
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.set
,shopt
Wszystkie opcje
set
iset -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.source
Ten wariant
.
istnieje również w ksh. W bash i mkshsource
przeszukuje bieżący katalog poPATH
, ale w ksh93 jest to dokładny odpowiednik.
.trap
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.type
W ksh
type
jest aliasem dlawhence -v
. W mkshtype -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 globowaniaAby emulować
dotglob
opcję w ksh93, możesz ustawićFIGNORE='@(.|..)'
. Nie sądzę, że coś takiego jest w mksh.shopt -s extglob
- ksh rozszerzone wzorce globówTa
extglob
opcja jest zawsze włączona w ksh.shopt -s failglob
- błąd, jeśli wzór globu nic nie pasujeNie sądzę, że istnieje to zarówno w mksh, jak i ksh93. Robi to w Zsh (zachowanie domyślne, chyba że
null_glob
lubcsh_null_glob
są ustawione).shopt -s globstar
-**/
globowanie rekurencyjneKsh93 ma globalne rekurencyjne z
**/
, włączone zset -G
. Mksh nie ma rekurencyjnego globowania.shopt -s lastpipe
- uruchom ostatnie polecenie potoku w powłoce nadrzędnejKsh93 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 literMksh 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)
.Zmienne
Oczywiście większość
BASH_xxx
zmiennych nie istnieje w ksh.$BASHPID
może być emulowany kosztownym, ale przenośnymsh -c 'echo $PPID'
, i został niedawno dodany do mksh.BASH_LINE
jest.sh.lineno
w ksh93 iLINENO
mksh.BASH_SUBSHELL
jest.sh.subshell
w ksh93.Zarówno Mksh, jak i ksh93 pobierają plik podany
ENV
podczas uruchamiania.EUID
iUID
nie istnieją w ksh93. Mksh nazywa jeUSER_ID
iKSH_UID
; nie maGROUPS
.FUNCNAME
iFUNCNEST
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. KshFIGNORE
podbija bash z zupełnie inną składnią.Ksh93 i mksh mają nic podobnego
HOSTTYPE
,MACHTYPE
iOSTYPE
. AniSHELLOPTS
lubTIMEFORMAT
.Mksh ma
PIPESTATUS
, ale ksh93 nie.Mksh i ksh93 mają
RANDOM
.źródło
$BASHPID
emulowaćsh -c 'echo $PPID'
? Próbowałem(sh -c 'echo $PPID')
w Bash, ale daje mi ten sam PID co$$
.To pytanie jest zbyt ogólne.
Zarówno mksh, jak i zsh są powłokami, które obsługują wiele rozszerzeń specyficznych dla bash GNU , ale zawsze są takie, które nie są zrozumiane.
zsh obsługuje więcej rzeczy, ale tylko w natywnym trybie zsh, który nie jest kompatybilny z powłokami POSIX (takimi jak GNU bash, AT&T ksh93 , mksh). Ponadto mksh jest znacznie szczuplejszy, szybszy i bardziej przenośny.
Ogólnie, jeśli chodzi o twoje skrypty, mówimy, po prostu je przetestuj. (mksh nie obsługuje jeszcze tablic asocjacyjnych w stylu bash4. Polecenie „deklaruj” jest specyficzne dla bash, „skład zestawu” jest równoważny. Nie znam wystarczająco dużo zsh, aby powiedzieć coś o tym wprost. ksh93 nie ma „lokalnego” ale używa do tego również „składu”). Ale jeśli chodzi o, powiedzmy, uruchamianie bezproblemowego systemu Debian, zapomnij o tym. Istnienie bash jest częścią „obietnicy” (API / ABI systemu) i wiele na nim polega.
Oświadczenie: Jestem programistą mksh.
źródło
Porównanie ZSH pocisków
Najbardziej nie znam się na mksh, więc nie wiem, gdzie szukać tej odpowiedzi.
Jeśli szukasz bezpiecznego zamiennika pocisku, żadna z tych pocisków nie różni się tak bardzo od Basha, jak wrodzona wada, którą omawiasz.
Język taki jak Perl obsługuje dane wejściowe bezpieczniej. Ale kluczem jest tutaj również łatwość konserwacji. Zastąpienie powłoki Perla nie jest zbyt dobrze przyjęte. Obowiązkiem opiekuna powłoki jest bezpieczne przetwarzanie danych wejściowych. Więc kiedy piszesz skrypty, sprawdzaj, sprawdzaj, sprawdzaj wszystko! Używaj kontraktów kodowych, aby zapewnić poprawne wyniki za każdym razem!
Perl Shell
Oświadczenie FSF w sprawie Shock Shock
źródło
Jedną z funkcji, która nie jest domyślnie włączona w
mksh
historii powłoki.W twoim
.mkshrc
właśnie zestawie:export HISTFILE=~/.mksh-history
źródło