Il y a quelques différences qui me viennent à l'esprit ; je ne fais que réfléchir, sans ordre particulier :
-
Python & Co. sont conçus pour être bons en scripting. Bash & Co. sont conçus pour être seulement bon en script, sans aucun compromis. Autrement dit, Python est conçu pour être bon à la fois pour les scripts et pour les autres applications, alors que Bash ne s'intéresse qu'aux scripts.
-
Bash & Co. sont non typés, Python & Co. sont fortement typés, ce qui signifie que le nombre 123
la chaîne 123
et le fichier 123
sont très différentes. Ils ne sont cependant pas statiquement typés, ce qui signifie qu'ils doivent avoir des littéraux différents pour ceux-ci, afin de les séparer.
Exemple :
| Ruby | Bash
-----------------------------------------
number | 123 | 123
string | '123' | 123
regexp | /123/ | 123
file | File.open('123') | 123
file descriptor | IO.open('123') | 123
URI | URI.parse('123') | 123
command | `123` | 123
-
Python & Co. sont conçus pour être évolutifs en haut à des programmes de 10000, 100000, peut-être même 1000000 lignes, Bash & Co. sont conçus pour évoluer en bas à 10 caractère programmes.
-
En Bash & Co, les fichiers, les répertoires, les descripteurs de fichiers, les processus sont tous des objets de première classe, en Python, seuls les objets Python sont de première classe, si vous voulez manipuler des fichiers, des répertoires etc , vous devez d'abord les envelopper dans un objet Python.
-
La programmation Shell est fondamentalement une programmation par flux de données. Personne ne s'en rend compte, pas même les personnes qui écrivent les shells, mais il s'avère que les shells sont assez bons pour cela, et les langages à usage général pas tellement. Dans le monde de la programmation à usage général, le flux de données semble être considéré comme un modèle de concurrence et non comme un paradigme de programmation.
J'ai le sentiment que tenter de résoudre ces problèmes en ajoutant des fonctionnalités ou des DSL à un langage de programmation polyvalent ne fonctionne pas. Du moins, je n'ai pas encore vu d'implémentation convaincante de cette méthode. Il existe RuSH (Ruby shell), qui tente d'implémenter un shell en Ruby, il y a aussi ruée vers qui est un DSL interne pour la programmation du shell en Ruby. Hotwire qui est un shell Python, mais aucun d'entre eux ne peut rivaliser avec Bash, Zsh, fish et leurs amis.
En fait, IMHO, la meilleure coquille actuelle est Microsoft PowerShell ce qui est très surprenant étant donné que pour plusieurs décennies Aujourd'hui, Microsoft a toujours eu le pire coquilles evar . Je veux dire, COMMAND.COM
? Vraiment ? (Malheureusement, ils ont toujours un terminal merdique. C'est toujours l'"invite de commande" qui existe depuis, quoi ? Windows 3.0 ?)
PowerShell a été créé en ignorant tout ce que Microsoft a fait jusqu'à présent ( COMMAND.COM
, CMD.EXE
VBScript, JScript) et de partir de l'interpréteur de commandes Unix, puis de supprimer tous les éléments de rétrocompatibilité (comme les backticks pour la substitution des commandes) et de les modifier un peu pour les rendre plus adaptés à Windows (comme l'utilisation du backtick, désormais inutilisé, comme caractère d'échappement au lieu de la barre oblique inversée qui est le caractère de séparation des composants du chemin dans Windows). C'est ensuite que la magie opère.
Ils abordent problèmes 1 et 3 d'en haut, en faisant essentiellement le choix inverse par rapport à Python. Python s'intéresse d'abord aux grands programmes, puis aux scripts. Bash ne s'intéresse qu'aux scripts. PowerShell s'intéresse d'abord aux scripts, puis aux grands programmes. Un moment décisif pour moi a été de regarder la vidéo d'une interview de Jeffrey Snover (le concepteur principal de PowerShell). L'intervieweur lui a demandé quelle taille de programme on pouvait écrire avec PowerShell et Snover a répondu sans hésiter : "80 caractères". À ce moment-là, j'ai réalisé que c'est enfin un gars chez Microsoft qui "comprend" la programmation shell (probablement en rapport avec le fait que PowerShell était ni développé par le groupe chargé des langages de programmation de Microsoft (c'est-à-dire les nerds des mathématiques du lambda-calcul) ni par le groupe chargé des systèmes d'exploitation (les nerds du noyau), mais plutôt par le groupe chargé des serveurs (c'est-à-dire les administrateurs système qui, en fait utiliser shells)), et que je devrais probablement me pencher sérieusement sur PowerShell.
Numéro 2 est résolu en faisant en sorte que les arguments soient typés statiquement. Ainsi, vous pouvez écrire simplement 123
et PowerShell sait s'il s'agit d'une chaîne de caractères, d'un nombre ou d'un fichier, car la cmdlet (c'est ainsi que l'on appelle les commandes shell dans PowerShell) déclare les types de ses arguments au shell. Cela a des ramifications assez profondes : contrairement à Unix, où chaque commande est responsable de l'analyse de ses propres arguments (l'interpréteur de commandes transmet essentiellement les arguments sous la forme d'un tableau de chaînes), l'analyse des arguments dans PowerShell est effectuée par la commande coquille . Les cmdlets spécifient toutes leurs options, tous leurs drapeaux et tous leurs arguments, ainsi que leurs types, leurs noms et leur documentation ( !) à l'interpréteur de commandes, qui peut alors effectuer l'analyse des arguments, la complétion de tabulation, l'IntelliSense, les popups de documentation en ligne, etc. en un seul endroit centralisé. (Ceci n'est pas révolutionnaire, et les concepteurs de PowerShell reconnaissent les shells tels que le DIGITAL Command Language (DCL) et le IBM OS/400 Command Language (CL) comme de l'art antérieur. Pour quiconque a déjà utilisé un AS/400, cela devrait vous sembler familier. Dans l'OS/400, vous pouvez écrire une commande shell et si vous ne connaissez pas la syntaxe de certains arguments, vous pouvez simplement les laisser de côté et appuyer sur la touche F4 qui fera apparaître un menu (similaire à un formulaire HTML) avec des champs étiquetés, une liste déroulante, des textes d'aide, etc. Ceci n'est possible que parce que le système d'exploitation connaît tous les arguments possibles et leurs types). Dans l'interpréteur de commandes Unix, ces informations sont souvent dupliquées trois fois : dans le code d'analyse des arguments de la commande elle-même, dans la section bash-completion
script pour la complétion des tabulations et dans la page de manuel.
Numéro 4 est résolu par le fait que PowerShell opère sur des objets fortement typés, ce qui inclut des choses comme les fichiers, les processus, les dossiers, etc.
Numéro 5 est particulièrement intéressant, parce que PowerShell est le seul shell que je connaisse, où les personnes qui l'ont écrit étaient en fait conscient du fait que les shells sont essentiellement des moteurs de flux de données et l'a délibérément implémenté comme un moteur de flux de données.
Une autre caractéristique intéressante de PowerShell est la convention de dénomination : toutes les cmdlets sont nommées Action-Object
et de plus, il existe également des noms normalisés pour des actions et des objets spécifiques. (Encore une fois, cela devrait être familier aux utilisateurs de l'OS/400.) Par exemple, tout ce qui est lié à la réception d'une information est appelé Get-Foo
. Et tout ce qui opère sur des (sous-)objets est appelé Bar-ChildItem
. Donc, l'équivalent de ls
es Get-ChildItem
(bien que PowerShell fournisse également des alias intégrés). ls
y dir
- en fait, chaque fois que cela a un sens, ils fournissent à la fois Unix et CMD.EXE
les alias ainsi que les abréviations ( gci
dans ce cas)).
Mais le caractéristique dominante IMO est le pipeline d'objets fortement typés. Bien que PowerShell soit dérivé de l'interpréteur de commandes Unix, il existe une distinction très importante : dans Unix, toutes les communications (à la fois via les pipes et les redirections ainsi que via les arguments de commande) se font avec des chaînes de caractères non typées et non structurées. Dans PowerShell, il s'agit d'objets structurés et fortement typés. C'est tellement puissant que je me demande sérieusement pourquoi personne d'autre n'y a pensé. (Dans mon shell scripts, j'estime que jusqu'à un tiers des commandes ne sont là que pour servir d'adaptateur entre deux autres commandes qui ne sont pas d'accord sur un format textuel commun. Beaucoup de ces adaptateurs disparaissent dans PowerShell, car les cmdlets échangent des objets structurés plutôt que du texte non structuré. Et si vous regardez à l'intérieur de les commandes, alors elles se composent essentiellement de trois étapes : analyser l'entrée textuelle en une représentation d'objet interne, manipuler les objets, les reconvertir en texte. Encore une fois, les première et troisième étapes disparaissent, car les données arrivent déjà sous forme d'objets.
Cependant, les concepteurs ont pris soin de préserver la dynamique et la flexibilité du scriptage shell grâce à ce qu'ils appellent un "système d'exploitation". Système de type adaptatif .
Bref, je ne veux pas transformer ça en une publicité pour PowerShell. Il y a plein de choses qui sont no La plupart d'entre elles ont trait soit à Windows, soit à l'implémentation spécifique, et pas tellement aux concepts. (Par exemple, le fait qu'il soit implémenté en .NET signifie que le tout premier démarrage du shell peut prendre plusieurs secondes si le framework .NET n'est pas déjà dans le cache du système de fichiers à cause d'une autre application qui en a besoin. Si l'on considère que vous utilisez souvent le shell pendant bien moins d'une seconde, c'est totalement inacceptable).
Le point le plus important que je veux souligner est que si vous voulez examiner les travaux existants dans les langages de script et les shells, vous ne devez pas vous arrêter à Unix et à la famille Ruby/Python/Perl/PHP . Par exemple, Tcl a déjà été mentionné. Rexx serait un autre langage de script. Emacs Lisp en serait une autre. Et dans le domaine des interpréteurs de commandes, il y a certains des interpréteurs de commandes mainframe/midrange déjà mentionnés, comme la ligne de commande OS/400 et DCL. Et aussi, rc.