Dans quelle mesure d'autres shells compatibles POSIX peuvent-ils fonctionner comme des remplacements raisonnables pour bash? Ils n'ont pas besoin d'être de véritables remplacements "drop-in", mais suffisamment proches pour fonctionner avec la plupart des scripts et prendre en charge le reste avec quelques modifications.
Je veux que les scripts bash explicites - initscripts, scripts client DHCP, etc. - fonctionnent avec un minimum de modifications
Je veux que ma propre collection de scripts shell plus spécialisés n'ait pas besoin de trop de modifications
Je veux avoir des fonctionnalités comme la manipulation de chaînes et la correspondance de motifs regex intégrée
Les seuls prétendants sérieux que je connaisse sont zsh et mksh. Donc, pour ceux d'entre vous ici qui sont bons avec l'un ou les deux:
Quelles sont les fonctionnalités de bash que zsh et mksh respectivement n'ont pas?
Quelles fonctionnalités les shells partagent avec bash, mais utilisent une syntaxe incompatible pour?
bash
, mksh et zsh peuvent fonctionner comme/bin/sh
avec différents niveaux de correction, mais pasbash
.Réponses:
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.Syntaxe du shell
Citant
$'…'
(chaînes littérales avec interpolation antislash) est disponible en ksh93 et mksh. `$"… "(Chaînes traduites) est spécifique à bash.Constructions conditionnelles
Mksh et ksh93 doivent
;&
passer par unecase
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.Coprocessus
Ksh et bash ont tous deux des coprocessus mais ils fonctionnent différemment.
Les fonctions
Mksh et ksh93 prennent en charge la
function name {…}
syntaxe des définitions de fonction en plus de la normename () {…}
, mais l'utilisationfunction
dans ksh modifie les règles de portée, donc respectez laname () …
compatibilité. Les règles pour les caractères autorisés dans les noms de fonction varient; s'en tenir aux alphanumériques et_
.Expansion du corset
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.Expansion des paramètres
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 castypeset -l
ettypeset -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 deVAR
isOTHERVAR
(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
Substitution de processus
<(…)
et>(…)
prise en charge dans ksh93 mais pas dans mksh.Motifs génériques
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:]]
.Redirection d'E / S
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
écriturea.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.Expressions conditionnelles
[[ … ]]
syntaxe double parenthèseLa 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'équivalentBASH_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}" ]
.Builtins
alias
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).
builtin
Ksh93 a un builtin appelé
builtin
, mais il n'exécute pas de nom en tant que commande intégrée. Utilisezcommand
pour contourner les alias et les fonctions; cela appellera un builtin s'il en existe un, sinon une commande externe (vous pouvez éviter cela avecPATH= command error_out_if_this_is_not_a_builtin
).caller
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 enfinLINENO
.declare
,local
,typeset
declare
est un nom spécifique à bash pour kshtypeset
. Utilisationtypeset
: ça marche aussi en bash.Mksh définit
local
comme un alias pourtypeset
. Dans ksh93, vous devez utilisertypeset
(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.cd
Ksh93 n'en a pas
-e
.echo
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.enable
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.
exec
Ksh93 a
-a
mais pas-l
. Mksh n'a ni l'un ni l'autre.export
Ni ksh93 ni mksh ne l'ont fait
export -n
. Utilisez à latypeset +x foo
place, cela fonctionne en bash et ksh.Ksh n'exporte pas de fonctions via l'environnement.
let
let
est le même en bash et ksh.mapfile
,readarray
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 vousIFS
et globulez. Voici l'équivalent demapfile -t lines </path/to/file
:printf
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.read
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.readonly
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.set
,shopt
Toutes les options de
set
etset -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.source
Cette variante de
.
existe également dans ksh. Dans bash et mksh,source
recherche le répertoire courant aprèsPATH
, mais dans ksh93, c'est exactement l'équivalent de.
.trap
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.type
Dans ksh,
type
est un alias pourwhence -v
. Dans mksh,type -p
n'imprime pas le chemin vers l'exécutable, mais un message lisible par l'homme; vous devez utiliser à lawhence -p COMMAND
place.Les options
shopt -s dotglob
- n'ignorez pas les fichiers dot dans le globbingPour émuler l'
dotglob
option dans ksh93, vous pouvez définirFIGNORE='@(.|..)'
. Je ne pense pas qu'il y ait quelque chose comme ça dans mksh.shopt -s extglob
- modèles de glob étendus kshL'
extglob
option est effectivement toujours activée dans ksh.shopt -s failglob
- erreur si un motif global ne correspond à rienJe ne pense pas que cela existe dans mksh ou ksh93. Il le fait en zsh (comportement par défaut sauf si
null_glob
oucsh_null_glob
sont définis).shopt -s globstar
-**/
globbing récursifKsh93 a un globbing récursif avec
**/
, activé avecset -G
. Mksh n'a pas de globulation récursive.shopt -s lastpipe
- exécuter la dernière commande d'un pipeline dans le shell parentKsh93 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 casseMksh 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 videMksh n'a pas ça. Ksh93 le prend en charge modèle par modèle: préfixez le modèle avec
~(N)
.Variables
De toute évidence, la plupart des
BASH_xxx
variables n'existent pas dans ksh.$BASHPID
peut être émulé avec le coûteux mais portablesh -c 'echo $PPID'
, et a été récemment ajouté à mksh.BASH_LINE
est.sh.lineno
en ksh93 etLINENO
en mksh.BASH_SUBSHELL
est.sh.subshell
en ksh93.Mksh et ksh93 source tous les deux le fichier donné au
ENV
démarrage.EUID
etUID
n'existent pas dans ksh93. Mksh les appelleUSER_ID
etKSH_UID
; il n'en a pasGROUPS
.FUNCNAME
etFUNCNEST
n'existent pas dans ksh. Ksh93 a.sh.fun
et.sh.level
. Les fonctions déclarées avecfunction 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 deFIGNORE
Ksh bash, avec une syntaxe complètement différente.Ksh93 et mksh n'ont rien de semblable
HOSTTYPE
,MACHTYPE
etOSTYPE
. NiSHELLOPTS
ouTIMEFORMAT
.Mksh l'a fait
PIPESTATUS
, mais pas ksh93.Mksh et ksh93 ont
RANDOM
.la source
$BASHPID
on émulersh -c 'echo $PPID'
? J'ai essayé(sh -c 'echo $PPID')
dans Bash mais ça me donne le même PID que$$
.Cette question est un peu trop large.
Les deux mksh et zsh sont des shells qui prennent en charge de nombreuses extensions spécifiques à GNU bash , mais il y en a toujours qui ne sont pas comprises.
zsh prend en charge plus de choses, mais uniquement dans son mode natif zsh, qui n'est pas compatible avec les shells POSIX (tels que GNU bash, AT&T ksh93 , mksh). De plus, mksh est beaucoup plus léger, plus rapide et plus portable.
En général, si ce sont vos scripts dont nous parlons, allez-y, testez-les simplement. (mksh ne prend pas encore en charge les tableaux associatifs de style bash4. La commande "declare" est spécifique à bash, "typeset" est un équivalent. Je ne connais pas suffisamment zsh pour dire quoi que ce soit à ce sujet. ksh93 n'a pas "local" mais utilise également "typeset" pour cela.) Mais s'il s'agit, par exemple, d'exécuter un système Debian sans bash, oubliez-le. L'existence de bash fait partie de la «promesse» (API / ABI du système) et en dépend beaucoup.
Avertissement: je suis le développeur mksh.
la source
Comparaison des coques ZSH
Je ne connais pas très bien mksh, donc je ne sais pas où chercher cette réponse.
Si vous recherchez un remplacement sécurisé pour le shell, aucun de ces shells ne diffère beaucoup de Bash en ce qui concerne le défaut inhérent dont vous parlez.
Un langage comme Perl gère les entrées de manière plus sécurisée. Mais la maintenabilité est également essentielle ici. Le remplacement de la coque Perl n'est pas très bien adopté. Il incombe au responsable du shell de gérer les entrées en toute sécurité. Alors quand vous écrivez des scripts, validez, validez, validez tout! Utilisez des contrats de code pour garantir des résultats corrects à chaque fois!
Coquille Perl
Déclaration de la FSF sur Shell Shock
la source
L' historique du shell n'est pas activé par défaut dans
mksh
.Dans votre
.mkshrc
ensemble juste:export HISTFILE=~/.mksh-history
la source