Was bedeutet das letzte "-" (Bindestrich) in Optionen von "bash"?

15

In diesem Tutorial müssen wir den folgenden Befehl ausführen:

# curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

Was bedeutet der letzte -(Bindestrich) nach bash?

Ich habe viele Befehle damit gesehen und konnte mir keine logische Erklärung finden und auch nicht herausfinden, wie ich eine Google-Suche danach umformulieren kann. Ist es die Ausgabe des Pipe-Befehls?

Omar BISTAMI
quelle
5
Gleiche Frage auf Ask Ubuntu - mit dem gleichen Beispiel!
200_success
2
Das Herunterladen von Dingen aus dem Netzwerk und das direkte Einspielen in sudo bashKlänge ist wirklich beängstigend. Suchen Sie nach einem Tutorial, das solche Praktiken nicht fördert.
hmakholm hat Monica
Es ist das Npm-Tutorial, aber ich stimme dir zu ...
Omar BISTAMI
1
Wenn Sie nach Dingen mit Symbolen suchen müssen, versuchen Sie es symbolhound.com.
Joe

Antworten:

31

Bash verhält sich etwas ungewöhnlich, wenn es darum geht -.

POSIX sagt:

Leitlinie 10:
Das erste --Argument, das kein Optionsargument ist, sollte als Trennzeichen für das Ende von Optionen akzeptiert werden. Alle folgenden Argumente sollten als Operanden behandelt werden, auch wenn sie mit dem -Zeichen beginnen .

[…]

Richtlinie 13:
Für Dienstprogramme, die Operanden verwenden, um Dateien darzustellen, die zum Lesen oder Schreiben geöffnet werden -sollen , sollte der Operand nur als Standardeingabe (oder als Standardausgabe, wenn aus dem Kontext klar hervorgeht, dass eine Ausgabedatei angegeben wird) oder als a bezeichnet werden Datei mit dem Namen -.

Und

Wenn ein Dienstprogramm, das im Shell- und Dienstprogramm-Band von POSIX.1-2017 als konform mit diesen Richtlinien beschrieben ist, den Operanden -als Standardeingabe oder -ausgabe akzeptieren oder nicht akzeptieren soll, wird diese Verwendung im Abschnitt OPERANDS erläutert. Wenn in einem solchen Dienstprogramm Operanden zur Darstellung von Dateien verwendet werden, wird durch die Implementierung festgelegt, ob der Operand -für die Standardeingabe (oder die Standardausgabe) oder für eine Datei mit dem Namen steht -.

Aber dann man 1 bashheißt es:

A --signalisiert das Ende von Optionen und deaktiviert die weitere Optionsverarbeitung. Alle Argumente nach dem --werden als Dateinamen und Argumente behandelt. Ein Argument von -ist äquivalent zu --.

Für Bash -bedeutet dies weder Standardeingabe noch eine Datei, daher etwas ungewöhnlich.

Nun zu Ihrem speziellen Fall:

curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

Ich vermute, dass der Autor dieses Befehls möglicherweise nicht erkennt -, dass er --in diesem Fall dem entspricht. Ich vermute, der Autor wollte sicherstellen bash, dass aus seiner Standardeingabe gelesen wird, sie sollte -nach der Richtlinie 13 funktionieren.

Aber selbst wenn es nach der Richtlinie funktioniert, -wäre es hier unnötig, da es basherkennt, wenn seine Standardeingabe eine Pipe ist und entsprechend verhält (sofern nichts -canderes angegeben ist).

Funktioniert -aber nicht nach der Richtlinie, es funktioniert wie --. Trotzdem --ist das hier unnötig, da es keine Argumente danach gibt.

Meiner Meinung nach -ändert das Letzte nichts. Der Befehl würde ohne ihn funktionieren.

Sehen Sie sich das folgende Beispiel an, um zu sehen, wie nützlich --und -nützlich es im Allgemeinen sein kann.


catIn meinem Kubuntu werden beide Richtlinien befolgt und ich werde sie verwenden, um die Nützlichkeit von -und zu demonstrieren --.

Lassen Sie eine Datei mit dem Namen fooexistieren. Dadurch wird die Datei gedruckt:

cat foo

Lassen Sie eine Datei mit dem Namen --helpexistieren. Die Datei wird nicht gedruckt:

cat --help

Aber dies wird die Datei mit dem Namen drucken --help:

cat -- --help

Dadurch wird die genannte Datei --helpmit der Standardeingabe verknüpft:

cat -- --help -

Es scheint, dass Sie es nicht wirklich brauchen --, da Sie immer übergeben können, ./--helpwas mit Sicherheit als Datei interpretiert wird. Aber bedenken Sie

cat "$file"

wenn Sie vorher nicht wissen, was der Inhalt der Variablen ist. Sie können es nicht einfach voranstellen ./, da es ein absoluter Pfad sein kann und ./ihn brechen würde. Andererseits kann es sich um eine Datei mit dem Namen handeln--help (warum nicht?). In diesem Fall --ist sehr nützlich; Dies ist ein viel robusterer Befehl:

cat -- "$file"
Kamil Maciorowski
quelle
6

Im man bash Ende der Optionen für einzelne Zeichen befindet sich:

--    A -- signals the end of options and disables further option processing.
      Any arguments after the -- are treated as filenames and arguments. An
      argument of - is equivalent to --.

Wenn Sie den vollständigen Befehl zitiert habe, kann ich keinen Grund zu der Verwendung finden , -nachdem bashin diesem Fall, aber es schadet nicht.

AFH
quelle
Vielen Dank für Ihre Antwort, Ja, ich habe den vollständigen Befehl zitiert. Also wird alles nach - oder - nicht als Option gesehen, sondern als Dateiname oder Argument. Könnten Sie bitte ein Beispiel nennen, wo es nützlich ist?
Omar BISTAMI
1
Es ist wirklich wichtig, ein Skript zuzulassen, dessen Name beginnt -, eine unwahrscheinliche Voraussetzung, aber -ich --mache es möglich.
AFH
1
@OmarBISTAMI Das Zitieren eines Befehls wirkt sich auf die Erweiterung der Shell aus, jedoch nicht auf die darauf folgenden Argumente. Wenn Sie die Anführungszeichen um legitime Argumente erweitern, werden sie Teil des Befehlsnamens, der auch nicht Ihren Wünschen entspricht. Es gibt einige Befehle, die Dateinamen als Argumente verwenden, aber standardmäßig keine Standardeingabe verwenden. Ein ausgeklügeltes Beispiel ermöglicht es Ihnen, Eingaben (von einem Terminal oder einer Pipe) zwischen zwei Dateien einzufügen. cat file1 - file2 > file3.
Joe
1
curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

bash -bedeutet, dass bashauf stdin gewartet wird. Bash führt also praktisch alles aus, was der Befehl auf der linken Seite zurückgibt|

Ein ähnliches, aber einfacheres Beispiel wäre:

echo hello | cat - Hier catwird "Hallo" gedruckt. Warum? Weil 'hallo' durch |und zu cat geschickt wirdcat auf alles wartet, was an sie gesendet wird

Lassen Sie uns nun den gesamten Befehl in zwei Teile aufteilen:

curl -sL https://rpm.nodesource.com/setup_6.x

Dieser curl-Befehl gibt etwas zurück, das von bash verstanden und ausgeführt werden kann

Dann haben wir eine Pipe, |die die Ausgabe, die durch den Befehl curl zurückgegeben wird, an die rechte Seite der Pipe sendet, d sudo -E bash -. h . Schließlich sudo -E bash -ist bash in der Lage, alles auszuführen, was an bash gesendet wird

Haris Muzaffar
quelle