J'ai remarqué beaucoup de questions et réponses et de commentaires exprimant du dédain pour (et parfois même la peur de) l'écriture de scripts au lieu de lignes simples. Je voudrais donc savoir:
Quand et pourquoi devrais-je écrire un script autonome plutôt qu'un "one-liner"? Ou vice versa?
Quels sont les cas d'utilisation et les avantages et inconvénients des deux?
Certaines langues (par exemple awk ou perl) sont-elles mieux adaptées aux lignes simples que d'autres (par exemple python)? Si oui, pourquoi?
S'agit-il simplement d'une préférence personnelle ou existe-t-il de bonnes raisons (c'est-à-dire objectives) d'écrire l'une ou l'autre dans des circonstances particulières? Quelles sont ces raisons?
Définitions
one-liner
: toute séquence de commandes tapées ou collées directement dans une ligne de commande shell . Souvent liés à des pipelines et / ou l' utilisation des langues telles quesed
,awk
,perl
et / ou des outils similairesgrep
oucut
ousort
.C'est l'exécution directe sur la ligne de commande qui est la caractéristique déterminante - la longueur et le formatage ne sont pas pertinents. Un "one-liner" peut être tout sur une seule ligne, ou il peut avoir plusieurs lignes (par exemple sh pour la boucle, ou un code awk ou sed intégré, avec des sauts de ligne et une indentation pour améliorer la lisibilité).
script
: toute séquence de commandes dans n'importe quel langage interprété qui sont enregistrées dans un fichier , puis exécutées. Un script peut être écrit entièrement dans une langue, ou il peut être un wrapper de script shell autour de plusieurs "one-liners" utilisant d'autres langues.
J'ai ma propre réponse (que je publierai plus tard), mais je veux que cela devienne un Q&A canonique sur le sujet, pas seulement mon opinion personnelle.
Réponses:
Une autre réponse basée sur l'expérience pratique.
J'utiliserais un one-liner si c'était du code "jetable" que je pourrais écrire directement à l'invite. Par exemple, je pourrais utiliser ceci:
J'utiliserais un script si je décidais que le code valait la peine d'être sauvegardé. À ce stade, j'ajouterais une description en haut du fichier, ajouterais probablement quelques vérifications d'erreurs, et peut-être même les archiver dans un référentiel de code pour le contrôle de version. Par exemple, si je décidais que la vérification du temps de disponibilité d'un ensemble de serveurs était une fonction utile que j'utiliserais encore et encore, le one-liner ci-dessus pourrait être étendu à ceci:
Généralisant, on pourrait dire
Bon mot
Scénario
cron
)Je vois un bon nombre de questions ici sur unix.SE demander un one-liner pour effectuer une tâche particulière. En utilisant mes exemples ci-dessus, je pense que le second est beaucoup plus compréhensible que le premier, et donc les lecteurs peuvent en apprendre davantage. Une solution peut être facilement dérivée de l'autre, donc dans un souci de lisibilité (pour les futurs lecteurs), nous devrions probablement éviter de fournir du code coincé sur une seule ligne pour autre chose que la plus triviale des solutions.
la source
set -- host1 host2 host3
alors utiliserfor h in "$@"
(ou simplementfor h
), ce qui rendrait le script POSIX portable. :-)Écrivez un script lorsque:
Écrivez une ligne unique lorsque:
la source
Lorsqu'une série de commandes requise est assez courte et / ou produit un résultat qui pourrait être utilisable dans le cadre d'un pipeline plus grand ou d'un alias de commande, il peut s'agir d'une bonne ligne unique.
Fondamentalement, je pense que les monolignes sont généralement des choses qu'un administrateur système chevronné connaissant à la fois le problème et les commandes utilisées peut écrire sur place, sans trop réfléchir.
Quand une ligne devient excessivement longue ou implique plus que des conditions ou des boucles très simples, il est généralement préférable de les écrire sous forme de script multi-lignes ou de fonction shell, pour plus de lisibilité. De plus, si c'est quelque chose que vous écrivez pour être utilisé encore et encore, ou quelque chose qui sera utilisé (et éventuellement dépanné) par d'autres personnes, vous devriez être prêt à passer le temps d'écrire la solution dans un langage clair (er), a commenté, formulaire de script.
En Python, l'indentation fait partie de la syntaxe, donc vous ne pouvez littéralement pas utiliser pleinement les fonctionnalités du langage si vous écrivez une seule ligne.
Les lignes simples Perl et awk consistent souvent à utiliser la puissance brute des expressions régulières. Mais certains appellent les expressions régulières un langage en écriture seule, pas entièrement sans raison. L'écriture d'un script multi-lignes vous permet d'écrire dans des commentaires pour décrire ce qu'une expression régulière particulière est censée faire, ce qui sera très utile lorsque vous relisez le script, après avoir fait autre chose pendant six mois entre les deux.
Il s'agit d'une question intrinsèquement très fondée sur l'opinion, car elle implique d'évaluer la complexité acceptable et les compromis entre lisibilité et compacité; toutes ces questions relèvent essentiellement du jugement personnel. Même le choix d'une langue peut dépendre de questions personnelles: si une langue particulière est théoriquement optimale pour un problème particulier, mais que vous ne la connaissez pas et savez déjà comment résoudre le problème avec une autre langue, vous pouvez choisir la un langage familier afin de faire le travail rapidement et avec un minimum d'effort, bien que la solution puisse être techniquement quelque peu inefficace.
Le meilleur est souvent l'ennemi du bien , et cela s'applique beaucoup ici.
Et si vous connaissez Perl, vous avez peut-être déjà entendu parler de TMTOWTDI: il y a plus d'une façon de le faire.
la source
Veuillez noter qu'il s'agit d'une opinion personnelle; Prenez-le avec un grain de sel.
Si la commande tient dans, disons, 80 caractères, utilisez une ligne. Les longues lignes de commande sont difficiles à utiliser. Il y a aussi le problème de récidive, voir # 2
Si vous devez exécuter la ou les commandes plusieurs fois, utilisez un script. Sinon, utilisez une doublure, à condition que la condition n ° 1 soit remplie.
la source
Je vois et j'utilise un one-liner comme un outil de développement temporaire pour éditer à plusieurs reprises jusqu'à ce qu'il fasse ce que je veux, ou je comprends comment une subtilité d'une sous-commande fonctionne.
Il est ensuite soit noté (et annoté) dans un fichier texte sur le sujet sur lequel j'étudiais, soit nettoyé dans un script qui est mis dans mon bac personnel PATH, éventuellement pour un raffinement, un paramétrage, etc. En règle générale, la seule ligne sera divisée en plus lisible, même si aucune autre modification n'est apportée, ou si je n'utilise plus jamais le script.
J'ai défini mon historique de shell sur plus de 5 000 lignes, avec un historique distinct par terminal et par connexion sur une télécommande, etc. Je déteste ne pas pouvoir trouver dans ces histoires une commande en ligne que j'ai développée il y a quelques semaines et que je ne pensais pas avoir besoin à nouveau, d'où ma stratégie.
Parfois, un groupe entier de commandes doit faire quelque chose, comme configurer du matériel; à la fin, je les copie tous de l'historique, les nettoie au minimum et les ajoute à un script shell
RUNME
juste comme des notes sur ce que j'ai fait, mais aussi pour qu'ils soient presque prêts à être réutilisés par quelqu'un d'autre. (C'est pourquoi je trouve des outils qui ne fournissent qu'une interface graphique pour les configurer.) .la source
ln
vsln -s
pour les liens durs vs soft dans une ligne qui boucle sur certains fichiers.Je souhaiterais que les membres de mon équipe écrivent des scripts pour toutes les opérations pouvant être exécutées plusieurs fois (par exemple, "workflows" ou "pipelines"), et pour toute tâche ponctuelle qui doit être documentée (généralement des choses comme "modifier certaines choses dans un ensemble de données pour corriger des données incorrectement fournies" dans notre cas). En dehors de cela, les "one-liners" ou les scripts n'ont pas trop d'importance.
Le fait de ne pas documenter correctement les flux de travail (sous forme de scripts ou équivalent) rend plus difficile l'introduction de nouveaux employés sur un projet, et rend également plus difficile la transition de personnes hors d'un projet. De plus, cela rend tout type d'audit difficile et le suivi des bogues peut être impossible.
Ceci indépendamment du langage utilisé pour la programmation.
D'autres lieux de travail peuvent avoir des coutumes ou des attentes similaires / différentes, peut-être même écrites.
À la maison, vous faites ce que vous voulez.
Par exemple, j'écris des scripts dès que je fais quelque chose de non trivial dans le shell, comme avant de soumettre une réponse à une question U&L, ou chaque fois que j'ai besoin de tester les composants individuels d'une commande ou d'un ensemble de commandes avant de l'exécuter "pour réal".
J'écris également des scripts pour des tâches répétitives que je veux vraiment faire de la même manière à chaque fois, même si elles sont simples, comme
J'utilise des fonctions shell (très rarement des alias) pour plus de commodité dans les shells interactifs, par exemple pour ajouter des options à certaines commandes par défaut (
-F
pourls
) ou pour créer des variations spécialisées de certaines commandes (pman
voici uneman
commande qui ne regarde que les manuels POSIX, par exemple) .la source
On dirait que j'ai une opinion minoritaire à ce sujet.
Le terme "script" est intentionnellement déroutant, débarrassez-vous-en. C'est un logiciel que vous y écrivez, même si vous utilisez uniquement
bash
etawk
.Au sein d'une équipe, je préfère écrire un logiciel avec un processus de révision de code appliqué par un outil (github / gitlab / gerrit). Cela donne un contrôle de version en prime. Si vous avez plusieurs systèmes, ajoutez des outils de déploiement continu. Et certaines suites de tests, si les systèmes cibles sont importants. Je ne suis pas religieux à ce sujet, mais je pèse les avantages et les coûts.
Si vous avez une équipe d'administrateurs, le plus simple
vim /root/bin/x.sh
est surtout une catastrophe en termes de communication liée au changement, de lisibilité du code et de distribution inter-systèmes. Souvent, un dysfonctionnement grave coûte plus de temps / d'argent que le processus soi-disant «lourd».Je préfère en fait une ligne pour tout ce qui ne mérite pas ce processus "lourd". Ils peuvent être réutilisés rapidement, en quelques touches, si vous savez utiliser efficacement l'historique de votre shell; facilement collé entre des systèmes indépendants (par exemple, différents clients).
Différence cruciale entre les monolignes (non révisées!) Et les logiciels révisés ("scripts"): la responsabilité vous incombe entièrement lorsque vous exécutez des monolignes. Vous ne pouvez jamais vous dire "Je viens de trouver ce one-liner quelque part, je l'ai exécuté sans comprendre, ce qui a suivi n'est pas de ma faute" - vous saviez que vous exécutez un logiciel non révisé et non testé, c'est donc votre faute. Assurez-vous qu'il est suffisamment petit pour que vous puissiez prévoir les résultats - soyez damné si vous ne le faites pas.
Vous avez parfois besoin de cette approche simpliste, et définir la barre sur environ une ligne de texte fonctionne bien dans la pratique (c'est-à-dire la frontière entre le code révisé et le code non révisé). Certains de mes uniformes ont l'air terriblement longs, mais ils fonctionnent efficacement pour moi. Tant que je les gâche et que je ne le pousse pas vers des collègues plus juniors, tout va bien. Le moment où j'ai besoin de les partager - je passe par le processus de développement de logiciels standard.
la source
Je dois dire que je suis quelque peu horrifié par les implications des premières parties de la question. Les langages de script Unix sont des langages de programmation à part entière et les langages de programmation sont des langages , ce qui signifie qu'ils sont à peu près aussi infiniment malléables et flexibles que les langages humains. Et l'une des caractéristiques de "la malléabilité et la flexibilité infinies" est qu'il n'y a presque jamais "une bonne façon" d'exprimer quelque chose - il existe des variétés de façons, et c'est une bonne chose! Donc, oui, bien sûr, c'est une question de préférence personnelle, et il n'y a rien de mal à cela. Quiconque dit qu'il n'y a qu'une seule façon de faire quelque chose,
Il était une fois, le mien
~/bin
était plein de petits scripts "utiles" que j'avais écrits. Mais j'ai réalisé que la plupart d'entre eux étaient utilisés le jour où je les ai écrits, et plus jamais. Donc, plus le temps passe, plus monbin
répertoire est petit .Je ne pense pas qu'il y ait quelque chose de mal à écrire un script. Si vous imaginez que vous ou quelqu'un d'autre pourriez l'utiliser à nouveau, écrivez certainement un script. Si vous voulez "correctement concevoir" un script supportable pour le plaisir, faites-le. (Même si personne ne l'utilise jamais, l'écrire est une bonne pratique.)
Raisons pour lesquelles je n'écris plus autant de scripts (et, je suppose, je préfère les "one-liners"):
bin
l'encombrement des répertoires a un coût. Je ne mets plus de choses là-bas à moins qu'elles ne leur appartiennent vraiment.la source
Je pense que la plupart du temps, la demande de "one-liner" est en fait une demande de "sound bite", c'est-à-dire:
Les gens veulent et demandent le code le plus court qui démontre une solution à la question posée.
Parfois, il n'y a aucun moyen de réduire un discours à une "morsure sonore" et il peut être impossible de réduire un script à un court "one-liner". Dans de tels cas, la seule réponse possible est un script.
Et, en général, une «morsure sonore» n'est jamais un bon substitut de tout le discours. Ainsi, un "one liner" n'est généralement bon que pour transmettre une idée ou pour donner un exemple pratique de cette idée. Ensuite, une fois l'idée comprise, elle doit être développée (appliquée) dans un script.
Alors, écrivez un "one-liner" pour transmettre une idée ou un concept.
Écrivez votre code général sous forme de scripts complets et non de lignes simples.
la source
Vous posez des questions sur "la peur et le dédain des scripts". Cela est dû à la situation Q + A, où souvent la réponse dit: il a besoin de cette étape et de cela, mais je peux également le mettre sur une seule ligne (vous pouvez donc le copier-coller et l'utiliser comme une simple commande longue).
Vous pouvez parfois seulement deviner si le Q est mieux servi par une solution de copier-coller rapide et sale, ou si un "joli" script est exactement ce que le Q doit comprendre.
Beaucoup d'avantages et d'inconvénients ici sont vrais, mais il leur manque toujours le point. Je dirais même que les définitions du Q ne sont pas utiles.
Les fichiers d' historique du shell sont des "one liners", mais ils sont toujours enregistrés. La fonction bash
operate-and-get-next (C-o)
vous permet même de les répéter semi-automatiquement.Je vois à peine le mot fonction mentionné. C'est la façon de stocker à la fois des "scripts" et des "one liners". Et avec quelques touches, vous pouvez basculer entre les deux formats. Une commande composée peut souvent correspondre aux deux.
history -r file
est le moyen de lire une ou plusieurs lignes de commande (et commentaires) à partir de n'importe quel fichier, pas seulement à partir du fichier historique par défaut. Cela prend juste une organisation minimale. Vous ne devez pas compter sur une grande taille de fichier d'historique et une recherche d'historique pour récupérer (une) version d'une ligne de commande.Les fonctions doivent être définies de manière similaire. Pour commencer, placez
thisfunc() {...}
un fichier "fonctions" dans votre répertoire personnel et sourcez-le. Oui, ce sont des frais généraux, mais c'est la solution générale.Si vous stockez chaque ligne de commande et chaque variante de script dans un fichier séparé, c'est un gaspillage (théorique, mais objectif) de blocs de système de fichiers.
Un doublure n'a rien de rapide et de sale en soi. C'est plus la partie copier-coller qui est un peu désapprouvée, et la façon dont nous nous appuyons simplement sur l'historique des commandes pour l'enregistrer pour nous.
@sitaram: votre one liner a vraiment des fonctionnalités inédites : ligne shebang, newline, quatre appels d'utilité - dont deux "programmes" sed. Je pense que le script perl d'origine était plus joli et fonctionnait plus rapidement et ne gaspillait aucun octet en s'étalant sur 60 lignes. Et perl vous permet également de serrer un peu.
Pour moi, c'est exactement le genre de doublure à éviter. Souhaitez-vous avoir cela (collé) sur votre ligne de commande? Non, et puis, si vous le stockez de toute façon dans un fichier (peu importe le script ou la fonction), vous pourriez tout aussi bien investir deux ou trois sauts de ligne pour lui donner un aspect --- agréable.
10 minutes. plus tard: je voulais juste vérifier si je peux dire "deux programmes sed" ou si c'est "deux substitutions / appels sed". Mais la réponse de sitaram a disparu. Ma réponse est toujours logique, j'espère.
la source