VorwortIch habe vor kurzem die Syntax von Bash-Skripten gelernt, aber wenn man mit der Bash-Syntax nicht vertraut ist, kann man sehr leicht Fehler machen, zum Beispiel: nicht definierte Variablen werden angezeigt. Auch wenn eine Variable in der Shell nicht definiert ist, kann sie trotzdem verwendet werden, aber das Ergebnis entspricht möglicherweise nicht Ihren Erwartungen. Zum Beispiel: #! /bin/bash # Hier beurteilen wir, ob die Variable var gleich der Zeichenfolge abc ist, aber die Variable var ist nicht deklariert, wenn [ "$var" = "abc" ] Dann # Wenn das if-Urteil wahr ist, drucken Sie "not abc" in der Konsole echo "nicht abc" anders # Wenn das if-Urteil falsch ist, drucken Sie "abc" in der Konsole Echo " abc " fi Das Ergebnis ist, dass abc gedruckt wird, aber das Problem ist, dass dieses Skript einen Fehler melden sollte. Es ist ein Fehler, dass der Variablen kein Wert zugewiesen wird. Um diese Fehler zu beheben, haben wir gelernt, am Anfang des Skripts Folgendes hinzuzufügen: Dieser Befehl bedeutet, dass das Skript es zum Kopf hinzufügt. Wenn es auf eine nicht vorhandene Variable stößt, meldet es einen Fehler und stoppt die Ausführung. Wenn Sie es erneut ausführen, erhalten Sie die folgende Meldung: Stellen Sie sich noch einmal vor, Sie wollten ursprünglich löschen: rm -rf $dir/* und dann ist das Verzeichnis leer, was passiert? rm -rf ist der Löschbefehl. Wenn $dir leer ist, entspricht dies der Ausführung von rm -rf /*, wodurch alle Dateien und Ordner gelöscht werden. . . Dann ist Ihr System hinüber. Handelt es sich hier um das legendäre Löschen der Datenbank und die anschließende Flucht? Wenn es sich um eine Node- oder Browserumgebung handelt, erhalten wir definitiv einen Fehler, wenn wir var === 'abc' direkt verwenden. Mit anderen Worten: Viele Erfahrungen aus der JavaScript-Programmierung können in Bash nicht wiederverwendet werden. Es wäre großartig, wenn sie wiederverwendet werden könnten. Später begann ich, mich umzusehen. Es wäre toll, wenn ich Node-Skripte statt Bash verwenden könnte. Nach einem Tag des Hin und Hers entdeckte ich nach und nach ein magisches Tool: Googles zx-Bibliothek. Keine Sorge, ich werde diese Bibliothek noch nicht vorstellen. Schauen wir uns zunächst an, wie der Mainstream Node zum Schreiben von Bash-Skripten verwendet, und Sie werden wissen, warum es ein magisches Tool ist. Ausführen von Bash-Skripten mit Node: eine zögerliche Lösung: child_process API Beispielsweise der exec-Befehl in der child_process API const { exec } = erfordern("untergeordneter_Prozess"); exec("ls -la", (Fehler, stdout, stderr) => { if (Fehler) { console.log(`Fehler: ${error.message}`); zurückkehren; } wenn (stderr) { Konsole.log(`stderr: ${stderr}`); zurückkehren; } Konsole.log(`stdout: ${stdout}`); }); Es ist hier zu beachten, dass exec zunächst einmal asynchron ist, viele unserer Bash-Skriptbefehle jedoch synchron sind. Beachten Sie auch: Das Fehlerobjekt unterscheidet sich von stderr. Fehler: Wenn das Modul child_process den Befehl nicht ausführen kann, ist das Objekt nicht leer. Wenn beispielsweise eine Datei nicht gefunden wird, ist das Fehlerobjekt nicht null. Wenn der Befehl jedoch erfolgreich ausgeführt wird und Nachrichten in den Standardfehlerstrom schreibt, ist dieses Stderr-Objekt nicht null. Natürlich können wir den synchronen Exec-Befehl execSync verwenden // Exec-Befehl aus dem Child_Process-Modul importieren const { execSync } = require("child_process"); // Synchron einen Ordner mit dem Namen „Hallo“ erstellen execSync("mkdir hello"); Lassen Sie uns kurz andere APIs von child_process vorstellen, die Bash-Befehle ausführen können.
Der Unterschied zwischen exec und ececFile besteht darin, dass exec zum Ausführen von Befehlen geeignet ist, während eexecFile zum Ausführen von Dateien geeignet ist. Knoten führt Bash-Skript aus: Erweiterte Lösung Shelljs const shell = erfordern('shelljs'); # Dateibefehl löschen shell.rm('-rf', 'out/Release'); // Dateibefehl kopieren shell.cp('-R', 'stuff/', 'out/Release'); # Wechseln Sie in das lib-Verzeichnis, listen Sie die Dateien mit der Endung .js im Verzeichnis auf und ersetzen Sie den Dateiinhalt (sed -i ist ein Befehl zum Ersetzen von Text). Shell.cd('lib'); shell.ls('*.js').forEach(Funktion (Datei) { shell.sed('-i', 'BUILD_VERSION', 'v0.1.2', Datei); shell.sed('-i', /^.*REMOVE_THIS_LINE.*$/, '', Datei); shell.sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, shell.cat('macro.js'), Datei); }); shell.cd('..'); # Sofern nicht anders angegeben, führen Sie die angegebenen Befehle synchron aus. Im synchronen Modus wird ein ShellString zurückgegeben. # (Kompatibel mit ShellJS v0.6.x, gibt es ein Objekt der Form { code:..., stdout:..., stderr:... } zurück). # Andernfalls wird das Unterprozessobjekt zurückgegeben und der Rückruf erhält Argumente (Code, stdout, stderr). wenn (shell.exec('git commit -am "Auto-commit"').code !== 0) { shell.echo('Fehler: Git-Commit fehlgeschlagen'); Shell.Exit(1); } Dem obigen Code nach zu urteilen, ist ShellJS wirklich eine sehr gute Lösung zum Schreiben von Bash-Skripten in NodeJS. Wenn Ihre Node-Umgebung nicht beliebig aktualisiert werden kann, ist ShellJS meiner Meinung nach tatsächlich ausreichend. Als nächstes werfen wir einen Blick auf den heutigen Protagonisten, zx, der bei 17,4k gestartet ist. zx-BibliothekOffizielle Website: www.npmjs.com/package/zx Schauen wir uns zunächst an, wie man es benutzt #!/usr/bin/env zx warte auf $`cat package.json | grep name` let branch = warte auf $`git branch --show-current` warte auf $`dep deploy --branch=${branch}` warte auf Promise.all([ $`sleep 1; echo 1`, $`sleep 2; echo 2`, $`sleep 3; echo 3`, ]) let name = "foo bar" warte auf $`mkdir /tmp/${name} Was meinen Sie? Es ist einfach das Schreiben von Linux-Befehlen. Sie können einen Großteil der Bash-Syntax ignorieren und einfach direkt js verwenden. Und die Vorteile sind noch viel größer. Einige seiner Funktionen sind recht interessant: 1. Unterstützt ts, kompiliert .ts automatisch in eine .mjs-Datei. Die .mjs-Datei ist die Dateiendung, die das es6-Modul in der höheren Version von Node unterstützt. Das heißt, diese Datei kann das Modul direkt importieren, ohne mit anderen Tools entkommen zu müssen. 2. Kommt mit Unterstützung für Pipeline-Betrieb Pipe-Methode 3. Es enthält eine Fetch-Bibliothek für Netzwerkanforderungen, eine Chalk-Bibliothek zum Drucken farbiger Schriftarten und eine Nothrow-Methode zur Fehlerbehandlung. Wenn ein Bash-Befehl fehlschlägt, können Sie ihn in diese Methode einbinden, um den Fehler zu ignorieren. Vollständiges chinesisches Dokument (bitte verzeihen Sie meine schlechten Übersetzungsfähigkeiten) #!/usr/bin/env zx warte auf $`cat package.json | grep name` let branch = warte auf $`git branch --show-current` warte auf $`dep deploy --branch=${branch}` warte auf Promise.all([ $`sleep 1; echo 1`, $`sleep 2; echo 2`, $`sleep 3; echo 3`, ]) let name = "foo bar" warte auf $`mkdir /tmp/${name} Bash ist großartig, aber beim Schreiben von Skripten entscheiden sich die Leute normalerweise für eine bequemere Programmiersprache. JavaScript ist eine perfekte Wahl, aber die Standardbibliothek Node.js erfordert einige zusätzliche Schritte, bevor sie verwendet werden kann. zx basiert auf child_process, maskiert Argumente und bietet sinnvolle Standardwerte. Installieren npm ich -g zx Erforderliche Umgebung Node.js >= 14.8.0 Schreiben Sie Ihr Skript in eine Datei mit der Erweiterung .mjs, um await auf der obersten Ebene verwenden zu können. Fügen Sie am Anfang Ihres zx-Skripts den folgenden Shebang hinzu: #!/usr/bin/env zx Jetzt können Sie Ihr Skript wie folgt ausführen: chmod +x ./script.mjs ./Skript.mjs Oder über die ausführbare zx-Datei: zx ./script.mjs Alle Funktionen ($, cd, fetch usw.) können ohne Importe direkt verwendet werden. $`Befehl`Verwenden Sie die Spawn-Funktion im child_process-Paket, um die angegebene Zeichenfolge auszuführen und ein ProcessPromise zurückzugeben. lass zählen = parseInt(warte $`ls -1 | wc -l`) console.log(`Anzahl der Dateien: ${count}`) So laden Sie beispielsweise Dateien parallel hoch: Wenn das ausgeführte Programm einen Exit-Code ungleich Null zurückgibt, wird ProcessOutput ausgelöst. versuchen { warte auf $`exit 1` } fangen (p) { console.log(`Beendigungscode: ${p.exitCode}`) console.log(`Fehler: ${p.stderr}`) } ProcessPromise, das Folgende ist die Schnittstellendefinition von Promise Typescript Klasse ProcessPromise<T> erweitert Promise<T> { schreibgeschützter Standarddin: Beschreibbar readonly stdout: Lesbar readonly stderr: Lesbar schreibgeschützter ExitCode: Promise<Nummer> pipe(dest): ProzessPromise<T> } Mit der Methode pipe() kann die Standardausgabe umgeleitet werden: warte auf $`cat file.txt`.pipe(process.stdout) Lesen Sie mehr über Pipelines unter github.com/google/zx/b… Typescript-Schnittstellendefinition von ProcessOutput Klasse ProzessAusgabe { schreibgeschützte Standardausgabe: Zeichenfolge schreibgeschützter stderr: Zeichenfolge schreibgeschützter ExitCode: Nummer toString(): Zeichenfolge } Funktion: CD()Ändern des aktuellen Arbeitsverzeichnisses cd('/tmp') warte auf $`pwd` // gibt /tmp aus bringen()Das Node-Fetch-Paket. let resp = warte auf fetch('http://wttr.in') wenn (bzw. ok) { console.log(warte bzw.text()) } Frage()Das readline Paket let bear = await question('Welche Art von Bär ist am besten? ') let token = await question('Umgebungsvariable auswählen: ', { Auswahlmöglichkeiten: Objekt.Schlüssel(Prozess.Umgebung) }) Im zweiten Parameter können Sie eine Reihe von Optionen für die automatische Tab-Vervollständigung angeben Nachfolgend sehen Sie die Schnittstellendefinition Funktion Frage (Abfrage?: Zeichenfolge, Optionen?: Frageoptionen): Promise<Zeichenfolge> Typ QuestionOptions = { Auswahlmöglichkeiten: Zeichenfolge[] } schlafen()Basierend auf der Funktion setTimeout warte auf Schlaf (1000) nothrow()Ändern Sie das Verhalten von $, um keine Ausnahme auszulösen, wenn der Exitcode ungleich 0 ist. ts-Schnittstellendefinition Funktion nothrow<P>(p: P): P warte auf nothrow($`grep etwas aus Datei`) // Innerhalb der Pipeline: warte auf $`find ./examples -type f -print0` .pipe(nothrow($`xargs -0 grep etwas`)) .pipe($`wc -l`) Die folgenden Pakete müssen nicht importiert werden und können direkt verwendet werden Kreideconsole.log(chalk.blue('Hallo Welt!')) fsÄhnlich wie die folgende Verwendung importiere {Versprechen als fs} von 'fs' let content = warte auf fs.readFile('./package.json') Betriebssystemwarte auf $`cd ${os.homedir()} && mkdir Beispiel` Konfiguration: $.shellGibt die zu verwendende Bash an. $.shell = "/usr/bin/bash" $.ZitatGibt die Funktion an, mit der Sonderzeichen bei der Befehlsersetzung maskiert werden. Das verwendete Standardpaket ist shq. Beachten: Die beiden Variablen __filename und __dirname sind in commonjs. Wir verwenden es6-Module mit der Endung .mjs. In ESM-Modulen stellt Node.js keine globalen Variablen __filename und __dirname bereit. Da solche globalen Variablen in Skripten sehr praktisch sind, stellt zx diese zur Verwendung in .mjs-Dateien bereit (bei Verwendung der ausführbaren zx-Datei). „Require“ ist auch eine Modulimportmethode in CommonJS. Im ESM-Modul ist keine require()-Funktion definiert. zx stellt eine require()-Funktion bereit, sodass es mit Importen in .mjs-Dateien verwendet werden kann (bei Verwendung der ausführbaren zx-Datei) Übergeben von UmgebungsvariablenProzess.Umgebung.FOO = "Bar" warte auf $`echo $FOO` Übergeben von ArraysWenn ein Array von Werten als Argument an $ übergeben wird, werden die Elemente des Arrays einzeln maskiert und durch Leerzeichen verbunden. Beispiel: let Dateien = [1,2,3] warte auf $`tar cz ${files}` $ und andere Funktionen können durch expliziten Import verwendet werden #!/usr/bin/env Knoten importiere {$} von 'zx' warte auf $`date` zx kann .ts-Skripte in .mjs kompilieren und ausführen zx-beispiele/typescript.ts ZusammenfassenDies ist das Ende dieses Artikels zum Schreiben von Bash-Skripten mit Node.js. Weitere Informationen zum Schreiben von Bash-Skripten mit Node.js finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: In wenigen Schritten zum einfachen Aufbau eines Windows-SSH-Servers
>>: MySQL-Trigger: Beispielanalyse zum Erstellen mehrerer Trigger
Deinstallieren von MySQL 1. Deinstallieren Sie in...
Inhaltsverzeichnis Vorwort Den Grundstein legen P...
1. Einleitung: Ich denke, dass die Änderungen nac...
Inhaltsverzeichnis 1. Kommunikationsmethode für V...
Dieser Artikel erläutert anhand von Beispielen di...
Inhaltsverzeichnis Umfassender Vergleich Aus der ...
1. Laden Sie die Zip-Archivversion von der offizi...
Bild herunterladen Docker-Pull OpenJDK Erstellen ...
Zusammenfassung HTML: Element plus V-Umhang CSS: ...
In diesem Artikelbeispiel wird der spezifische Co...
Einführung Weil JavaScript standardmäßig ein Thre...
Die EXPLAIN-Anweisung wird im MySQL-Abfrageanweis...
Inhaltsverzeichnis Vorwort Projektdesign hinteres...
Vorwort Der Ubuntu-Server des Unternehmens platzi...
2D-Transformationen in CSS ermöglichen es uns, ei...