Je m'en tiendrai aux fonctionnalités de script. De riches fonctionnalités interactives (édition en ligne de commande, complétion, invites, etc.) ont tendance à être très différentes, obtenant des effets similaires de manière totalement incompatible. Quelles fonctionnalités sont dans zsh et manquent dans bash, ou vice versa? donne quelques conseils sur l'utilisation interactive.
La chose la plus proche de bash serait ATT ksh93 ou mksh (le shell Korn et un clone). Zsh possède également un sous-ensemble de fonctionnalités, mais vous devez l'exécuter en mode d'émulation ksh, pas en mode natif zsh.
Je ne listerai pas les fonctionnalités POSIX (qui sont disponibles dans n'importe quel shshell moderne ), ni les fonctionnalités relativement obscures, ni les fonctionnalités mentionnées ci-dessus pour une utilisation interactive. Les observations sont valables à partir de bash 4.2, ksh 93u et mksh 40.9.20120630 telles que trouvées sur Debian Wheezy.
$'…'(chaînes littérales avec interpolation antislash) est disponible en ksh93 et mksh. `$"… "(Chaînes traduites) est spécifique à bash.
Mksh et ksh93 doivent ;&passer par une casedéclaration, mais pas ;;&pour tester les cas suivants. Mksh a ;|pour cela, et mksh récent permet la ;;&compatibilité.
((…))les expressions et [[ … ]]tests arithmétiques sont des fonctionnalités ksh. Certains opérateurs conditionnels sont différents, voir «expressions conditionnelles» ci-dessous.
Ksh et bash ont tous deux des coprocessus mais ils fonctionnent différemment.
Mksh et ksh93 prennent en charge la function name {…}syntaxe des définitions de fonction en plus de la norme name () {…}, mais l'utilisation functiondans ksh modifie les règles de portée, donc respectez la name () …compatibilité. Les règles pour les caractères autorisés dans les noms de fonction varient; s'en tenir aux alphanumériques et _.
Ksh93 et mksh prennent en charge l'expansion des accolades {foo,bar}. Ksh93 prend en charge les plages numériques, {1..42}mais pas mksh.
Soutien ksh93 et mksh extraction de sous - chaînes avec ${VAR:offset}et ${VAR:offset:length}, mais pas la casse comme ${VAR^}, ${VAR,}, etc. Vous pouvez faire la conversion de cas typeset -let typeset -udans les deux bash et ksh.
Ils prennent en charge le remplacement par ${VAR/PATTERN/STRING}ou ${VAR/PATTERN//STRING}. Les règles de citation pour STRING sont légèrement différentes, donc évitez les barres obliques inverses (et peut-être d'autres caractères) dans STRING (créez une variable et utilisez-la à la ${VAR/PATTERN/$REPLACEMENT}place si le remplacement contient des caractères de citation).
Expansion Array ( ${ARRAY[KEY]}, "${ARRAY[@]}", ${#ARRAY[@]}, ${!ARRAY[@]}) travaillent dans bash comme dans ksh.
${!VAR}développer jusqu'à ${OTHERVAR}quand la valeur de VARis OTHERVAR(référence de variable indirecte) est spécifique à bash (ksh fait quelque chose de différent avec ${!VAR}). Pour obtenir cette double expansion dans ksh, vous devez utiliser une référence de nom à la place ( typeset -n VAR=OTHERVAR; echo "$VAR"). ${!PREFIX*}fonctionne de la même manière.
Substitution de processus <(…)et >(…)prise en charge dans ksh93 mais pas dans mksh.
Les modèles glob étendus ksh qui doivent shopt -s extglobêtre activés dans bash sont toujours disponibles dans ksh93 et mksh.
Mksh ne prend pas en charge les classes de caractères comme [[:alpha:]].
Bash et ksh93 définissent des pseudo-fichiers et , mais pas mksh./dev/tcp/HOST/PORT/dev/udp/HOST/PORT
L'expansion des caractères génériques dans une redirection dans les scripts (comme dans l' var="*.txt"; echo hello >$aécriture a.txtsi ce nom de fichier est la seule correspondance pour le modèle) est une fonctionnalité spécifique à bash (les autres shells ne le font jamais dans les scripts).
<<< ici les chaînes fonctionnent en ksh comme en bash.
Le raccourci >&pour rediriger les erreurs de syntaxe est également pris en charge par mksh mais pas par ksh93.
[[ … ]] syntaxe double parenthèse
La syntaxe du double crochet de ksh est prise en charge par ATT ksh93 et mksh comme dans bash.
Opérateurs de fichiers
Ksh93, mksh et bash prennent en charge les mêmes extensions de POSIX, y compris en -atant que synonyme obsolète de -e, -k(collant), -G(détenu par egid), -O(propriétaire par euid), -ef(même fichier), -nt(plus récent que), -ot(plus ancien que).
-N FILE (modifié depuis la dernière lecture) n'est pas pris en charge par mksh.
Mksh n'a pas d'opérateur de correspondance d'expressions rationnelles =~. Ksh93 a cet opérateur, et il effectue la même correspondance que dans bash, mais n'a pas d'équivalent BASH_REMATCHpour récupérer les groupes correspondants par la suite.
Opérateurs de chaîne
Ksh93 et mksh prennent en charge les mêmes opérateurs de comparaison de chaînes <et >comme bash ainsi que le ==synonyme de =. Mksh n'utilise pas les paramètres régionaux pour déterminer l'ordre lexicographique, il compare les chaînes comme des chaînes d'octets.
Autres opérateurs
-v VARpour tester si une variable est définie est spécifique à bash. Dans n'importe quel shell POSIX, vous pouvez utiliser [ -z "${VAR+1}" ].
L'ensemble des caractères autorisés dans les noms d'alias n'est pas le même dans tous les shells. Je pense que c'est la même chose que pour les fonctions (voir ci-dessus).
Ksh93 a un builtin appelé builtin, mais il n'exécute pas de nom en tant que commande intégrée. Utilisez commandpour contourner les alias et les fonctions; cela appellera un builtin s'il en existe un, sinon une commande externe (vous pouvez éviter cela avec PATH= command error_out_if_this_is_not_a_builtin).
Ceci est spécifique à bash. Vous pouvez obtenir un effet similaire avec .sh.fun, .sh.fileet .sh.linenodans ksh93. En mksh, il y a enfin LINENO.
declareest un nom spécifique à bash pour ksh typeset. Utilisation typeset: ça marche aussi en bash.
Mksh définit localcomme un alias pour typeset. Dans ksh93, vous devez utiliser typeset(ou définir un alias).
Mksh n'a pas de tableaux associatifs (ils sont prévus pour une version encore inédite).
Je ne pense pas qu'il y ait un équivalent exact de bash typeset -t(fonction trace) dans ksh.
Ksh93 n'en a pas -e.
Ksh93 et mksh traitent les options -eet -ncomme dans bash. Mksh comprend également que -Eksh93 ne le traite pas comme une option. L'expansion de barre oblique inverse est désactivée par défaut dans ksh93, activée par défaut dans mksh.
Ksh ne fournit pas un moyen de désactiver les commandes intégrées. Pour éviter une intégration, recherchez le chemin de la commande externe et invoquez-le explicitement.
Ksh93 a -amais pas -l. Mksh n'a ni l'un ni l'autre.
Ni ksh93 ni mksh ne l'ont fait export -n. Utilisez à la typeset +x fooplace, cela fonctionne en bash et ksh.
Ksh n'exporte pas de fonctions via l'environnement.
let est le même en bash et ksh.
Il s'agit d'une fonctionnalité spécifique à bash. Vous pouvez utiliser des while readboucles ou une substitution de commande pour lire un fichier et le diviser en un tableau de lignes. Prenez soin de vous IFSet globulez. Voici l'équivalent de mapfile -t lines </path/to/file:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printfest très similaire. Je pense que ksh93 prend en charge toutes les directives de format de bash. mksh ne prend pas en charge %qou %(DATE_FORMAT)T; sur certaines installations, printfn'est pas un module intégré mksh et appelle la commande externe à la place.
printf -v VAR est spécifique à bash, ksh imprime toujours sur la sortie standard.
Plusieurs options sont spécifiques à bash, y compris toutes celles concernant readline. Les options -r, -d, -n, -N, -t, -usont identiques dans bash, ksh93 et mksh.
Vous pouvez déclarer une variable en lecture seule dans Ksh93 et mksh avec la même syntaxe. Si la variable est un tableau, vous devez d'abord l'affecter, puis la rendre en lecture seule avec readonly VAR. Les fonctions ne peuvent pas être rendues en lecture seule dans ksh.
Toutes les options de setet set -osont des fonctionnalités POSIX ou ksh.
shoptest spécifique à bash. De nombreuses options concernent de toute façon une utilisation interactive. Pour les effets sur la globalisation et d'autres fonctionnalités activées par certaines options, consultez la section «Options» ci-dessous.
Cette variante de .existe également dans ksh. Dans bash et mksh, sourcerecherche le répertoire courant après PATH, mais dans ksh93, c'est exactement l'équivalent de ..
Le DEBUGpseudo-signal n'est pas implémenté dans mksh. Dans ksh93, il existe avec une manière différente de rapporter les informations, voir le manuel pour plus de détails.
Dans ksh, typeest un alias pour whence -v. Dans mksh, type -pn'imprime pas le chemin vers l'exécutable, mais un message lisible par l'homme; vous devez utiliser à la whence -p COMMANDplace.
Les options
shopt -s dotglob - n'ignorez pas les fichiers dot dans le globbing
Pour émuler l' dotgloboption dans ksh93, vous pouvez définir FIGNORE='@(.|..)'. Je ne pense pas qu'il y ait quelque chose comme ça dans mksh.
L' extgloboption est effectivement toujours activée dans ksh.
shopt -s failglob - erreur si un motif global ne correspond à rien
Je ne pense pas que cela existe dans mksh ou ksh93. Il le fait en zsh (comportement par défaut sauf si null_globou csh_null_globsont définis).
Ksh93 a un globbing récursif avec **/, activé avec set -G. Mksh n'a pas de globulation récursive.
shopt -s lastpipe - exécuter la dernière commande d'un pipeline dans le shell parent
Ksh93 exécute toujours la dernière commande d'un pipeline dans le shell parent, qui en bash nécessite que l' lastpipeoption soit définie. Mksh exécute toujours la dernière commande d'un pipeline dans un sous-shell.
shopt -s nocaseglob, shopt -s nocasematch- motifs insensibles à la casse
Mksh n'a pas de correspondance de modèle insensible à la casse. Ksh93 le prend en charge modèle par modèle: préfixez le modèle avec ~(i).
shopt -s nullglob - développer des modèles qui ne correspondent à aucun fichier à une liste vide
Mksh n'a pas ça. Ksh93 le prend en charge modèle par modèle: préfixez le modèle avec ~(N).
De toute évidence, la plupart des BASH_xxxvariables n'existent pas dans ksh. $BASHPIDpeut être émulé avec le coûteux mais portable sh -c 'echo $PPID', et a été récemment ajouté à mksh. BASH_LINEest .sh.linenoen ksh93 et LINENOen mksh. BASH_SUBSHELLest .sh.subshellen ksh93.
Mksh et ksh93 source tous les deux le fichier donné au ENVdémarrage.
EUIDet UIDn'existent pas dans ksh93. Mksh les appelle USER_IDet KSH_UID; il n'en a pas GROUPS.
FUNCNAMEet FUNCNESTn'existent pas dans ksh. Ksh93 a .sh.funet .sh.level. Les fonctions déclarées avec function foo { …; }(pas de parenthèses!) Ont leur propre nom dans $0.
GLOBIGNOREexiste dans ksh93 mais avec un nom et une syntaxe différents: il est appelé FIGNORE, et c'est un modèle unique, pas une liste séparée par deux-points. Utilisez un @(…|…)modèle. Les subsumes de FIGNOREKsh bash, avec une syntaxe complètement différente.
Ksh93 et mksh n'ont rien de semblable HOSTTYPE, MACHTYPEet OSTYPE. Ni SHELLOPTSou TIMEFORMAT.
Mksh l'a fait PIPESTATUS, mais pas ksh93.
Mksh et ksh93 ont RANDOM.