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 sh
shell 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 case
dé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 function
dans 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 -l
et typeset -u
dans 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 VAR
is 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.txt
si 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 -a
tant 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_REMATCH
pour 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 VAR
pour 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 command
pour 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.file
et .sh.lineno
dans ksh93. En mksh, il y a enfin LINENO
.
declare
est un nom spécifique à bash pour ksh typeset
. Utilisation typeset
: ça marche aussi en bash.
Mksh définit local
comme 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 -e
et -n
comme dans bash. Mksh comprend également que -E
ksh93 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 -a
mais 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 foo
place, 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 read
boucles ou une substitution de commande pour lire un fichier et le diviser en un tableau de lignes. Prenez soin de vous IFS
et globulez. Voici l'équivalent de mapfile -t lines </path/to/file
:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printf
est très similaire. Je pense que ksh93 prend en charge toutes les directives de format de bash. mksh ne prend pas en charge %q
ou %(DATE_FORMAT)T
; sur certaines installations, printf
n'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
, -u
sont 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 set
et set -o
sont des fonctionnalités POSIX ou ksh.
shopt
est 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, source
recherche le répertoire courant après PATH
, mais dans ksh93, c'est exactement l'équivalent de .
.
Le DEBUG
pseudo-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, type
est un alias pour whence -v
. Dans mksh, type -p
n'imprime pas le chemin vers l'exécutable, mais un message lisible par l'homme; vous devez utiliser à la whence -p COMMAND
place.
Les options
shopt -s dotglob
- n'ignorez pas les fichiers dot dans le globbing
Pour émuler l' dotglob
option dans ksh93, vous pouvez définir FIGNORE='@(.|..)'
. Je ne pense pas qu'il y ait quelque chose comme ça dans mksh.
L' extglob
option 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_glob
ou csh_null_glob
sont 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' lastpipe
option 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_xxx
variables n'existent pas dans ksh. $BASHPID
peut être émulé avec le coûteux mais portable sh -c 'echo $PPID'
, et a été récemment ajouté à mksh. BASH_LINE
est .sh.lineno
en ksh93 et LINENO
en mksh. BASH_SUBSHELL
est .sh.subshell
en ksh93.
Mksh et ksh93 source tous les deux le fichier donné au ENV
démarrage.
EUID
et UID
n'existent pas dans ksh93. Mksh les appelle USER_ID
et KSH_UID
; il n'en a pas GROUPS
.
FUNCNAME
et FUNCNEST
n'existent pas dans ksh. Ksh93 a .sh.fun
et .sh.level
. Les fonctions déclarées avec function foo { …; }
(pas de parenthèses!) Ont leur propre nom dans $0
.
GLOBIGNORE
existe 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 FIGNORE
Ksh bash, avec une syntaxe complètement différente.
Ksh93 et mksh n'ont rien de semblable HOSTTYPE
, MACHTYPE
et OSTYPE
. Ni SHELLOPTS
ou TIMEFORMAT
.
Mksh l'a fait PIPESTATUS
, mais pas ksh93.
Mksh et ksh93 ont RANDOM
.