Il m'a fallu près de 10 ans d’utilisation de Linux pour poser cette question. Il s’agissait d’essais et d’erreur et de naviguer au hasard sur Internet tard dans la nuit.
Mais les gens ne devraient pas avoir besoin de 10 ans pour cela. Si je commençais tout juste avec Linux, je voudrais savoir: quand alias, quand écrire un script et quand écrire une fonction?
En ce qui concerne les alias, j'utilise des alias pour des opérations très simples qui ne prennent pas d'arguments.
alias houston='cd /home/username/.scripts/'
Cela semble évident. Mais certaines personnes font ceci:
alias command="bash bashscriptname"
(et l'ajouter au .bashrc
fichier)
Y a-t-il une bonne raison de le faire? J'essaie vraiment très fort, mais je ne peux vraiment pas penser à une situation dans laquelle je voudrais faire cela. Donc, s'il y a un cas extrême où cela ferait une différence, veuillez répondre ci-dessous.
Parce que c’est là que je voudrais simplement mettre quelque chose dans mon chemin PATH chmod +x
, ce qui est une autre chose qui est arrivée après des années d’essais et d’erreur en Linux.
Ce qui m'amène au sujet suivant. Par exemple, j'ai ajouté .scripts/
à PATH un dossier caché ( ) dans le répertoire de base en ajoutant simplement une ligne à ma .bashrc
( PATH=$PATH:/home/username/.scripts/
), ainsi tout élément exécutable se trouvant automatiquement ici se termine automatiquement.
Si j'en avais besoin.
Je n'ai pas vraiment besoin de ça, n'est-ce pas? Je ne l'utiliserais que pour les langages qui ne sont pas le shell, comme Python.
Si c'est le shell, je peux juste écrire une fonction à l'intérieur même .bashrc
:
funcname () {
somecommand -someARGS "$@"
}
Comme je l'ai dit, j'ai découvert beaucoup de choses par essais et erreurs. Et je n’ai vraiment vu la beauté des fonctions que lorsque mon ordinateur est mort et j’ai été forcé d’utiliser les ordinateurs des gens autour de moi quand ils ne les utilisaient pas.
Au lieu de déplacer tout un répertoire de scripts d'un ordinateur à l'autre, j'ai fini par remplacer simplement le fichier .bashrc de tous les autres par le mien, car ils n'avaient même jamais apporté une seule modification.
Mais ai-je manqué quelque chose?
Alors, que diriez-vous à un utilisateur Linux débutant de quand alias, quand écrire un script et quand écrire une fonction?
Si ce n'est pas évident, je suppose que les personnes qui répondront utiliseront les trois options. Si vous utilisez uniquement des alias, ou que des scripts, ou que vous utilisez uniquement des fonctions - ou si vous utilisez uniquement des alias et des scripts ou des alias et des fonctions ou des scripts et des fonctions - cette question ne vous concerne pas vraiment.
la source
Réponses:
En général, un alias ne devrait pas (en général) faire plus que modifier les options par défaut d'une commande. Ce n'est rien de plus qu'un simple remplacement de texte sur le nom de la commande. Il ne peut rien faire avec des arguments, mais les passe à la commande qu'il exécute. Donc, si vous devez simplement ajouter un argument devant une seule commande, un alias fonctionnera. Des exemples courants sont
Une fonction doit être utilisée lorsque vous devez faire quelque chose de plus complexe qu'un alias, mais que cela ne serait pas utile par lui-même. Par exemple, répondez à une question que j’ai posée concernant le changement
grep
de comportement par défaut selon qu’il s’agisse ou non d’un pipeline:C'est un exemple parfait de fonction car elle est trop complexe pour un alias (nécessitant des valeurs par défaut différentes en fonction d'une condition), mais ce n'est pas quelque chose dont vous aurez besoin dans un script non interactif.
Si vous obtenez trop de fonctions ou des fonctions trop volumineuses, placez-les dans des fichiers séparés dans un répertoire caché et sourcez-les dans
~/.bashrc
:Un script doit être autonome. Il devrait avoir une valeur en tant que quelque chose qui peut être réutilisé ou utilisé à plusieurs fins.
la source
.
ousource
, un script est exécuté par un processus bash distinct et possède son propre environnement. Pour cette raison, tout élément modifiant l'environnement du shell (fonctions, variables, etc.) ne persistera pas dans l'environnement du shell à partir duquel vous exécutez le script.Les autres réponses fournissent des directives générales souples basées sur les goûts personnels, mais ignorent de nombreux faits pertinents à prendre en compte lors du choix entre scripts, fonctions ou alias.
Alias et fonctions ¹
Les scripts
$PATH
recherche, de nombreux shells stockent un hachage de son nom de chemin en mémoire pour gagner du temps lors des$PATH
recherches ultérieures , mais il s'agit de l'étendue de l'empreinte mémoire d'un script lorsqu'il n'est pas utilisé.Les scripts peuvent être appelés de différentes manières que les fonctions et les alias. Ils peuvent être passés sous forme d'argument à un interprète, par exemple
sh script
, ou directement invoqués en tant qu'exécutable, auquel cas l'interpréteur dans la ligne shebang (par exemple#!/bin/sh
) est appelé pour l'exécuter. Dans les deux cas, le script est exécuté par un processus interpréteur distinct avec son propre environnement, distinct de celui de votre shell, environnement dans lequel le script ne peut avoir aucune incidence. En effet, le shell interprète n'a même pas besoin de correspondre au shell appelant. Comme les scripts invoqués de cette manière semblent se comporter comme n'importe quel exécutable ordinaire, ils peuvent être utilisés par n'importe quel programme.Enfin, un script peut être lu et exécuté par le shell en cours avec
.
, ou , dans certains coquillages,source
. Dans ce cas, le script se comporte presque comme une fonction lue à la demande au lieu d’être constamment gardée en mémoire.Application
Compte tenu de ce qui précède, nous pouvons proposer des directives générales pour définir un script, une fonction ou un alias.
Est-ce que d'autres programmes que votre shell doivent être capables de l'utiliser? Si c'est le cas, il doit s'agir d'un script.
Voulez-vous seulement qu'il soit disponible à partir d'un shell interactif? Il est courant de vouloir modifier le comportement par défaut de nombreuses commandes lors d'une exécution interactive sans affecter les commandes / scripts externes. Dans ce cas, utilisez un alias / fonction défini dans le fichier rc "du mode interactif uniquement" du shell (
bash
c'est le cas.bashrc
).Faut-il changer l'environnement du shell? Une fonction / alias ou un script source sont des choix possibles.
Est-ce quelque chose que vous utilisez fréquemment? Il est probablement plus efficace de le garder en mémoire, alors faites-en une fonction / un alias si possible.
Inversement, est-ce quelque chose que vous utilisez rarement? Dans ce cas, il ne sert à rien d'avoir de la mémoire quand vous n'en avez pas besoin, alors faites-en un script.
¹ Bien que les fonctions et les alias présentent des différences importantes, ils sont regroupés car les fonctions peuvent tout faire comme les alias. Les alias ne peuvent pas avoir de variables locales, ils ne peuvent pas non plus traiter d'arguments, et ils sont peu pratiques pour une longueur supérieure à une ligne.
² Chaque processus en cours dans un système Unix a un environnement constitué de plusieurs
variable=value
paires de paramètres qui contiennent souvent des paramètres de configuration globaux, commeLANG
pour les paramètres régionaux par défaut etPATH
pour spécifier un chemin de recherche exécutable.la source
alias g='gradle'
auto-complétement je reçois gradle lorsque j'utilise mong
alias, mais je ne le récupère pas immédiatement lorsque j'utilise un scriptgradle $*
ou une fonction avecgradle $@
Je pense que c'est au goût de chacun. Pour moi, la logique est la suivante:
Rien ne vous empêche réellement de faire quelque chose qui fonctionne .
la source
Au moins partiellement, c'est une question de goût personnel. Par ailleurs, il existe des distinctions fonctionnelles claires:
En ce qui concerne les scripts shell que j'ai effectués ces dernières années, j'ai plus ou moins arrêté d'écrire des alias (car ils ont tous tendance à devenir des fonctions au fil du temps) et n'effectuez des scripts que s'ils doivent également être disponibles à partir d'environnements non bash.
PS: En ce qui
alias command="bash bashscriptname"
me concerne, je ne vois aucune raison de le faire. Même sibashscriptname
n'est pas dans $ PATH, un simplealias c=/path/to/script
suffirait.la source
alias command="bash bashscriptname"
le script ne doit pas nécessairement être exécutable; dans lealias c=/path/to/script
il doit.exec()
shell de fonctions" :-)Voici quelques points supplémentaires sur les alias et les fonctions:
Par exemple:
Comme nous pouvons le constater, il existe des espaces de noms distincts pour les alias et les fonctions; plus de détails peuvent être trouvés en utilisant
declare -A -p BASH_ALIASES
etdeclare -f f
, qui imprime leurs définitions ( les deux sont stockées dans la mémoire).Exemple montrant les limitations des alias:
Comme on peut le constater, les alias ne sont pas imbriquables, contrairement aux fonctions. En outre, leur utilisation est limitée aux sessions interactives.
Enfin, notez que vous pouvez avoir un calcul arbitraire dans un alias en déclarant une fonction comme l'appelant immédiatement, comme ceci:
qui est déjà largement utilisé en cas de pseudonymes Git. L'avantage de le faire par rapport à la déclaration d'une fonction est que votre alias ne peut pas être simplement écrasé par la source (ou l'utilisation
.
) d'un script qui déclare une fonction de même nom.la source
Quand écrire un script ...
export
variables et / ou fonctions édifiées sont transmises au script par valeur . Les modifications apportées à ces variables ne sont pas répercutées dans le script parent.Quand écrire une fonction ...
Quand écrire un alias ...
~/.profile
ou~/.bashrc
.Dans les scripts tels que les scripts de bibliothèque, un alias pour une fonction est parfois nécessaire, par exemple lorsqu'une fonction est renommée mais que la compatibilité avec les versions antérieures est requise. Cela peut être accompli en créant une fonction simple avec l'ancien nom qui transmet tous ses arguments à la nouvelle fonction ...
la source
Une autre chose que je ne crois pas a été évoquée: une fonction s’exécute dans le contexte du processus d’appel, alors qu’un script crée un nouveau shell.
Cela pourrait être important pour la performance - une fonction est plus rapide, car il n'a pas
fork()
etexec()
. Dans des circonstances normales, la différence est triviale, mais si vous déboguez un système qui manque de mémoire et qui détruit les pages, cela pourrait faire une grande différence.De plus, si vous souhaitez modifier votre environnement shell actuel, vous devez utiliser une fonction. Par exemple, une fonction peut changer la recherche de commande
$PATH
pour le shell actuel, mais pas un script, car il fonctionne sur une copie fork / exec de$PATH
.la source
export -f
un rôle, même si son fonctionnement interne est assez obscur. Ce n'est pas portable pour shell traditionnel Bourne je crois.Script et alias et script et fonction ne s'excluent pas mutuellement. Vous pouvez et stockez des alias et des fonctions dans des scripts.
Les scripts ne sont que du code qui est rendu persistant . Les fonctions utiles et les alias que vous aimerez utiliser à l'avenir sont stockés dans des scripts. Cependant, un script est souvent un ensemble de plusieurs fonctions.
Comme les alias ne sont pas paramétrés , ils sont très limités. habituellement pour définir certains paramètres par défaut.
Une fonction est une unité de code séparée , un concept bien défini de quelques lignes de code qui ne peuvent pas être séparées en parties plus petites et utiles. l'un qui peut être réutilisé directement ou autre par d'autres fonctions.
la source
Si cela doit être très rapide, faites-en un alias ou une fonction.
S'il doit être utilisable en dehors de votre shell préféré, faites-en un script. 1
Si cela prend des arguments, faites-en une fonction ou un script.
S'il doit contenir des caractères spéciaux, faites-en un alias ou un script. 2
Si cela doit fonctionner avec sudo, faites-en un alias ou un script. 3
Si vous souhaitez le modifier facilement sans vous déconnecter, un script est plus facile. 4
Notes de bas de page
1 Ou faites-en un alias, mettez-le
~/.env
et définissez-leexport ENV="$HOME/.env"
, mais c'est compliqué de le faire fonctionner de manière portable.2 Les noms de fonction doivent être des identificateurs, ils doivent donc commencer par une lettre et ne peuvent contenir que des lettres, des chiffres et des traits de soulignement. Par exemple, j'ai un alias
alias +='pushd +1'
. Cela ne peut pas être une fonction.3 Et ajoutez l'alias
alias sudo='sudo '
. Ditto toute autre commande commestrace
,gdb
, etc. , qui prend une commande comme premier argument.4 Voir aussi: fpath. Bien sûr, vous pouvez également faire
source ~/.bashrc
ou similaire, mais cela a souvent d'autres effets secondaires.la source
+
dans Bash. Fait intéressant, après des tests, j'ai découvert que dans bash, vous pouvez créer+
un alias mais pas une fonction, comme vous le dites, mais zsh est l'inverse -+
peut être une fonction mais pas un alias.zsh
vous devez écrirealias -- +='some command here'
.+
est portable. Voir les spécifications POSIX sur les noms d'aliassudo
utilisation. En ce qui concerne la note de bas de page 4, je stocke mes alias dans~/.bash_aliases
les définitions de fonctions~/.bash_functions
afin que je puisse facilement les modifiersource
(sans risque d'effets secondaires).Juste pour ajouter quelques notes:
Sinon, vous pouvez utiliser la forme la plus simple possible, c'est-à-dire d'abord considérer alias, ensuite fonction, puis script.
la source
sudo
. Mais d'abord vous avez besoinalias sudo='sudo '
.Ma règle de base est:
la source
Dans un environnement multi-utilisateur (ou multi-sysamin), j'utilise des scripts pour tout, même si cela finit par être un bref wrapper 'exec thing ....'.
Bien sûr, il est techniquement plus lent / moins efficace qu'un alias ou une fonction, mais cela n'a presque jamais d'importance - et à condition que cela soit dans le chemin, un script fonctionne toujours.
Votre fonctionnalité peut être appelée depuis cron, depuis quelque chose dont l’environnement est réduit ou modifié, tel que sudo ou env, ou l’utilisateur peut simplement utiliser un shell différent: tout ou susceptible de rompre un alias ou une fonction.
Si vous avez des problèmes de performances, traitez cela comme un cas spécial, ou mieux encore, considérez cela comme un déclencheur pour réécrire dans un langage de script plus fonctionnel.
Si nous parlons de fonctionnalités qui ne seront utilisées que dans d’autres scripts, vous pouvez également envisager de définir un shell standard et d’écrire un script de bibliothèque de fonctions qui peut tout simplement être. source I à tous les autres scripts.
T
la source
Exemple pour une situation dans laquelle vous aimeriez probablement utiliser un alias.
Je sais que ceci est un ancien post, mais je voudrais signaler une situation dans laquelle j'ai presque dû utiliser une combinaison d'alias avec un script et j'ai choisi de ne pas utiliser de fonction.
J'ai un script
~/.bin/
appelésetup
qui fait ce qui suit: 1Le fait est que si je me contentais de courir,
setup <project-name>
je n'aurais pas défini ces variables et je n'aurais pas eu accès au répertoire du tout. La solution que je trouve être le meilleur était d'ajouter ce scriptPATH
et ajouteralias setup=". ~/.bin/setup"
à~/.bashrc
ou autre.Remarques:
la source
Quand écrire un script
Lorsque vous souhaitez exécuter la commande à partir d'un outil autre que le shell.
Cela inclut vim (pour moi): ayant des filtres écrits et d’autres programmes sous forme de scripts, je peux faire quelque chose comme
:%!my-filter
filtrer un fichier à travers le programme à partir de mon éditeur.S'il
my-filter
s'agissait d'une fonction ou d'un alias, cela ne serait pas possible.la source