Seguirò le funzionalità di scripting. Le funzionalità interattive avanzate (edizione della riga di comando, completamento, istruzioni, ecc.) Tendono ad essere molto diverse, ottenendo effetti simili in modi totalmente incompatibili. Quali caratteristiche sono in zsh e mancano da bash o viceversa? fornisce alcuni suggerimenti sull'uso interattivo.
La cosa più vicina a bash sarebbe ATT ksh93 o mksh (la shell Korn e un clone). Zsh ha anche un sottoinsieme di funzionalità, ma dovresti eseguirlo in modalità di emulazione ksh, non in modalità nativa zsh.
Non elencherò le funzionalità POSIX (che sono disponibili in qualsiasi shshell moderna ), né le funzionalità relativamente oscure, né quelle menzionate sopra per uso interattivo. Le osservazioni sono valide da bash 4.2, ksh 93u e mksh 40.9.20120630 come si trova su Debian wheezy.
$'…'(stringhe letterali con interpolazione barra rovesciata) è disponibile in ksh93 e mksh. `$" ... "(stringhe tradotte) è specifico per bash.
Mksh e ksh93 devono ;&passare attraverso una casedichiarazione, ma non ;;&per testare i casi successivi. Mksh ha ;|questo e il recente mksh consente la ;;&compatibilità.
((…))espressioni e [[ … ]]test aritmetici sono caratteristiche di ksh. Alcuni operatori condizionali sono diversi, vedere "espressioni condizionali" di seguito.
Ksh e bash hanno entrambi coprocessi ma funzionano in modo diverso.
Mksh e ksh93 supportano la function name {…}sintassi per le definizioni delle funzioni oltre allo standard name () {…}, ma l'uso functionin ksh modifica le regole di scoping, quindi attenersi name () …a mantenere la compatibilità. Le regole per i caratteri consentiti nei nomi delle funzioni variano; attenersi agli alfanumerici e _.
Ksh93 e mksh supportano l'espansione del controvento {foo,bar}. Ksh93 supporta intervalli numerici {1..42}ma mksh no.
Ksh93 e supporto mksh estrazione di sottostringa con ${VAR:offset}e ${VAR:offset:length}, ma non caso pieghevole come ${VAR^}, ${VAR,}, ecc Si può fare la conversione caso typeset -le typeset -usia in bash e ksh.
Supportano la sostituzione con ${VAR/PATTERN/STRING}o ${VAR/PATTERN//STRING}. Le regole di quotazione per STRING sono leggermente diverse, quindi evita le barre rovesciate (e forse altri caratteri) in STRING (costruisci una variabile e usa ${VAR/PATTERN/$REPLACEMENT}invece se la sostituzione contiene caratteri di quotazione).
Espansione dell'array ( ${ARRAY[KEY]}, "${ARRAY[@]}", ${#ARRAY[@]}, ${!ARRAY[@]}) opera in bash come in ksh.
${!VAR}espandendosi a ${OTHERVAR}quando il valore di VARis OTHERVAR(riferimento variabile indiretto) è specifico di bash (ksh fa qualcosa di diverso con ${!VAR}). Per ottenere questa doppia espansione in ksh, devi invece usare un riferimento al nome ( typeset -n VAR=OTHERVAR; echo "$VAR"). ${!PREFIX*}funziona allo stesso modo.
Sostituzione del processo <(…)ed >(…)è supportato in ksh93 ma non in mksh.
I modelli glob estesi ksh che devono shopt -s extglobessere attivati in bash sono sempre disponibili in ksh93 e mksh.
Mksh non supporta classi di personaggi come [[:alpha:]].
Bash e ksh93 definiscono pseudo-file e , ma mksh no./dev/tcp/HOST/PORT/dev/udp/HOST/PORT
Espandere i caratteri jolly in un reindirizzamento negli script (come per var="*.txt"; echo hello >$aiscritto a.txtse quel nome file è l'unica corrispondenza per il modello) è una funzione specifica di bash (altre shell non lo fanno mai negli script).
<<< qui-stringhe funzionano in ksh come in bash.
Il collegamento >&per reindirizzare gli errori di sintassi è supportato anche da mksh ma non da ksh93.
[[ … ]] sintassi doppia parentesi
La sintassi della doppia parentesi di ksh è supportata sia da ATT ksh93 che da mksh come in bash.
Operatori di file
Ksh93, mksh e bash supportano le stesse estensioni di POSIX, incluso -acome sinonimo obsoleto di -e, -k(appiccicoso), -G(di proprietà di egid), -O(proprietario di euid), -ef(stesso file), -nt(più recente di), -ot(più vecchio di).
-N FILE (modificato dall'ultima lettura) non è supportato da mksh.
Mksh non ha un operatore di abbinamento regexp =~. Ksh93 ha questo operatore ed esegue la stessa corrispondenza di in bash, ma non ha un equivalente di BASH_REMATCHrecuperare gruppi corrispondenti in seguito.
Operatori di stringa
Ksh93 e mksh supportano gli stessi operatori di confronto di stringhe <e >come bash e il ==sinonimo di =. Mksh non usa le impostazioni locali per determinare l'ordine lessicografico, confronta le stringhe come stringhe di byte.
Altri operatori
-v VARverificare se una variabile è definita è specifico di bash. In qualsiasi shell POSIX, è possibile utilizzare [ -z "${VAR+1}" ].
L'insieme di caratteri consentiti nei nomi di alias non è lo stesso in tutte le shell. Penso che sia lo stesso delle funzioni (vedi sopra).
Ksh93 ha un builtin chiamato builtin, ma non esegue un nome come comando incorporato. Utilizzare commandper bypassare alias e funzioni; questo chiamerà un builtin se ne esiste uno, altrimenti un comando esterno (puoi evitarlo con PATH= command error_out_if_this_is_not_a_builtin).
Questo è specifico per Bash. È possibile ottenere un effetto simile con .sh.fun, .sh.filee .sh.linenoin ksh93. In mksh c'è finalmente LINENO.
declareè un nome specifico per bash per ksh typeset. Usa typeset: funziona anche in bash.
Mksh definisce localcome un alias per typeset. In ksh93, devi usare typeset(o definire un alias).
Mksh non ha array associativi (sono previsti per una versione non ancora pubblicata).
Non penso che esista un equivalente esatto di bash typeset -t(funzione trace) in ksh.
Ksh93 non ha -e.
Ksh93 e mksh elaborano le opzioni -ee -ncome in bash. Mksh capisce anche che -Eksh93 non lo considera un'opzione. L'espansione della barra rovesciata è disattivata per impostazione predefinita in ksh93, attivata per impostazione predefinita in mksh.
Ksh non fornisce un modo per disabilitare i comandi integrati. Per evitare un built-in, cerca il percorso del comando esterno e invocalo esplicitamente.
Ksh93 ha -ama non -l. Mksh non ha nessuno dei due.
Né ksh93 né mksh hanno export -n. Usa typeset +x fooinvece, funziona in bash e ksh.
Ksh non esporta le funzioni attraverso l'ambiente.
let è lo stesso in bash e ksh.
Questa è una funzione specifica per bash. È possibile utilizzare i while readloop o la sostituzione dei comandi per leggere un file e dividerlo in una matrice di righe. Abbi cura di te IFSe del dolore. Ecco l'equivalente di mapfile -t lines </path/to/file:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printfè molto simile. Penso che ksh93 supporti tutte le direttive sul formato di Bash. mksh non supporta %qo %(DATE_FORMAT)T; su alcune installazioni, printfnon è un mksh incorporato e chiama invece il comando esterno.
printf -v VAR è specifico per bash, ksh stampa sempre sullo standard output.
Diverse opzioni sono specifiche di bash, comprese tutte quelle su readline. Le opzioni -r, -d, -n, -N, -t, -usono identici in bash, ksh93 e mksh.
Puoi dichiarare una variabile di sola lettura in Ksh93 e mksh con la stessa sintassi. Se la variabile è un array, è necessario prima assegnarlo, quindi renderlo di sola lettura con readonly VAR. Le funzioni non possono essere rese di sola lettura in ksh.
Tutte le opzioni per sete set -osono POSIX o ksh.
shoptè specifico per bash. Molte opzioni riguardano comunque l'uso interattivo. Per effetti sul globbing e altre funzionalità abilitate da alcune opzioni, vedere la sezione "Opzioni" di seguito.
Questa variante .esiste anche in ksh. In bash e mksh, sourcecerca la directory corrente dopo PATH, ma in ksh93, è un equivalente esatto di ..
Lo DEBUGpseudo-segnale non è implementato in mksh. In ksh93, esiste un modo diverso per riportare informazioni, vedere il manuale per i dettagli.
In ksh, typeè un alias per whence -v. In mksh, type -pnon stampa il percorso dell'eseguibile, ma un messaggio leggibile dall'uomo; devi usare whence -p COMMANDinvece.
Opzioni
shopt -s dotglob - non ignorare i file di punti in globbing
Per emulare l' dotglobopzione in ksh93, puoi impostare FIGNORE='@(.|..)'. Non penso che ci sia qualcosa di simile in Mksh.
L' extglobopzione è effettivamente sempre attiva in ksh.
shopt -s failglob - errore se un modello glob non corrisponde a nulla
Non penso che questo esista in mksh o ksh93. Lo fa in zsh (comportamento predefinito a meno null_globche non sia csh_null_globimpostato).
Ksh93 ha globbing ricorsivo con **/, abilitato con set -G. Mksh non ha globbing ricorsivo.
shopt -s lastpipe - esegue l'ultimo comando di una pipeline nella shell padre
Ksh93 esegue sempre l'ultimo comando di una pipeline nella shell padre, che in bash richiede che l' lastpipeopzione sia impostata. Mksh esegue sempre l'ultimo comando di una pipeline in una subshell.
shopt -s nocaseglob, shopt -s nocasematch- modelli senza distinzione tra maiuscole e minuscole
Mksh non ha una corrispondenza di pattern senza distinzione tra maiuscole e minuscole. Ksh93 lo supporta in base al modello: prefisso il modello con ~(i).
shopt -s nullglob - espande i motivi che non corrispondono ad alcun file in un elenco vuoto
Mksh non ha questo. Ksh93 lo supporta in base al modello: prefisso il modello con ~(N).
Ovviamente la maggior parte delle BASH_xxxvariabili non esiste in ksh. $BASHPIDpuò essere emulato con il costoso ma portatile sh -c 'echo $PPID', ed è stato recentemente aggiunto a mksh. BASH_LINEè .sh.linenoin ksh93 e LINENOin mksh. BASH_SUBSHELLè .sh.subshellin ksh93.
Mksh e ksh93 hanno entrambi il file sorgente dato ENVall'avvio.
EUIDe UIDnon esistono in ksh93. Mksh li chiama USER_IDe KSH_UID; non ha GROUPS.
FUNCNAMEe FUNCNESTnon esistono in ksh. Ksh93 ha .sh.fune .sh.level. Le funzioni dichiarate con function foo { …; }(nessuna parentesi!) Hanno il loro nome in $0.
GLOBIGNOREesiste in ksh93 ma con un nome e una sintassi diversi: si chiama FIGNOREed è un singolo modello, non un elenco separato da due punti. Usa uno @(…|…)schema. Ksh sottrae FIGNOREbash, con una sintassi completamente diversa.
Ksh93 e mksh hanno nulla di simile HOSTTYPE, MACHTYPEe OSTYPE. Né SHELLOPTSo TIMEFORMAT.
Mksh ha PIPESTATUS, ma ksh93 no.
Mksh e Ksh93 hanno RANDOM.