J'ai remarqué beaucoup de questions et de réponses et de commentaires exprimant du mépris (et parfois même de la peur) pour écrire des scripts au lieu de one-liners. Donc, j'aimerais 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 ?
-
Certains langages (par exemple awk ou perl) sont-ils mieux adaptés aux one-liners que d'autres (par exemple python) ? Si oui, pourquoi ?
-
Est-ce juste une question de préférence personnelle ou y a-t-il de bonnes raisons (c'est-à-dire objectives) d'écrire l'un 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 . Impliquant souvent des pipelines et/ou l'utilisation de langages tels quesed
,awk
,perl
, et/ou des outils commegrep
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, une boucle sh for 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(s) langage(s) interprété(s) qui sont sauvegardées dans un fichier , puis exécuté. Un script peut être entièrement écrit dans une langue, ou il peut s'agir d'un wrapper de script shell autour de plusieurs "lignes simples" 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éponse acceptée :
Une autre réponse basée sur l'expérience pratique.
J'utiliserais un one-liner s'il s'agissait d'un code "à jeter" que je pourrais écrire directement à l'invite. Par exemple, je pourrais utiliser ceci :
for h in host1 host2 host3; do printf "%s\t%s\n" "$h" "$(ssh "$h" uptime)"; done
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, j'ajouterais probablement une vérification des erreurs et peut-être même l'enregistrerais dans un référentiel de code pour la gestion des versions. Par exemple, si je décidais que la vérification de la disponibilité d'un ensemble de serveurs était une fonction utile que j'utiliserais encore et encore, la phrase ci-dessus pourrait être étendue à ceci :
#!/bin/bash
# Check the uptime for each of the known set of hosts
########################################################################
#
hosts=(host1 host2 host3)
for h in "${hosts[@]}"
do
printf "%s\t" "$h"
uptime=$(ssh -o ConnectTimeout=5 -n "$h" uptime 2>/dev/null)
printf "%s\n" "${uptime:-(unreachable)}"
done
Généraliser, pourrait-on dire
-
Une ligne
- Code simple (c'est-à-dire juste "quelques" instructions), écrit dans un but précis et ponctuel
- Code qui peut être écrit rapidement et facilement chaque fois que nécessaire
- Code jetable
-
Scénario
- Code qui sera (probablement) utilisé plus d'une fois ou deux
- Code complexe nécessitant plus que "quelques" instructions
- Code qui devra être maintenu par d'autres
- Code à comprendre par les autres
- Code à exécuter sans surveillance (par exemple, à partir de
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 l'intérêt de la lisibilité (pour les futurs lecteurs), nous devrions probablement éviter de fournir du code compressé sur une seule ligne pour autre chose que la solution la plus triviale.
Connexe :extension du nom de chemin bash/shell pour mkdir, touch, etc. ?