Diese Frage ist in einem Quiz vor dem Interview aufgetaucht und macht mich verrückt. Kann jemand darauf antworten und mich beruhigen? Das Quiz bezieht sich nicht auf eine bestimmte Shell, die Jobbeschreibung bezieht sich jedoch auf eine Unix-sa. wieder ist die frage einfach ...
Was macht 'set -e' und warum wird es als gefährlich eingestuft?
Antworten:
set -e
Bewirkt, dass die Shell beendet wird, wenn ein Unterbefehl oder eine Pipeline einen Status ungleich Null zurückgibt.Die Antwort, nach der der Interviewer wahrscheinlich gesucht hat, lautet:
Von http://www.debian.org/doc/debian-policy/ch-opersys.html 9.3.2 -
Dies ist vom Standpunkt eines Interviewers aus eine berechtigte Frage, da sie die Kenntnisse eines Kandidaten in Bezug auf Scripting und Automatisierung auf Serverebene misst
quelle
Von
bash(1)
:Leider bin ich nicht kreativ genug, um darüber nachzudenken, warum es gefährlich sein könnte, außer "der Rest des Skripts wird nicht ausgeführt" oder "es könnte möglicherweise echte Probleme maskieren".
quelle
set
! Ich lande immer beibuiltin(1)
. Vielen Dank.set
zu finden istman 1 bash
?? und wie könnte jemand die-e
Option für dasset
Schlüsselwort in einer Handbuchseite finden, die so enorm groß ist? Sie können hier nicht einfach/-e
suchenhelp set
Es ist zu beachten, dass
set -e
für verschiedene Abschnitte eines Skripts aktiviert und deaktiviert werden kann. Es muss nicht für die Ausführung des gesamten Skripts aktiviert sein. Es könnte sogar bedingt aktiviert werden. Das heißt, ich benutze es nie, da ich meine eigene Fehlerbehandlung mache (oder nicht).Bemerkenswert ist auch der Abschnitt auf der Bash-Manpage des
trap
Befehls, in dem auch dieset -e
Funktionsweise unter bestimmten Umständen beschrieben wird.Es gibt also einige Bedingungen, unter denen ein Nicht-Null-Status kein Verlassen verursacht.
Ich denke, die Gefahr besteht darin, nicht zu verstehen, wann etwas
set -e
passiert und wann nicht, und mich unter einer ungültigen Annahme fälschlicherweise darauf zu verlassen.Siehe auch BashFAQ / 105. Warum macht set -e (oder set -o errexit oder trap ERR) nicht das, was ich erwartet hatte?
quelle
Denken Sie daran, dies ist ein Quiz für ein Vorstellungsgespräch. Die Fragen wurden möglicherweise vom aktuellen Personal geschrieben und sind möglicherweise falsch. Das ist nicht unbedingt schlecht, und jeder macht Fehler, und Interviewfragen sitzen oft in einer dunklen Ecke ohne Überprüfung und kommen nur während eines Interviews heraus.
Es ist durchaus möglich, dass 'set -e' nichts tut, was wir als "gefährlich" betrachten würden. Aber der Autor dieser Frage könnte irrtümlich glauben, dass 'set -e' gefährlich ist, aufgrund ihrer eigenen Ignoranz oder Voreingenommenheit. Vielleicht haben sie ein fehlerhaftes Shell-Skript geschrieben, das schrecklich bombardiert wurde, und sie dachten fälschlicherweise, dass 'set -e' schuld ist, obwohl sie es versäumt haben, eine ordnungsgemäße Fehlerprüfung zu schreiben.
Ich habe in den letzten 2 Jahren an wahrscheinlich 40 Vorstellungsgesprächen teilgenommen, und die Interviewer stellen manchmal Fragen, die falsch sind, oder haben Antworten, die falsch sind.
Oder vielleicht ist es eine Trickfrage, die lahm wäre, aber nicht ganz unerwartet.
Oder vielleicht ist dies eine gute Erklärung: http://www.mail-archive.com/[email protected]/msg473314.html
quelle
set -e
Weist bash in einem Skript an, den Vorgang zu beenden, wenn ein Wert ungleich Null zurückgegeben wird.Ich konnte sehen, wie ärgerlich und fehlerhaft das wäre, nicht sicher, was gefährlich ist, es sei denn, Sie hatten Berechtigungen für etwas geöffnet und bevor Sie sie wieder einschränken konnten, starb Ihr Skript.
quelle
set -e
, für mich spricht es von Faulheit, die Fehlerprüfung in Ihren Skripten zu ignorieren. Denken Sie also daran, auch bei diesem Arbeitgeber, wenn er sie verwendet viel, wie sehen ihre Skripte aus, die Sie zwangsläufig pflegen müssen ...set -e
Beendet das Skript, wenn ein Exit-Code ungleich Null auftritt, außer unter bestimmten Bedingungen. Um die Gefahren seines Gebrauchs in wenigen Worten zusammenzufassen: Es verhält sich nicht so, wie die Leute denken, dass es es tut.Meiner Meinung nach sollte es als gefährlicher Hack angesehen werden, der nur noch aus Kompatibilitätsgründen existiert. Die
set -e
Anweisung wandelt die Shell nicht von einer Sprache, die Fehlercodes verwendet, in eine Sprache um, die einen ausnahmeartigen Steuerungsfluss verwendet. Sie versucht lediglich, dieses Verhalten nur schlecht zu emulieren.Greg Wooledge hat viel zu den Gefahren von
set -e
:set -e
)Im zweiten Link gibt es verschiedene Beispiele für das unintuitive und unvorhersehbare Verhalten von
set -e
.Einige Beispiele für das nicht intuitive Verhalten von
set -e
(einige stammen aus dem obigen Wiki-Link):let x++
0 zurückgegeben wird, was vomlet
Schlüsselwort als falscher Wert behandelt und in einen Exit-Code ungleich Null umgewandelt wird.set -e
bemerkt dies und beendet das Skript unbemerkt.Das oben beschriebene Verfahren funktioniert wie erwartet und gibt eine Warnung aus, falls diese
/opt/foo
bereits vorhanden ist.Das Obige endet, obwohl der einzige Unterschied darin besteht, dass eine einzelne Zeile in eine Funktion umgestaltet wurde, wenn
/opt/foo
es nicht existiert. Dies liegt daran, dass die Tatsache, dass es ursprünglich funktionierte, eine besondere Ausnahme von seinemset -e
Verhalten darstellt. Wenn dera && b
Wert ungleich Null ist, wird er von ignoriertset -e
. Da es sich jedoch um eine Funktion handelt, entspricht der Exit-Code der Funktion dem Exit-Code dieses Befehls, und die Funktion, die einen Wert ungleich Null zurückgibt, beendet das Skript im Hintergrund.Das obige liest das Array
config_vars
aus der Dateiconfig
. Wie der Autor vielleicht beabsichtigt, wird es mit einem Fehler beendet, wennconfig
es fehlt. Da der Autor möglicherweise nicht beabsichtigt, wird er stillschweigend beendet, wenn erconfig
nicht in einer neuen Zeile endet. Wennset -e
hier nicht verwendetconfig_vars
würde , würden alle Zeilen der Datei enthalten sein, unabhängig davon, ob sie in einer neuen Zeile endete oder nicht.Benutzer von Sublime Text (und anderen Texteditoren, die falsch mit Zeilenumbrüchen umgehen) sollten aufpassen.
Der Autor kann davon ausgehen, dass
$user
dergroups
Befehl fehlschlägt , wenn der Benutzer aus irgendeinem Grund nicht vorhanden ist, und das Skript beendet wird, anstatt den Benutzer eine Aufgabe ungeprüft ausführen zu lassen. In diesem Fall wird dieset -e
Kündigung jedoch niemals wirksam. Wenn$user
das Skript aus irgendeinem Grund nicht gefunden werden kann, gibt dieshould_audit_user
Funktion nur falsche Daten zurück, als wäre sieset -e
nicht in Kraft.Dies gilt für alle Funktionen, die aus dem Bedingungsteil einer
if
Anweisung aufgerufen werden , unabhängig davon, wie tief sie verschachtelt sind, unabhängig davon, wo sie definiert sind, auch wenn Sieset -e
sie erneut ausführen . Wenn Sieif
zu einem beliebigen Zeitpunkt verwenden, wird der Effekt vollständig deaktiviert,set -e
bis der Bedingungsblock vollständig ausgeführt ist. Wenn der Autor diese Fallstricke nicht kennt oder seinen gesamten Aufrufstapel in allen möglichen Situationen, in denen eine Funktion aufgerufen werden kann, nicht kennt, schreibt er fehlerhaften Code, und das falsche Sicherheitsgefühl, das von bereitgestellt wird,set -e
wird zumindest teilweise aufgehoben Schuld.Selbst wenn der Autor sich dieser Fallstricke voll bewusst ist, besteht die Problemumgehung darin, Code auf die gleiche Weise zu schreiben, wie man es ohne ihn schreiben würde
set -e
, wodurch dieser Switch weniger als nutzlos wird. Der Autor muss nicht nur den Code für die manuelle Fehlerbehandlung so schreiben, als ob erset -e
nicht in Kraft wäre, sondern das Vorhandensein von hat ihnset -e
möglicherweise in die Irre geführt, dass er dies nicht tun muss.Einige weitere Nachteile von
set -e
:let x++
oben ist dies jedoch nicht der Fall. Wenn das Skript unerwartet abstürzt, geschieht dies normalerweise im Hintergrund, was das Debuggen behindert. Wenn das Skript nicht stirbt und Sie es erwartet haben (siehe vorherigen Aufzählungspunkt), haben Sie einen subtileren und heimtückischeren Fehler in Ihren Händen.if
Aufzählungspunkt.set -e
weil zwischen diesen Versionen Optimierungen vorgenommen wurden.set -e
ist ein umstrittenes Problem, und einige Leute, die sich der Probleme bewusst sind, empfehlen, dagegen vorzugehen, während andere nur empfehlen, vorsichtig zu sein, während es aktiv ist, um die Fallstricke zu kennen. Es gibt viele Anfänger in der Shell-Skripterstellung, dieset -e
bei allen Skripten Abhilfe schaffen , aber im wirklichen Leben funktioniert das nicht so.set -e
ist kein Ersatz für Bildung.quelle
Ich würde sagen, es ist gefährlich, weil du den Fluss deines Skripts nicht mehr kontrollierst. Das Skript kann beendet werden, solange einer der vom Skript aufgerufenen Befehle einen Wert ungleich Null zurückgibt. Alles, was Sie tun müssen, ist, etwas zu tun, das das Verhalten oder die Ausgabe einer der Komponenten ändert, und Sie müssen das Hauptskript beenden. Es mag eher ein Stilproblem sein, aber es hat definitiv Konsequenzen. Was ist, wenn das Hauptskript von Ihnen ein Flag setzen soll und nicht, weil es vorzeitig beendet wurde? Sie würden am Ende den Rest des Systems bemängeln, wenn davon ausgegangen wird, dass das Flag vorhanden sein sollte, oder wenn Sie mit einem unerwarteten Standardwert oder einem alten Wert arbeiten.
quelle
Stellen Sie sich als konkreteres Beispiel für @ Marcins Antwort, die mich persönlich gebissen hat, vor, dass
rm foo/bar.txt
irgendwo in Ihrem Skript eine Zeile vorkommt. Normalerweise keine große Sache, wennfoo/bar.txt
es sie nicht gibt. Mit demset -e
jetzigen Zeitpunkt wird Ihr Skript dort jedoch vorzeitig beendet! Hoppla.quelle