Es hat mich fast 10 Jahre Linux-Erfahrung gekostet, diese Frage zu stellen. Es war alles Versuch und Irrtum und zufälliges nächtliches Surfen im Internet.
Aber die Leute sollten dafür keine 10 Jahre brauchen. Wenn ich gerade mit Linux anfangen würde, würde ich wissen wollen: Wann sollte ein Alias erstellt, wann ein Skript erstellt und wann eine Funktion geschrieben werden?
Wenn es um Aliase geht, verwende ich Aliase für sehr einfache Operationen, für die keine Argumente erforderlich sind.
alias houston='cd /home/username/.scripts/'
Das scheint offensichtlich. Aber einige Leute machen das:
alias command="bash bashscriptname"
(und zur .bashrc
Datei hinzufügen )
Gibt es einen guten Grund dafür? Ich bemühe mich sehr, aber ich kann mir wirklich keine Umstände vorstellen, unter denen ich das tun möchte. Wenn es also einen Randfall gibt, bei dem dies einen Unterschied machen würde, antworten Sie bitte unten.
Denn hier habe ich einfach etwas in meinen PATH und chmod +x
das hier eingefügt, was auch nach Jahren des Versuchs und Irrtums unter Linux der Fall war.
Das bringt mich zum nächsten Thema. Zum Beispiel habe ich .scripts/
meinem PATH einen versteckten Ordner ( ) im Home-Verzeichnis hinzugefügt, indem ich einfach eine Zeile zu my .bashrc
( PATH=$PATH:/home/username/.scripts/
) hinzugefügt habe , damit alle darin enthaltenen ausführbaren Dateien automatisch vervollständigt werden.
Wenn ich müsste.
Das brauche ich aber nicht wirklich, oder? Ich würde das nur für Sprachen verwenden, die nicht die Shell sind, wie Python.
Wenn es die Shell ist, kann ich einfach eine Funktion innerhalb derselben schreiben .bashrc
:
funcname () {
somecommand -someARGS "$@"
}
Wie ich bereits sagte, habe ich viel durch Ausprobieren herausgefunden. Und ich habe die Schönheit der Funktionen erst wirklich gesehen, als mein Computer starb und ich gezwungen war, die Computer der Leute um mich herum zu benutzen, wenn sie sie nicht benutzten.
Anstatt ein ganzes Verzeichnis von Skripten von Computer zu Computer zu verschieben, habe ich letztendlich nur die .bashrc aller anderen durch meine eigene ersetzt, da sie noch nie eine einzige Änderung vorgenommen hatten.
Aber habe ich etwas verpasst?
Also, was würden Sie einem Linux-Anfänger darüber sagen, wann ein Alias erstellt, wann ein Skript erstellt und wann eine Funktion geschrieben werden soll?
Wenn es nicht offensichtlich ist, gehe ich davon aus, dass die Personen, die darauf antworten, alle drei Optionen nutzen werden. Wenn Sie nur Aliase oder nur Skripte verwenden oder nur Funktionen verwenden - oder wenn Sie nur Aliase und Skripte oder Aliase und Funktionen oder Skripte und Funktionen verwenden - richtet sich diese Frage nicht wirklich an Sie.
quelle
Antworten:
Ein Alias sollte (im Allgemeinen) nicht mehr als die Standardoptionen eines Befehls ändern. Es ist nichts weiter als eine einfache Ersetzung des Befehlsnamens. Es kann nichts mit Argumenten anfangen, sondern sie an den Befehl übergeben, den es tatsächlich ausführt. Wenn Sie also einfach ein Argument vor einem einzelnen Befehl einfügen müssen, funktioniert ein Alias. Häufige Beispiele sind
Eine Funktion sollte verwendet werden, wenn Sie komplexere Aufgaben als einen Alias ausführen müssen, dies allein jedoch nicht von Nutzen wäre. Nehmen Sie diese Antwort zum Beispiel auf eine Frage, die ich zum Ändern
grep
des Standardverhaltens gestellt habe, je nachdem, ob es sich in einer Pipeline befindet:Dies ist ein perfektes Beispiel für eine Funktion, da sie für einen Alias zu komplex ist (je nach Bedingung sind unterschiedliche Standardeinstellungen erforderlich), in einem nicht interaktiven Skript jedoch nicht erforderlich ist.
Wenn Sie zu viele oder zu große Funktionen erhalten, speichern Sie diese in separaten Dateien in einem versteckten Verzeichnis und geben Sie sie in Ihrem
~/.bashrc
:Ein Skript sollte für sich alleine stehen. Es sollte einen Wert haben, der wiederverwendet oder für mehr als einen Zweck verwendet werden kann.
quelle
.
oder bereitgestellt wirdsource
- von einem separaten Bash-Prozess ausgeführt wird und über eine eigene Umgebung verfügt. Aus diesem Grund bleibt alles, was die Shell-Umgebung verändert (z. B. Funktionen, Variablen usw.), in der Shell-Umgebung, in der Sie das Skript ausführen, nicht erhalten.Die anderen Antworten enthalten einige allgemeine Richtlinien, die sich nach dem persönlichen Geschmack richten, ignorieren jedoch viele relevante Fakten , die bei der Entscheidung zwischen Skripten, Funktionen oder Aliasen berücksichtigt werden sollten.
Aliase und Funktionen ¹
Skripte
$PATH
Suche gefunden wird, speichern viele Shells einen Hash seines Pfadnamens im Speicher, um Zeit bei zukünftigen Suchen zu sparen.$PATH
Dies ist jedoch der Umfang des Speicherbedarfs eines Skripts, wenn es nicht verwendet wird.Skripte können auf mehr Arten aufgerufen werden als Funktionen und Aliase. Sie können als Argument an einen Interpreter übergeben werden, z. B.
sh script
oder direkt als ausführbare Datei aufgerufen werden. In diesem Fall wird der Interpreter in der Shebang-Zeile (z. B.#!/bin/sh
) aufgerufen, um sie auszuführen. In beiden Fällen wird das Skript von einem separaten Interpreter-Prozess mit einer eigenen Umgebung ausgeführt, die von der Ihrer Shell getrennt ist und deren Umgebung das Skript in keiner Weise beeinflussen kann. In der Tat muss die Interpreter-Shell nicht einmal mit der aufrufenden Shell übereinstimmen. Da sich auf diese Weise aufgerufene Skripte wie normale ausführbare Dateien verhalten, können sie von jedem Programm verwendet werden.Schließlich kann ein Skript von der aktuellen Shell mit
.
oder in einigen Shells gelesen und ausgeführt werdensource
. In diesem Fall verhält sich das Skript ähnlich wie eine Funktion, die bei Bedarf gelesen wird, anstatt ständig im Speicher zu bleiben.Anwendung
In Anbetracht der obigen Ausführungen können wir einige allgemeine Richtlinien für die Erstellung eines Skripts oder einer Funktion / eines Alias erstellen.
Müssen andere Programme als Ihre Shell in der Lage sein, es zu benutzen? Wenn ja, muss es ein Skript sein.
Möchten Sie nur, dass es über eine interaktive Shell verfügbar ist? Es ist üblich, das Standardverhalten vieler Befehle zu ändern, wenn sie interaktiv ausgeführt werden, ohne externe Befehle / Skripte zu beeinflussen. Für diesen Fall verwenden Sie eine Alias / Funktion in dem „interactive-mode-only“ Shell gesetzt rc - Datei (
bash
das ist.bashrc
).Muss die Umgebung der Shell geändert werden? Es können sowohl eine Funktion / ein Alias als auch ein bezogenes Skript ausgewählt werden.
Verwenden Sie es häufig? Es ist wahrscheinlich effizienter, es im Speicher zu behalten, machen Sie es also zu einer Funktion / einem Alias, wenn möglich.
Verwenden Sie es dagegen nur selten? In diesem Fall macht es keinen Sinn, es als Schweinespeicher zu verwenden, wenn Sie es nicht benötigen. Machen Sie es also zu einem Skript.
¹ Obwohl Funktionen und Aliase einige wichtige Unterschiede aufweisen, werden sie zusammengefasst, da Funktionen alles können, was Aliase können. Aliase können keine lokalen Variablen haben oder Argumente verarbeiten und sind für alles, was länger als eine Zeile ist, unpraktisch.
² Jeder ausgeführte Prozess in einem Unix-System verfügt über eine Umgebung, die aus einer Reihe von
variable=value
Paaren besteht, die häufig globale Konfigurationseinstellungen enthalten, z. B.LANG
für das Standardgebietsschema undPATH
zur Angabe des ausführbaren Suchpfads.quelle
alias g='gradle'
bei Verwendung meinesg
Alias eine gradle-Autovervollständigung durchgeführt , bei Verwendung eines Skripts mitgradle $*
oder einer Funktion mitgradle $@
Ich denke, es liegt an jedem Geschmack. Für mich lautet die Logik wie folgt:
Es gibt wirklich nichts, was Sie daran hindert, etwas zu tun, das funktioniert .
quelle
Zumindest teilweise ist es eine Frage des persönlichen Geschmacks. Auf der anderen Seite gibt es einige klare funktionale Unterschiede:
In den letzten Jahren habe ich mehr oder weniger aufgehört, Aliase zu schreiben (weil sie alle im Laufe der Zeit zu Funktionen werden) und Skripte nur dann zu erstellen, wenn sie auch in Nicht-Bash-Umgebungen verfügbar sein müssen.
PS:
alias command="bash bashscriptname"
Ich sehe keinen Grund, dies zu tun. Auch wennbashscriptname
nicht in $ PATH steht, würde ein einfachesalias c=/path/to/script
ausreichen.quelle
alias command="bash bashscriptname"
Skript muss nicht unbedingt ausführbar sein; in deralias c=/path/to/script
muss es sein.exec()
Shell-Funktionen" :-)Hier einige zusätzliche Punkte zu Aliasen und Funktionen:
Zum Beispiel:
Wie wir sehen können, gibt es separate Namespaces für Aliase und Funktionen. Weitere Details finden Sie mit
declare -A -p BASH_ALIASES
unddeclare -f f
, die ihre Definitionen ausdrucken (beide sind im Speicher abgelegt).Beispiel mit Einschränkungen von Aliasen:
Wie wir sehen können, sind Aliase im Gegensatz zu Funktionen nicht verschachtelbar. Außerdem ist ihre Verwendung auf die interaktiven Sitzungen beschränkt.
Beachten Sie zum Schluss, dass Sie eine beliebige Berechnung in einem Alias durchführen können, indem Sie eine Funktion deklarieren und sofort aufrufen, wie folgt:
was bei Git-Aliasen bereits weit verbreitet ist. Dies hat gegenüber der Deklaration einer Funktion den Vorteil, dass Ihr Alias nicht einfach überschrieben werden kann, indem Sie
.
ein Skript als Quelle angeben (oder verwenden ), das zufällig eine Funktion mit demselben Namen deklariert.quelle
Wann schreibe ich ein Skript ...
export
ed-Variablen und / oder -Funktionen werden als Wert an das Skript übergeben. Änderungen an diesen Variablen werden nicht an das übergeordnete Skript weitergegeben.Wann schreibe ich eine Funktion ...
Wann soll ein Alias geschrieben werden?
~/.profile
oder~/.bashrc
.In Skripten wie Bibliotheksskripten wird manchmal ein Alias für eine Funktion benötigt, z. B. wenn eine Funktion umbenannt wird, aber Abwärtskompatibilität erforderlich ist. Dies kann erreicht werden, indem eine einfache Funktion mit dem alten Namen erstellt wird, die alle ihre Argumente an die neue Funktion übergibt ...
quelle
Eine andere Sache, von der ich nicht glaube, dass sie angesprochen wurde: Eine Funktion wird im Kontext des aufrufenden Prozesses ausgeführt, während ein Skript eine neue Shell aufgibt.
Dies kann für die Leistung wichtig sein - eine Funktion ist schneller, da dies nicht der Fall ist
fork()
undexec()
. Unter normalen Umständen ist der Unterschied trivial. Wenn Sie jedoch ein System debuggen, dessen Arbeitsspeicher knapp wird und das überfüllt ist, kann dies einen großen Unterschied bewirken.Wenn Sie Ihre aktuelle Shell-Umgebung ändern möchten, sollten Sie auch eine Funktion verwenden. Beispielsweise kann eine Funktion die Befehlssuche
$PATH
für die aktuelle Shell ändern , ein Skript jedoch nicht, da es auf einer Fork / Exec-Kopie von ausgeführt wird$PATH
.quelle
export -f
eine Funktion ausführen , obwohl das genaue Innenleben etwas unklar ist. Dies ist meiner Meinung nach nicht auf traditionelle Bourne-Shell übertragbar.Skript und Alias sowie Skript und Funktion schließen sich nicht gegenseitig aus. Sie können Aliase und Funktionen in Skripten speichern.
Skripte sind nur Code, der persistent gemacht wird . Nützliche Funktionen und Aliase, die Sie in Zukunft gerne verwenden, werden in Skripten gespeichert. Ein Skript ist jedoch häufig eine Sammlung von mehr als einer Funktion.
Da Aliase nicht parametrisiert sind , sind sie sehr begrenzt. normalerweise, um einige Standardparameter zu definieren.
Eine Funktion ist eine separate Codeeinheit , ein genau definiertes Konzept einiger Codezeilen, die nicht in kleinere, nützliche Teile unterteilt werden können. eine, die von anderen Funktionen direkt oder anderweitig wiederverwendet werden kann.
quelle
Wenn es sehr schnell sein soll, machen Sie es zu einem Alias oder einer Funktion.
Wenn es außerhalb Ihrer bevorzugten Shell verwendet werden soll, machen Sie es zu einem Skript. 1
Wenn es Argumente braucht, machen Sie es zu einer Funktion oder einem Skript.
Wenn es Sonderzeichen enthalten muss, machen Sie es zu einem Alias oder einem Skript. 2
Wenn es mit sudo arbeiten muss, machen Sie es zu einem Alias oder einem Skript. 3
Wenn Sie es einfach ändern möchten, ohne sich aus- und einzuloggen, ist ein Skript einfacher. 4
Fußnoten
1 Oder machen Sie es zu einem Alias, fügen Sie es ein und legen Sie es
~/.env
festexport ENV="$HOME/.env"
, aber es ist kompliziert, es portabel zu machen.2 Funktionsnamen müssen Bezeichner sein, daher müssen sie mit einem Buchstaben beginnen und dürfen nur Buchstaben, Ziffern und Unterstriche enthalten. Zum Beispiel habe ich einen Alias
alias +='pushd +1'
. Es kann keine Funktion sein.3 Fügen Sie den Alias hinzu
alias sudo='sudo '
. Dito anderer Befehl wiestrace
,gdb
etc. , die einen Befehl als erstes Argument annimmt.4 Siehe auch: Pfad. Natürlich können Sie auch tun
source ~/.bashrc
oder ähnliches, aber dies hat oft andere Nebenwirkungen.quelle
+
in Bash können. Interessanterweise habe ich nach dem Testen festgestellt, dass Sie in bash+
einen Alias+
erstellen können, aber keine Funktion, wie Sie sagen, aber zsh ist das Gegenteil - kann eine Funktion sein, aber kein Alias.zsh
musst du schreibenalias -- +='some command here'
.+
portabel. Siehe die POSIX-Spezifikation für Alias-Namensudo
Nutzung. In Bezug auf Fußnote 4 speichere ich meine Aliase~/.bash_aliases
und Funktionsdefinitionen,~/.bash_functions
damit ich sie leicht wieder herstellensource
kann (ohne die Gefahr von Nebenwirkungen).Nur um ein paar Anmerkungen hinzuzufügen:
Ansonsten können Sie die einfachste Form verwenden, dh zuerst Alias, dann Funktion, dann Skript.
quelle
sudo
. Aber zuerst brauchst dualias sudo='sudo '
.Meine Faustregel lautet:
quelle
In einer Mehrbenutzerumgebung (oder Multi-Sysamin-Umgebung) verwende ich Skripte für alles, auch wenn es nur ein kurzer Wrapper für 'exec something ....' ist.
Sicher, es ist technisch langsamer / weniger effizient als ein Alias oder eine Funktion, aber das spielt fast keine Rolle - und vorausgesetzt, es befindet sich im Pfad, funktioniert ein Skript immer.
Ihre Funktion wird möglicherweise von cron aus aufgerufen, von etwas mit einer reduzierten oder geänderten Umgebung wie sudo oder env, oder der Benutzer verwendet nur eine andere Shell als Sie - alles oder was wahrscheinlich einen Alias oder eine Funktion beschädigen wird.
Wenn Sie etwas Leistungskritisches haben, behandeln Sie dies als Sonderfall oder, noch besser, als Auslöser für das Neuschreiben in einer funktionaleren Skriptsprache.
Wenn es sich um Funktionen handelt, die nur in anderen Skripten verwendet werden, können Sie auch eine Standard-Shell definieren und ein Funktionsbibliotheks-Skript schreiben, das nur so sein kann. Ich habe auf alle anderen Skripte zugegriffen.
T
quelle
Ein Beispiel für eine Situation, in der Sie höchstwahrscheinlich einen Alias verwenden möchten.
Ich weiß, dass dies ein alter Beitrag ist, aber ich möchte auf eine Situation hinweisen, in der ich fast eine Kombination aus Aliasnamen und einem Skript verwenden musste und mich dafür entschieden habe, keine Funktion zu verwenden.
Ich habe ein Skript
~/.bin/
aufgerufensetup
, das Folgendes tut: 1Der Punkt ist, dass ich, wenn ich nur laufen
setup <project-name>
würde, diese Variablen nicht definiert hätte und überhaupt nicht in das Verzeichnis gekommen wäre. Die Lösung fand ich das Beste sein war dieses Skript hinzuzufügen ,PATH
und fügen Siealias setup=". ~/.bin/setup"
zu~/.bashrc
oder was auch immer.Anmerkungen:
quelle
Wann soll ein Skript geschrieben werden?
Wenn Sie den Befehl möglicherweise von einem anderen Tool als der Shell ausführen möchten.
Dies schließt vim (für mich) ein: Wenn ich Filter und andere Programme als Skripte geschrieben habe, kann ich so etwas wie
:%!my-filter
das Filtern einer Datei durch das Programm von meinem Editor aus tun .Wenn
my-filter
eine Funktion oder ein Alias vorhanden wäre, wäre dies nicht möglich.quelle